From c63d94483b1e52817ca01ca82a867a78ebd39fa6 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 24 Mar 2018 18:30:28 -0400 Subject: Redesign wlr_texture - Textures are now immutable (apart from those created from raw pixels), no more invalid textures - Move all wl_drm stuff in wlr_renderer - Most of wlr_texture fields are now private - Remove some duplicated DMA-BUF code in the DRM backend - Add more assertions - Stride is now always given as bytes rather than pixels - Drop wl_shm functions Fun fact: this patch has been written 10,000 meters up in the air. --- examples/multi-pointer.c | 2 +- examples/output-layout.c | 6 +++--- examples/pointer.c | 4 ++-- examples/rotation.c | 6 +++--- examples/touch.c | 13 ++++++++----- 5 files changed, 17 insertions(+), 14 deletions(-) (limited to 'examples') diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index 43ccdb66..1f869f50 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -149,7 +149,7 @@ static void handle_input_add(struct compositor_state *state, sample->compositor); struct wlr_xcursor_image *image = sample->xcursor->images[0]; - wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wl_list_insert(&sample->cursors, &cursor->link); diff --git a/examples/output-layout.c b/examples/output-layout.c index 45d896b0..c1392a30 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -197,9 +197,9 @@ int main(int argc, char *argv[]) { compositor_init(&compositor); state.renderer = wlr_gles2_renderer_create(compositor.backend); - state.cat_texture = wlr_render_texture_create(state.renderer); - wlr_texture_upload_pixels(state.cat_texture, WL_SHM_FORMAT_ABGR8888, - cat_tex.width, cat_tex.width, cat_tex.height, cat_tex.pixel_data); + state.cat_texture = wlr_texture_from_pixels(state.renderer, + WL_SHM_FORMAT_ABGR8888, cat_tex.width * 4, cat_tex.width, cat_tex.height, + cat_tex.pixel_data); if (!wlr_backend_start(compositor.backend)) { wlr_log(L_ERROR, "Failed to start backend"); diff --git a/examples/pointer.c b/examples/pointer.c index e8a0e892..9794e6e5 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -112,7 +112,7 @@ static void handle_output_add(struct output_state *ostate) { sample->compositor); struct wlr_xcursor_image *image = sample->xcursor->images[0]; - wlr_cursor_set_image(sample->cursor, image->buffer, image->width, + wlr_cursor_set_image(sample->cursor, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wlr_cursor_warp(sample->cursor, NULL, sample->cursor->x, sample->cursor->y); @@ -324,7 +324,7 @@ int main(int argc, char *argv[]) { } struct wlr_xcursor_image *image = state.xcursor->images[0]; - wlr_cursor_set_image(state.cursor, image->buffer, image->width, + wlr_cursor_set_image(state.cursor, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y, 0); compositor_init(&compositor); diff --git a/examples/rotation.c b/examples/rotation.c index cbff09a1..dfafeeca 100644 --- a/examples/rotation.c +++ b/examples/rotation.c @@ -142,13 +142,13 @@ int main(int argc, char *argv[]) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); } - state.cat_texture = wlr_render_texture_create(state.renderer); + state.cat_texture = wlr_texture_from_pixels(state.renderer, + WL_SHM_FORMAT_ABGR8888, cat_tex.width * 4, cat_tex.width, cat_tex.height, + cat_tex.pixel_data); if (!state.cat_texture) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); } - wlr_texture_upload_pixels(state.cat_texture, WL_SHM_FORMAT_ABGR8888, - cat_tex.width, cat_tex.width, cat_tex.height, cat_tex.pixel_data); if (!wlr_backend_start(compositor.backend)) { wlr_log(L_ERROR, "Failed to start backend"); diff --git a/examples/touch.c b/examples/touch.c index f9c496cf..7639165c 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -45,10 +45,13 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts wlr_renderer_begin(sample->renderer, wlr_output->width, wlr_output->height); wlr_renderer_clear(sample->renderer, (float[]){0.25f, 0.25f, 0.25f, 1}); + int tex_width, tex_height; + wlr_texture_get_size(sample->cat_texture, &tex_width, &tex_height); + struct touch_point *p; wl_list_for_each(p, &sample->touch_points, link) { - int x = (int)(p->x * width) - sample->cat_texture->width / 2; - int y = (int)(p->y * height) - sample->cat_texture->height / 2; + int x = (int)(p->x * width) - tex_width / 2; + int y = (int)(p->y * height) - tex_height / 2; wlr_render_texture(sample->renderer, sample->cat_texture, wlr_output->transform_matrix, x, y, 1.0f); } @@ -110,13 +113,13 @@ int main(int argc, char *argv[]) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); } - state.cat_texture = wlr_render_texture_create(state.renderer); + state.cat_texture = wlr_texture_from_pixels(state.renderer, + WL_SHM_FORMAT_ARGB8888, cat_tex.width * 4, cat_tex.width, cat_tex.height, + cat_tex.pixel_data); if (!state.cat_texture) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); } - wlr_texture_upload_pixels(state.cat_texture, WL_SHM_FORMAT_ARGB8888, - cat_tex.width, cat_tex.width, cat_tex.height, cat_tex.pixel_data); if (!wlr_backend_start(compositor.backend)) { wlr_log(L_ERROR, "Failed to start backend"); -- cgit v1.2.3 From b31ce4220cea6acede2ae2af1b19a3a7d4b81fc6 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 18 Mar 2018 15:09:37 -0400 Subject: Add broken test client and rootston stubs --- examples/layer-shell.c | 211 +++++++++++++++++++++++++++++++ examples/meson.build | 6 + include/rootston/desktop.h | 5 + include/rootston/layers.h | 19 +++ include/rootston/view.h | 1 - protocol/meson.build | 1 + protocol/wlr-layer-shell-unstable-v1.xml | 5 +- rootston/desktop.c | 4 +- rootston/layer_shell.c | 54 ++++++++ rootston/meson.build | 1 + 10 files changed, 302 insertions(+), 5 deletions(-) create mode 100644 examples/layer-shell.c create mode 100644 include/rootston/layers.h create mode 100644 rootston/layer_shell.c (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c new file mode 100644 index 00000000..285bec5a --- /dev/null +++ b/examples/layer-shell.c @@ -0,0 +1,211 @@ +#define _POSIX_C_SOURCE 2 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlr-layer-shell-unstable-v1-client-protocol.h" + +static struct wl_compositor *compositor = NULL; +static struct zwlr_layer_shell_v1 *layer_shell = NULL; +static struct wl_output *wl_output = NULL; + +struct wl_surface *wl_surface; +struct wlr_egl egl; +struct wl_egl_window *egl_window; +struct wlr_egl_surface *egl_surface; +struct wl_callback *frame_callback; + +static uint32_t output = 0; +static uint32_t layer = -1; +static uint32_t anchor = 0; +static uint32_t width = 256, height = 256; + +static void draw(void); + +static void surface_frame_callback( + void *data, struct wl_callback *cb, uint32_t time) { + wl_callback_destroy(cb); + frame_callback = NULL; + draw(); +} + +static struct wl_callback_listener frame_listener = { + .done = surface_frame_callback +}; + +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}; + glViewport(0, 0, width, height); + glClearColor(color[0], color[1], 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); +} + +static void layer_surface_configure(void *data, + struct zwlr_layer_surface_v1 *surface, + uint32_t serial, uint32_t w, uint32_t h) { + width = w; + height = h; + zwlr_layer_surface_v1_ack_configure(surface, serial); +} + +struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .configure = layer_surface_configure, +}; + +static void handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) { + if (strcmp(interface, "wl_compositor") == 0) { + compositor = wl_registry_bind(registry, name, + &wl_compositor_interface, 1); + } else if (strcmp(interface, "wl_output") == 0) { + if (output == 0) { + wl_output = wl_registry_bind(registry, name, + &wl_output_interface, 1); + } else { + output--; + } + } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { + layer_shell = wl_registry_bind( + registry, name, &zwlr_layer_shell_v1_interface, 1); + } +} + +static void handle_global_remove(void *data, struct wl_registry *registry, + uint32_t name) { + // who cares +} + +static const struct wl_registry_listener registry_listener = { + .global = handle_global, + .global_remove = handle_global_remove, +}; + +int main(int argc, char **argv) { + wlr_log_init(L_DEBUG, NULL); + char *namespace = "wlroots"; + bool found; + int c; + while ((c = getopt(argc, argv, "w:h:o:"))) { + switch (c) { + case 'o': + output = atoi(optarg); + break; + case 'w': + width = atoi(optarg); + break; + case 'h': + height = atoi(optarg); + break; + case 'l': { + struct { + char *name; + enum zwlr_layer_shell_v1_layer value; + } layers[] = { + { "background", ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND }, + { "bottom", ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM }, + { "top", ZWLR_LAYER_SHELL_V1_LAYER_TOP }, + { "overlay", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY }, + }; + found = false; + for (size_t i = 0; i < sizeof(layers) / sizeof(layers[0]); ++i) { + if (strcmp(optarg, layers[i].name)) { + layer = layers[i].value; + found = true; + break; + } + } + if (!found) { + fprintf(stderr, "invalid layer %s\n", optarg); + return 1; + } + break; + } + case 'a': { + struct { + char *name; + uint32_t value; + } anchors[] = { + { "top", ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP }, + { "bottom", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM }, + { "left", ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT }, + { "right", ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT }, + }; + found = false; + for (size_t i = 0; i < sizeof(anchors) / sizeof(anchors[0]); ++i) { + if (strcmp(optarg, anchors[i].name)) { + anchor |= anchors[i].value; + found = true; + break; + } + } + if (!found) { + fprintf(stderr, "invalid anchor %s\n", optarg); + return 1; + } + } + default: + break; + } + } + + struct wl_display *display = wl_display_connect(NULL); + if (display == NULL) { + fprintf(stderr, "Failed to create display\n"); + return 1; + } + + struct wl_registry *registry = wl_display_get_registry(display); + wl_registry_add_listener(registry, ®istry_listener, NULL); + wl_display_dispatch(display); + wl_display_roundtrip(display); + + if (compositor == NULL) { + fprintf(stderr, "wl-compositor not available\n"); + return 1; + } + if (layer_shell == NULL) { + fprintf(stderr, "layer-shell not available\n"); + return 1; + } + if (wl_output == NULL) { + fprintf(stderr, "wl_output not available\n"); + return 1; + } + + wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, NULL, + WL_SHM_FORMAT_ARGB8888); + + wl_surface = wl_compositor_create_surface(compositor); + + struct zwlr_layer_surface_v1 *layer_surface = + zwlr_layer_shell_v1_get_layer_surface(layer_shell, + wl_surface, wl_output, layer, namespace); + zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); + // TODO: margin, interactivity, exclusive zone + + wl_surface_commit(wl_surface); + + egl_window = wl_egl_window_create(wl_surface, width, height); + egl_surface = wlr_egl_create_surface(&egl, egl_window); + + wl_display_roundtrip(display); + draw(); + + while (wl_display_dispatch(display) != -1) { + // This space intentionally left blank + } + return 0; +} diff --git a/examples/meson.build b/examples/meson.build index a83def8f..558af4ac 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -48,3 +48,9 @@ executable( dependencies: [wayland_client, wlr_protos, wlroots, threads], link_with: lib_shared, ) + +executable( + 'layer-shell', + 'layer-shell.c', + dependencies: [wayland_client, wlr_protos, wlroots] +) diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 5ff9f5e2..ad7654a1 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,8 @@ struct roots_desktop { struct wl_list views; // roots_view::link + struct wl_list layers[4]; // layer_surface::link + struct wl_list outputs; // roots_output::link struct timespec last_frame; @@ -55,6 +58,7 @@ struct roots_desktop { struct wl_listener xdg_shell_v6_surface; struct wl_listener xdg_shell_surface; struct wl_listener wl_shell_surface; + struct wl_listener layer_shell_surface; struct wl_listener decoration_new; #ifdef WLR_HAS_XWAYLAND @@ -88,6 +92,7 @@ void view_unmap(struct roots_view *view); void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data); void handle_xdg_shell_surface(struct wl_listener *listener, void *data); void handle_wl_shell_surface(struct wl_listener *listener, void *data); +void handle_layer_shell_surface(struct wl_listener *listener, void *data); void handle_xwayland_surface(struct wl_listener *listener, void *data); #endif diff --git a/include/rootston/layers.h b/include/rootston/layers.h new file mode 100644 index 00000000..269056ea --- /dev/null +++ b/include/rootston/layers.h @@ -0,0 +1,19 @@ +#ifndef ROOTSTON_LAYERS_H +#define ROOTSTON_LAYERS_H +#include +#include +#include +#include +#include + +struct roots_layer_surface { + struct wlr_layer_surface *layer_surface; + struct wl_list link; + + struct wl_listener destroy; + struct wl_listener map; + struct wl_listener unmap; + struct wl_listener surface_commit; +}; + +#endif diff --git a/include/rootston/view.h b/include/rootston/view.h index 1397a8d2..6e746e8c 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -1,6 +1,5 @@ #ifndef ROOTSTON_VIEW_H #define ROOTSTON_VIEW_H - #include #include #include diff --git a/protocol/meson.build b/protocol/meson.build index 8c8a7c0e..a41fdec3 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -39,6 +39,7 @@ client_protocols = [ [wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml'], 'idle.xml', 'screenshooter.xml', + 'wlr-layer-shell-unstable-v1.xml', ] wl_protos_src = [] diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml index 285c9b8f..c4f2a7e3 100644 --- a/protocol/wlr-layer-shell-unstable-v1.xml +++ b/protocol/wlr-layer-shell-unstable-v1.xml @@ -222,9 +222,8 @@ - - - + diff --git a/rootston/desktop.c b/rootston/desktop.c index dcf0b7b2..015a8215 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -716,7 +716,9 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->wl_shell_surface.notify = handle_wl_shell_surface; desktop->layer_shell = wlr_layer_shell_create(server->wl_display); - // TODO: Pick up new surfaces + wl_signal_add(&desktop->layer_shell->events.new_surface, + &desktop->layer_shell_surface); + desktop->layer_shell_surface.notify = handle_layer_shell_surface; #ifdef WLR_HAS_XWAYLAND const char *cursor_theme = NULL; diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c new file mode 100644 index 00000000..50bf6466 --- /dev/null +++ b/rootston/layer_shell.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "rootston/desktop.h" +#include "rootston/layers.h" +#include "rootston/server.h" + +static void handle_destroy(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_surface_commit(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_map(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_unmap(struct wl_listener *listener, void *data) { + // TODO +} + +void handle_layer_shell_surface(struct wl_listener *listener, void *data) { + struct wlr_layer_surface *layer_surface = data; + struct roots_desktop *desktop = + wl_container_of(listener, desktop, layer_shell_surface); + wlr_log(L_DEBUG, "new layer surface: namespace %s layer %d", + layer_surface->namespace, layer_surface->layer); + + struct roots_layer_surface *roots_surface = + calloc(1, sizeof(struct roots_layer_surface)); + if (!roots_surface) { + return; + } + roots_surface->surface_commit.notify = handle_surface_commit; + wl_signal_add(&layer_surface->surface->events.commit, + &roots_surface->surface_commit); + roots_surface->destroy.notify = handle_destroy; + wl_signal_add(&layer_surface->events.destroy, &roots_surface->destroy); + roots_surface->map.notify = handle_map; + 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); + + roots_surface->layer_surface = layer_surface; + + wl_list_insert(&desktop->layers[layer_surface->layer], &roots_surface->link); +} diff --git a/rootston/meson.build b/rootston/meson.build index 9dbe37c2..1b78c7c8 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -5,6 +5,7 @@ sources = [ 'ini.c', 'input.c', 'keyboard.c', + 'layer_shell.c', 'main.c', 'output.c', 'seat.c', -- cgit v1.2.3 From 4bc1cc49d5b8007145774214bc9126577b56b53c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 18 Mar 2018 17:17:28 -0400 Subject: Fix strcmp use --- examples/layer-shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 285bec5a..9b26386d 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -121,7 +121,7 @@ int main(int argc, char **argv) { }; found = false; for (size_t i = 0; i < sizeof(layers) / sizeof(layers[0]); ++i) { - if (strcmp(optarg, layers[i].name)) { + if (strcmp(optarg, layers[i].name) == 0) { layer = layers[i].value; found = true; break; @@ -145,7 +145,7 @@ int main(int argc, char **argv) { }; found = false; for (size_t i = 0; i < sizeof(anchors) / sizeof(anchors[0]); ++i) { - if (strcmp(optarg, anchors[i].name)) { + if (strcmp(optarg, anchors[i].name) == 0) { anchor |= anchors[i].value; found = true; break; -- cgit v1.2.3 From fcf8c6c8a29e3ce0a17bcf7ce1ca92fed8493502 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 19 Mar 2018 20:24:16 -0400 Subject: Fix issues preventing layer from getting allocated Now all of the steps to get rootston a reference to the layer surface are correctly wired up. --- examples/layer-shell.c | 13 +++++++------ rootston/desktop.c | 4 ++++ types/wlr_layer_shell.c | 25 ++++++++++++++++++------- 3 files changed, 29 insertions(+), 13 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 9b26386d..d2e07a90 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -21,7 +21,7 @@ struct wlr_egl_surface *egl_surface; struct wl_callback *frame_callback; static uint32_t output = 0; -static uint32_t layer = -1; +static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t anchor = 0; static uint32_t width = 256, height = 256; @@ -98,7 +98,7 @@ int main(int argc, char **argv) { char *namespace = "wlroots"; bool found; int c; - while ((c = getopt(argc, argv, "w:h:o:"))) { + while ((c = getopt(argc, argv, "w:h:o:")) != -1) { switch (c) { case 'o': output = atoi(optarg); @@ -185,9 +185,6 @@ int main(int argc, char **argv) { return 1; } - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, NULL, - WL_SHM_FORMAT_ARGB8888); - wl_surface = wl_compositor_create_surface(compositor); struct zwlr_layer_surface_v1 *layer_surface = @@ -195,8 +192,12 @@ int main(int argc, char **argv) { wl_surface, wl_output, layer, namespace); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); // 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, + WL_SHM_FORMAT_ARGB8888); egl_window = wl_egl_window_create(wl_surface, width, height); egl_surface = wlr_egl_create_surface(&egl, egl_window); diff --git a/rootston/desktop.c b/rootston/desktop.c index 015a8215..f00fc63f 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -719,6 +719,10 @@ struct roots_desktop *desktop_create(struct roots_server *server, wl_signal_add(&desktop->layer_shell->events.new_surface, &desktop->layer_shell_surface); desktop->layer_shell_surface.notify = handle_layer_shell_surface; + for (size_t i = 0; + i < sizeof(desktop->layers) / sizeof(desktop->layers[0]); ++i) { + wl_list_init(&desktop->layers[i]); + } #ifdef WLR_HAS_XWAYLAND const char *cursor_theme = NULL; diff --git a/types/wlr_layer_shell.c b/types/wlr_layer_shell.c index 8063b219..aaf9ee84 100644 --- a/types/wlr_layer_shell.c +++ b/types/wlr_layer_shell.c @@ -14,20 +14,20 @@ static void resource_handle_destroy(struct wl_client *client, wl_resource_destroy(resource); } -static struct zwlr_layer_shell_v1_interface layer_shell_impl; -static struct zwlr_layer_surface_v1_interface layer_surface_impl; +static const struct zwlr_layer_shell_v1_interface layer_shell_implementation; +static const struct zwlr_layer_surface_v1_interface layer_surface_implementation; static struct wlr_layer_client *layer_client_from_resource( struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &zwlr_layer_shell_v1_interface, - &layer_shell_impl)); + &layer_shell_implementation)); return wl_resource_get_user_data(resource); } static struct wlr_layer_surface *layer_surface_from_resource( struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &zwlr_layer_surface_v1_interface, - &layer_surface_impl)); + &layer_surface_implementation)); return wl_resource_get_user_data(resource); } @@ -291,11 +291,22 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client, wl_client_post_no_memory(wl_client); return; } + if (layer > ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) { + wl_resource_post_error(surface->resource, + ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER, + "Invalid layer %d", layer); + free(surface); + return; + } + + wl_list_init(&surface->configure_list); wl_signal_init(&surface->events.destroy); wl_signal_add(&surface->surface->events.destroy, &surface->surface_destroy_listener); surface->surface_destroy_listener.notify = handle_wlr_surface_destroyed; + wl_signal_init(&surface->events.map); + wl_signal_init(&surface->events.unmap); wlr_surface_set_role_committed(surface->surface, handle_wlr_surface_committed, surface); @@ -307,7 +318,7 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client, wl_list_insert(&client->surfaces, &surface->link); } -static struct zwlr_layer_shell_v1_interface layer_shell_impl = { +static const struct zwlr_layer_shell_v1_interface layer_shell_implementation = { .get_layer_surface = layer_shell_handle_get_layer_surface, }; @@ -347,8 +358,8 @@ static void layer_shell_bind(struct wl_client *wl_client, void *data, client->client = wl_client; client->shell = layer_shell; - wl_resource_set_implementation(client->resource, &layer_shell_impl, client, - wlr_layer_client_destroy); + wl_resource_set_implementation(client->resource, + &layer_shell_implementation, client, wlr_layer_client_destroy); wl_list_insert(&layer_shell->clients, &client->link); } -- cgit v1.2.3 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 --- examples/layer-shell.c | 7 +- include/rootston/desktop.h | 2 - include/rootston/layers.h | 3 + include/rootston/output.h | 3 + include/wlr/types/wlr_layer_shell.h | 3 +- protocol/wlr-layer-shell-unstable-v1.xml | 28 +++++-- render/egl.c | 2 +- rootston/desktop.c | 4 - rootston/layer_shell.c | 135 ++++++++++++++++++++++++++++++- rootston/output.c | 57 ++++++++++--- types/wlr_layer_shell.c | 26 +++++- 11 files changed, 235 insertions(+), 35 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index d2e07a90..b5542f7a 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -23,7 +23,7 @@ struct wl_callback *frame_callback; static uint32_t output = 0; static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t anchor = 0; -static uint32_t width = 256, height = 256; +static int32_t width = 256, height = 256; static void draw(void); @@ -98,7 +98,7 @@ int main(int argc, char **argv) { char *namespace = "wlroots"; bool found; int c; - while ((c = getopt(argc, argv, "w:h:o:")) != -1) { + while ((c = getopt(argc, argv, "w:h:o:l:a:")) != -1) { switch (c) { case 'o': output = atoi(optarg); @@ -190,7 +190,10 @@ int main(int argc, char **argv) { struct zwlr_layer_surface_v1 *layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, wl_surface, wl_output, layer, namespace); + zwlr_layer_surface_v1_set_size(layer_surface, width, height); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); + zwlr_layer_surface_v1_add_listener(layer_surface, + &layer_surface_listener, layer_surface); // TODO: margin, interactivity, exclusive zone wl_surface_commit(wl_surface); wl_display_dispatch(display); diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index ad7654a1..92cc6d9d 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -29,8 +29,6 @@ struct roots_desktop { struct wl_list views; // roots_view::link - struct wl_list layers[4]; // layer_surface::link - struct wl_list outputs; // roots_output::link struct timespec last_frame; diff --git a/include/rootston/layers.h b/include/rootston/layers.h index 269056ea..f432d53d 100644 --- a/include/rootston/layers.h +++ b/include/rootston/layers.h @@ -14,6 +14,9 @@ struct roots_layer_surface { struct wl_listener map; struct wl_listener unmap; struct wl_listener surface_commit; + + bool configured; + struct wlr_box geo; }; #endif diff --git a/include/rootston/output.h b/include/rootston/output.h index a852a204..5545d76a 100644 --- a/include/rootston/output.h +++ b/include/rootston/output.h @@ -14,6 +14,7 @@ struct roots_output { struct wl_list link; // roots_desktop:outputs struct roots_view *fullscreen_view; + struct wl_list layers[4]; // layer_surface::link struct timespec last_frame; struct wlr_output_damage *damage; @@ -35,5 +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); #endif diff --git a/include/wlr/types/wlr_layer_shell.h b/include/wlr/types/wlr_layer_shell.h index 0807fe8d..3002345d 100644 --- a/include/wlr/types/wlr_layer_shell.h +++ b/include/wlr/types/wlr_layer_shell.h @@ -42,14 +42,12 @@ struct wlr_layer_client { }; struct wlr_layer_surface_state { - // Client uint32_t anchor; uint32_t exclusive_zone; struct { uint32_t top, right, bottom, left; } margin; bool keyboard_interactive; - // Server uint32_t width, height; }; @@ -61,6 +59,7 @@ struct wlr_layer_surface_configure { struct wlr_layer_surface { struct wlr_surface *surface; + struct wlr_output *output; struct wlr_layer_client *client; struct wl_resource *resource; struct wl_list link; // wlr_layer_client:surfaces diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml index c4f2a7e3..d6de59ab 100644 --- a/protocol/wlr-layer-shell-unstable-v1.xml +++ b/protocol/wlr-layer-shell-unstable-v1.xml @@ -86,11 +86,27 @@ are designed to be rendered as a layer of a stacked desktop-like environment. - Layer surface state (anchor, exclusive zone, margin, interactivity) is - double-buffered, and will be applied at the time wl_surface.commit of the - corresponding wl_surface is called. + Layer surface state (size, anchor, exclusive zone, margin, interactivity) + is double-buffered, and will be applied at the time wl_surface.commit of + the corresponding wl_surface is called. + + + Sets the size of the surface in pixels. The compositor will display the + surface centered with respect to its anchors. + + If you pass -1 for either value, the compositor will assign it and + inform you of the assignment in the configure event. You must set your + anchor to opposite edges in the dimensions you omit; not doing so is a + protocol error. Both values are -1 by default. + + Size is double-buffered, see wl_surface.commit. + + + + + Requests that the compositor anchor the surface to the specified edges @@ -222,9 +238,9 @@ - - + + + diff --git a/render/egl.c b/render/egl.c index f2966774..d230f589 100644 --- a/render/egl.c +++ b/render/egl.c @@ -426,7 +426,7 @@ int wlr_egl_get_dmabuf_formats(struct wlr_egl *egl, int **formats) { if (!egl->egl_exts.dmabuf_import || !egl->egl_exts.dmabuf_import_modifiers) { - wlr_log(L_ERROR, "dmabuf extension not present"); + wlr_log(L_DEBUG, "dmabuf extension not present"); return -1; } diff --git a/rootston/desktop.c b/rootston/desktop.c index f00fc63f..015a8215 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -719,10 +719,6 @@ struct roots_desktop *desktop_create(struct roots_server *server, wl_signal_add(&desktop->layer_shell->events.new_surface, &desktop->layer_shell_surface); desktop->layer_shell_surface.notify = handle_layer_shell_surface; - for (size_t i = 0; - i < sizeof(desktop->layers) / sizeof(desktop->layers[0]); ++i) { - wl_list_init(&desktop->layers[i]); - } #ifdef WLR_HAS_XWAYLAND const char *cursor_theme = NULL; diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index 50bf6466..25e683fe 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -8,8 +8,112 @@ #include #include "rootston/desktop.h" #include "rootston/layers.h" +#include "rootston/output.h" #include "rootston/server.h" +static void apply_exclusive(struct wlr_box *output_area, + uint32_t anchor, uint32_t exclusive) { + struct { + uint32_t anchors; + int *value; + int multiplier; + } edges[] = { + { + .anchors = + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, + .value = &output_area->y, + .multiplier = 1, + }, + { + .anchors = + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, + .value = &output_area->height, + .multiplier = -1, + }, + { + .anchors = + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, + .value = &output_area->x, + .multiplier = 1, + }, + { + .anchors = + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, + .value = &output_area->width, + .multiplier = -1, + }, + }; + for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); ++i) { + if ((anchor & edges[i].anchors)) { + edges[i].value += exclusive * edges[i].multiplier; + } + } +} + +static void arrange_layer(struct wlr_output *output, struct wl_list *list) { + struct wlr_box output_area = { .x = 0, .y = 0 }; + wlr_output_effective_resolution(output, + &output_area.width, &output_area.height); + struct roots_layer_surface *roots_surface; + 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; + struct wlr_box box = { .width = state->width, .height = state->height }; + // Horizontal axis + const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT + | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + if ((state->anchor & both_horiz) && box.width == -1) { + box.x = 0; + box.width = output_area.width; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { + box.x = output_area.x; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { + box.x = output_area.width - box.width; + } else { + box.x = (output_area.width / 2) - (box.width / 2); + } + // Vertical axis + const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP + | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; + if ((state->anchor & both_vert) && box.height == -1) { + box.y = 0; + box.height = output_area.height; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { + box.y = output_area.y; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { + box.y = output_area.height - box.height; + } else { + box.y = (output_area.height / 2) - (box.height / 2); + } + wlr_log(L_DEBUG, "arranged layer at %dx%d@%d,%d", + box.width, box.height, box.x, box.y); + roots_surface->geo = box; + apply_exclusive(&output_area, state->anchor, state->exclusive_zone); + if (box.width != (int)state->width + || box.height != (int)state->height + || !roots_surface->configured) { + wlr_layer_surface_configure(layer, box.width, box.height); + roots_surface->configured = true; + } + } +} + +static void arrange_layers(struct wlr_output *_output) { + struct roots_output *output = _output->data; + size_t layers = sizeof(output->layers) / sizeof(output->layers[0]); + for (size_t i = 0; i < layers; ++i) { + arrange_layer(output->wlr_output, &output->layers[i]); + } +} + static void handle_destroy(struct wl_listener *listener, void *data) { // TODO } @@ -19,7 +123,13 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { } static void handle_map(struct wl_listener *listener, void *data) { - // TODO + struct wlr_layer_surface *layer_surface = 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); } static void handle_unmap(struct wl_listener *listener, void *data) { @@ -30,8 +140,14 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { struct wlr_layer_surface *layer_surface = data; struct roots_desktop *desktop = wl_container_of(listener, desktop, layer_shell_surface); - wlr_log(L_DEBUG, "new layer surface: namespace %s layer %d", - layer_surface->namespace, layer_surface->layer); + wlr_log(L_DEBUG, "new layer surface: namespace %s layer %d anchor %d %dx%d %d,%d,%d,%d", + layer_surface->namespace, layer_surface->layer, layer_surface->layer, + layer_surface->client_pending.width, + layer_surface->client_pending.height, + layer_surface->client_pending.margin.top, + layer_surface->client_pending.margin.right, + layer_surface->client_pending.margin.bottom, + layer_surface->client_pending.margin.left); struct roots_layer_surface *roots_surface = calloc(1, sizeof(struct roots_layer_surface)); @@ -49,6 +165,17 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { wl_signal_add(&layer_surface->events.unmap, &roots_surface->unmap); roots_surface->layer_surface = layer_surface; + layer_surface->data = roots_surface; + + struct roots_output *output = layer_surface->output->data; + wl_list_insert(&output->layers[layer_surface->layer], &roots_surface->link); + + // Temporarily set the layer's current state to client_pending + // So that we can easily arrange it + struct wlr_layer_surface_state old_state = layer_surface->current; + layer_surface->current = layer_surface->client_pending; + + arrange_layers(output->wlr_output); - wl_list_insert(&desktop->layers[layer_surface->layer], &roots_surface->link); + layer_surface->current = old_state; } 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) { diff --git a/types/wlr_layer_shell.c b/types/wlr_layer_shell.c index aaf9ee84..631b7009 100644 --- a/types/wlr_layer_shell.c +++ b/types/wlr_layer_shell.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include "util/signal.h" @@ -69,12 +70,31 @@ static void layer_surface_handle_ack_configure(struct wl_client *client, surface->current.anchor = configure->state.anchor; surface->current.exclusive_zone = configure->state.exclusive_zone; surface->current.margin = configure->state.margin; + surface->current.width = configure->state.width; + surface->current.height = configure->state.height; layer_surface_configure_destroy(configure); } +static void layer_surface_handle_set_size(struct wl_client *client, + struct wl_resource *resource, int32_t width, int32_t height) { + struct wlr_layer_surface *surface = layer_surface_from_resource(resource); + surface->client_pending.width = width; + surface->client_pending.height = height; +} + static void layer_surface_handle_set_anchor(struct wl_client *client, struct wl_resource *resource, uint32_t anchor) { + const uint32_t max_anchor = + ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | + ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | + ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | + ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; + if (anchor > max_anchor) { + wl_resource_post_error(resource, + ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_ANCHOR, + "invalid anchor %d", anchor); + } struct wlr_layer_surface *surface = layer_surface_from_resource(resource); surface->client_pending.anchor = anchor; } @@ -110,6 +130,7 @@ static void layer_surface_handle_get_popup(struct wl_client *client, static const struct zwlr_layer_surface_v1_interface layer_surface_implementation = { .destroy = resource_handle_destroy, .ack_configure = layer_surface_handle_ack_configure, + .set_size = layer_surface_handle_set_size, .set_anchor = layer_surface_handle_set_anchor, .set_exclusive_zone = layer_surface_handle_set_exclusive_zone, .set_margin = layer_surface_handle_set_margin, @@ -155,7 +176,7 @@ static void layer_surface_resource_destroy(struct wl_resource *resource) { static bool wlr_layer_surface_state_changed(struct wlr_layer_surface *surface) { if (!surface->configured) { - return false; + return true; } struct wlr_layer_surface_state *state; @@ -239,6 +260,8 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface, surface->current.margin = surface->client_pending.margin; surface->current.keyboard_interactive = surface->client_pending.keyboard_interactive; + surface->current.width = surface->client_pending.width; + surface->current.height = surface->client_pending.height; if (!surface->added) { surface->added = true; @@ -280,6 +303,7 @@ static void layer_shell_handle_get_layer_surface(struct wl_client *wl_client, surface->client = client; surface->surface = wlr_surface_from_resource(surface_resource); + surface->output = wlr_output_from_resource(output_resource); surface->resource = wl_resource_create(wl_client, &zwlr_layer_surface_v1_interface, wl_resource_get_version(client_resource), -- 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 'examples') 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 0f7e78f6aa8530adc0dcc74a760b6478720e2ded Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 20 Mar 2018 21:45:50 -0400 Subject: Fix issue with multiple outputs in layer example --- examples/layer-shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 91c509f6..f006a1b7 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -94,7 +94,7 @@ static void handle_global(void *data, struct wl_registry *registry, compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); } else if (strcmp(interface, "wl_output") == 0) { - if (output == 0) { + if (output == 0 && !wl_output) { wl_output = wl_registry_bind(registry, name, &wl_output_interface, 1); } else { -- cgit v1.2.3 From b73c4f48c10ae79a33d1611fb641d22b8b619c39 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 20 Mar 2018 21:57:16 -0400 Subject: Fix exclusive zone among other layers --- examples/layer-shell.c | 9 +++++++-- rootston/layer_shell.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index f006a1b7..f3b9d3a0 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -119,9 +119,10 @@ static const struct wl_registry_listener registry_listener = { int main(int argc, char **argv) { wlr_log_init(L_DEBUG, NULL); char *namespace = "wlroots"; + int exclusive_zone = 0; bool found; int c; - while ((c = getopt(argc, argv, "w:h:o:l:a:")) != -1) { + while ((c = getopt(argc, argv, "w:h:o:l:a:x:")) != -1) { switch (c) { case 'o': output = atoi(optarg); @@ -132,6 +133,9 @@ int main(int argc, char **argv) { case 'h': height = atoi(optarg); break; + case 'x': + exclusive_zone = atoi(optarg); + break; case 'l': { struct { char *name; @@ -215,9 +219,10 @@ int main(int argc, char **argv) { wl_surface, wl_output, layer, namespace); zwlr_layer_surface_v1_set_size(layer_surface, width, height); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); + zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, exclusive_zone); zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, layer_surface); - // TODO: margin, interactivity, exclusive zone + // TODO: margin, interactivity wl_surface_commit(wl_surface); wl_display_roundtrip(display); diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index c0dff85a..ac7b2b20 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -53,7 +53,7 @@ static void apply_exclusive(struct wlr_box *output_area, }; for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); ++i) { if ((anchor & edges[i].anchors)) { - edges[i].value += exclusive * edges[i].multiplier; + *edges[i].value += exclusive * edges[i].multiplier; } } } -- cgit v1.2.3 From d1c0e6fe2c21b4c7f651a82fb7342b54a4989c39 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 24 Mar 2018 18:00:01 -0400 Subject: Add layer_surface.close --- examples/layer-shell.c | 13 ++++++++++++- include/wlr/types/wlr_layer_shell.h | 7 ++++++- protocol/wlr-layer-shell-unstable-v1.xml | 10 ++++++++++ rootston/layer_shell.c | 6 ++++-- types/wlr_layer_shell.c | 11 +++++++++++ 5 files changed, 43 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index f3b9d3a0..08826251 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -25,6 +25,7 @@ static uint32_t output = 0; static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t anchor = 0; static int32_t width = 256, height = 256; +static bool run_display = true; static struct { struct timespec last_frame; @@ -84,8 +85,18 @@ static void layer_surface_configure(void *data, zwlr_layer_surface_v1_ack_configure(surface, serial); } +static void layer_surface_closed(void *data, + struct zwlr_layer_surface_v1 *surface) { + eglDestroySurface(egl.display, egl_surface); + wl_egl_window_destroy(egl_window); + zwlr_layer_surface_v1_destroy(surface); + wl_surface_destroy(wl_surface); + run_display = false; +} + struct zwlr_layer_surface_v1_listener layer_surface_listener = { .configure = layer_surface_configure, + .closed = layer_surface_closed, }; static void handle_global(void *data, struct wl_registry *registry, @@ -235,7 +246,7 @@ int main(int argc, char **argv) { wl_display_roundtrip(display); draw(); - while (wl_display_dispatch(display) != -1) { + while (wl_display_dispatch(display) != -1 && run_display) { // This space intentionally left blank } return 0; diff --git a/include/wlr/types/wlr_layer_shell.h b/include/wlr/types/wlr_layer_shell.h index 3002345d..5d9feb27 100644 --- a/include/wlr/types/wlr_layer_shell.h +++ b/include/wlr/types/wlr_layer_shell.h @@ -67,7 +67,7 @@ struct wlr_layer_surface { const char *namespace; enum zwlr_layer_shell_v1_layer layer; - bool added, configured, mapped; + bool added, configured, mapped, closed; uint32_t configure_serial; struct wl_event_source *configure_idle; uint32_t configure_next_serial; @@ -99,4 +99,9 @@ void wlr_layer_shell_destroy(struct wlr_layer_shell *layer_shell); void wlr_layer_surface_configure(struct wlr_layer_surface *surface, uint32_t width, uint32_t height); +/** + * Unmaps this layer surface and notifies the client that it has been closed. + */ +void wlr_layer_surface_close(struct wlr_layer_surface *surface); + #endif diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml index d6de59ab..b5cb3d3a 100644 --- a/protocol/wlr-layer-shell-unstable-v1.xml +++ b/protocol/wlr-layer-shell-unstable-v1.xml @@ -237,6 +237,16 @@ + + + The closed event is sent by the compositor when the surface will no + longer be shown. The output may have been destroyed or the user may have + asked for it to be removed. Further changes to the surface will be ignored. + The client should destroy the resource after receiving this event, and + create a new surface if they so choose. + + + diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index ac7b2b20..114a5f29 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -118,7 +118,7 @@ static void handle_output_destroy(struct wl_listener *listener, void *data) { struct roots_layer_surface *layer = wl_container_of(listener, layer, output_destroy); layer->layer_surface->output = NULL; - wl_resource_destroy(layer->layer_surface->resource); + wlr_layer_surface_close(layer->layer_surface); } static void handle_surface_commit(struct wl_listener *listener, void *data) { @@ -135,7 +135,9 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { static void unmap(struct wlr_layer_surface *layer_surface) { struct roots_layer_surface *layer = layer_surface->data; - wl_list_remove(&layer->link); + if (layer->link.prev) { + wl_list_remove(&layer->link); + } struct wlr_output *wlr_output = layer_surface->output; if (wlr_output != NULL) { diff --git a/types/wlr_layer_shell.c b/types/wlr_layer_shell.c index 631b7009..59f8d568 100644 --- a/types/wlr_layer_shell.c +++ b/types/wlr_layer_shell.c @@ -244,6 +244,12 @@ void wlr_layer_surface_configure(struct wlr_layer_surface *surface, wlr_layer_surface_schedule_configure(surface); } +void wlr_layer_surface_close(struct wlr_layer_surface *surface) { + surface->closed = true; + layer_surface_unmap(surface); + zwlr_layer_surface_v1_send_closed(surface->resource); +} + static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface, void *role_data) { struct wlr_layer_surface *surface = role_data; @@ -255,6 +261,11 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface, return; } + if (surface->closed) { + // Ignore commits after the compositor has closed it + return; + } + surface->current.anchor = surface->client_pending.anchor; surface->current.exclusive_zone = surface->client_pending.exclusive_zone; surface->current.margin = surface->client_pending.margin; -- cgit v1.2.3 From df9dbf31706254887652b54214e2c9ee2346f0e8 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 26 Mar 2018 12:01:13 -0400 Subject: Fix rebase issues; rearrange layers on destroy --- examples/layer-shell.c | 16 ++++++++++++---- rootston/layer_shell.c | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 08826251..999d948f 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 199309L +#include #include #include #include @@ -24,7 +25,7 @@ struct wl_callback *frame_callback; static uint32_t output = 0; static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t anchor = 0; -static int32_t width = 256, height = 256; +static uint32_t width = 256, height = 256; static bool run_display = true; static struct { @@ -82,6 +83,9 @@ static void layer_surface_configure(void *data, uint32_t serial, uint32_t w, uint32_t h) { width = w; height = h; + if (egl_window) { + wl_egl_window_resize(egl_window, width, height, 0, 0); + } zwlr_layer_surface_v1_ack_configure(surface, serial); } @@ -223,11 +227,16 @@ int main(int argc, char **argv) { return 1; } + wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, NULL, + WL_SHM_FORMAT_ARGB8888); + wl_surface = wl_compositor_create_surface(compositor); + assert(wl_surface); struct zwlr_layer_surface_v1 *layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, wl_surface, wl_output, layer, namespace); + assert(layer_surface); zwlr_layer_surface_v1_set_size(layer_surface, width, height); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, exclusive_zone); @@ -237,11 +246,10 @@ int main(int argc, char **argv) { wl_surface_commit(wl_surface); wl_display_roundtrip(display); - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, NULL, - WL_SHM_FORMAT_ARGB8888); - egl_window = wl_egl_window_create(wl_surface, width, height); + assert(egl_window); egl_surface = wlr_egl_create_surface(&egl, egl_window); + assert(egl_surface); wl_display_roundtrip(display); draw(); diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index c4e82535..ccea4f8d 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -153,6 +153,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { unmap(layer->layer_surface); } wl_list_remove(&layer->output_destroy.link); + arrange_layers(layer->layer_surface->output); free(layer); } -- cgit v1.2.3 From 86ca4bea6de9b3494235201f5587cb7e00aed84e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 26 Mar 2018 18:12:31 -0400 Subject: Fix layer rendering/layout bugs --- examples/layer-shell.c | 32 ++++++-- include/rootston/layers.h | 1 + include/wlr/types/wlr_layer_shell.h | 5 +- protocol/wlr-layer-shell-unstable-v1.xml | 31 +++++-- rootston/layer_shell.c | 136 ++++++++++++++++++++++--------- types/wlr_layer_shell.c | 35 ++++---- types/wlr_seat.c | 5 +- 7 files changed, 171 insertions(+), 74 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 999d948f..3518a56f 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -26,6 +26,7 @@ static uint32_t output = 0; static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t anchor = 0; static uint32_t width = 256, height = 256; +static double alpha = 1.0; static bool run_display = true; static struct { @@ -67,7 +68,7 @@ static void draw(void) { } glViewport(0, 0, width, height); - glClearColor(demo.color[0], demo.color[1], demo.color[2], 1.0); + glClearColor(demo.color[0], demo.color[1], demo.color[2], alpha); glClear(GL_COLOR_BUFFER_BIT); frame_callback = wl_surface_frame(wl_surface); @@ -135,9 +136,11 @@ int main(int argc, char **argv) { wlr_log_init(L_DEBUG, NULL); char *namespace = "wlroots"; int exclusive_zone = 0; + int32_t margin_top = 0, margin_right = 0, + margin_bottom = 0, margin_left = 0; bool found; int c; - while ((c = getopt(argc, argv, "w:h:o:l:a:x:")) != -1) { + while ((c = getopt(argc, argv, "w:h:o:l:a:x:m:t:")) != -1) { switch (c) { case 'o': output = atoi(optarg); @@ -197,6 +200,22 @@ int main(int argc, char **argv) { fprintf(stderr, "invalid anchor %s\n", optarg); return 1; } + break; + } + case 't': + alpha = atof(optarg); + break; + case 'm': { + char *endptr = optarg; + margin_top = strtol(endptr, &endptr, 10); + assert(*endptr == ','); + margin_right = strtol(endptr + 1, &endptr, 10); + assert(*endptr == ','); + margin_bottom = strtol(endptr + 1, &endptr, 10); + assert(*endptr == ','); + margin_left = strtol(endptr + 1, &endptr, 10); + assert(!*endptr); + break; } default: break; @@ -227,8 +246,9 @@ int main(int argc, char **argv) { return 1; } - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, NULL, - WL_SHM_FORMAT_ARGB8888); + EGLint attribs[] = { EGL_ALPHA_SIZE, 8, EGL_NONE }; + wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, + attribs, WL_SHM_FORMAT_ARGB8888); wl_surface = wl_compositor_create_surface(compositor); assert(wl_surface); @@ -240,9 +260,11 @@ int main(int argc, char **argv) { zwlr_layer_surface_v1_set_size(layer_surface, width, height); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, exclusive_zone); + zwlr_layer_surface_v1_set_margin(layer_surface, + margin_top, margin_right, margin_bottom, margin_left); zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, layer_surface); - // TODO: margin, interactivity + // TODO: interactivity wl_surface_commit(wl_surface); wl_display_roundtrip(display); diff --git a/include/rootston/layers.h b/include/rootston/layers.h index 43041786..cc285fe7 100644 --- a/include/rootston/layers.h +++ b/include/rootston/layers.h @@ -15,6 +15,7 @@ struct roots_layer_surface { struct wl_listener unmap; struct wl_listener surface_commit; struct wl_listener output_destroy; + struct wl_listener output_mode; bool configured; struct wlr_box geo; diff --git a/include/wlr/types/wlr_layer_shell.h b/include/wlr/types/wlr_layer_shell.h index 5d9feb27..c24b391e 100644 --- a/include/wlr/types/wlr_layer_shell.h +++ b/include/wlr/types/wlr_layer_shell.h @@ -43,12 +43,13 @@ struct wlr_layer_client { struct wlr_layer_surface_state { uint32_t anchor; - uint32_t exclusive_zone; + int32_t exclusive_zone; struct { uint32_t top, right, bottom, left; } margin; bool keyboard_interactive; - uint32_t width, height; + uint32_t desired_width, desired_height; + uint32_t actual_width, actual_height; }; struct wlr_layer_surface_configure { diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml index b5cb3d3a..fe2c72cd 100644 --- a/protocol/wlr-layer-shell-unstable-v1.xml +++ b/protocol/wlr-layer-shell-unstable-v1.xml @@ -96,15 +96,15 @@ Sets the size of the surface in pixels. The compositor will display the surface centered with respect to its anchors. - If you pass -1 for either value, the compositor will assign it and + If you pass 0 for either value, the compositor will assign it and inform you of the assignment in the configure event. You must set your anchor to opposite edges in the dimensions you omit; not doing so is a - protocol error. Both values are -1 by default. + protocol error. Both values are 0 by default. Size is double-buffered, see wl_surface.commit. - - + + @@ -127,13 +127,28 @@ implementation-dependent - do not assume that this region will not actually be occluded. - This value is only meaningful if the surface is anchored to an edge, - rather than a corner. The zone is the number of pixels from the edge - that are considered exclusive. + A positive value is only meaningful if the surface is anchored to an + edge, rather than a corner. The zone is the number of pixels from the + edge that are considered exclusive. + + Surfaces that do not wish to have an exclusive zone may instead specify + how they should interact with surfaces that do. If set to zero, the + surface indicates that it would like to be moved to avoid occluding + surfaces with a positive excluzive zone. If set to -1, the surface + indicates that it would not like to be moved to accomodate for other + surfaces, and the compositor should extend it all the way to the edges + it is anchored to. + + For example, a panel might set its exclusive zone to 10 pixels, so that + maximized shell surfaces are not shown on top of it. A notification + might set its exclusive zone to zero, so that it is moved to avoid + occluding the panel, but shell surfaces are shown underneath it. A + wallpaper or lock screen might set their exclusive zone to -1, so that + they stretch below or over the panel. Exclusive zone is double-buffered, see wl_surface.commit. - + diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index e7604ec5..e2d5b9f0 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -12,7 +12,10 @@ #include "rootston/server.h" static void apply_exclusive(struct wlr_box *usable_area, - uint32_t anchor, uint32_t exclusive) { + uint32_t anchor, int32_t exclusive) { + if (exclusive <= 0) { + return; + } struct { uint32_t anchors; int *positive_axis; @@ -64,48 +67,80 @@ static void apply_exclusive(struct wlr_box *usable_area, } static void arrange_layer(struct wlr_output *output, struct wl_list *list, - struct wlr_box *usable_area) { + struct wlr_box *usable_area, bool exclusive) { struct roots_layer_surface *roots_surface; + struct wlr_box full_area = { 0 }; + wlr_output_effective_resolution(output, + &full_area.width, &full_area.height); 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; - struct wlr_box box = { .width = state->width, .height = state->height }; + if (exclusive) { + if (state->exclusive_zone <= 0) { + continue; + } + } else { + if (state->exclusive_zone > 0) { + continue; + } + } + struct wlr_box bounds; + if (state->exclusive_zone == -1) { + bounds = full_area; + } else { + bounds = *usable_area; + } + struct wlr_box box = { + .width = state->desired_width, + .height = state->desired_height + }; // Horizontal axis const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; if ((state->anchor & both_horiz) && box.width == 0) { - box.x = 0; - box.width = usable_area->width; + box.x = bounds.x; + box.width = bounds.width; } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { - box.x = usable_area->x; + box.x = bounds.x; } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { - box.x = usable_area->x + (usable_area->width - box.width); + box.x = bounds.x + (bounds.width - box.width); } else { - box.x = usable_area->x + ((usable_area->width / 2) - (box.width / 2)); + box.x = bounds.x + ((bounds.width / 2) - (box.width / 2)); } // Vertical axis const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; if ((state->anchor & both_vert) && box.height == 0) { - box.y = 0; - box.height = usable_area->height; + box.y = bounds.y; + box.height = bounds.height; } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { - box.y = usable_area->y; + box.y = bounds.y; } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { - box.y = usable_area->y + (usable_area->height - box.height); + box.y = bounds.y + (bounds.height - box.height); } else { - box.y = usable_area->y + ((usable_area->height / 2) - (box.height / 2)); + box.y = bounds.y + ((bounds.height / 2) - (box.height / 2)); + } + // Margin + if ((state->anchor & both_horiz)) { + box.x += state->margin.left; + box.width -= state->margin.left + state->margin.right; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { + box.x += state->margin.bottom; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { + box.x -= state->margin.right; } - wlr_log(L_DEBUG, "arranged layer at %dx%d@%d,%d", - box.width, box.height, box.x, box.y); + if ((state->anchor & both_vert)) { + box.y += state->margin.top; + box.height -= state->margin.top + state->margin.bottom; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { + box.y += state->margin.top; + } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { + box.y -= state->margin.bottom; + } + // Apply roots_surface->geo = box; apply_exclusive(usable_area, state->anchor, state->exclusive_zone); - if (!roots_surface->configured || - box.width != (int)state->width || - box.height != (int)state->height) { - wlr_layer_surface_configure(layer, box.width, box.height); - roots_surface->configured = true; - } + wlr_layer_surface_configure(layer, box.width, box.height); } } @@ -116,25 +151,20 @@ static void arrange_layers(struct wlr_output *_output) { wlr_output_effective_resolution(output->wlr_output, &usable_area.width, &usable_area.height); + // Arrange exclusive surfaces from top->bottom arrange_layer(output->wlr_output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], - &usable_area); - arrange_layer(output->wlr_output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], - &usable_area); - memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box)); - + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], + &usable_area, true); arrange_layer(output->wlr_output, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], - &usable_area); - - memset(&usable_area, 0, sizeof(struct wlr_box)); - wlr_output_effective_resolution(output->wlr_output, - &usable_area.width, &usable_area.height); - + &usable_area, true); arrange_layer(output->wlr_output, - &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], - &usable_area); + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], + &usable_area, true); + arrange_layer(output->wlr_output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], + &usable_area, true); + memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box)); struct roots_view *view; wl_list_for_each(view, &output->desktop->views, link) { @@ -142,15 +172,37 @@ static void arrange_layers(struct wlr_output *_output) { view_arrange_maximized(view); } } + + // Arrange non-exlusive surfaces from top->bottom + wlr_output_effective_resolution(output->wlr_output, + &usable_area.width, &usable_area.height); + arrange_layer(output->wlr_output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], + &usable_area, false); + arrange_layer(output->wlr_output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP], + &usable_area, false); + arrange_layer(output->wlr_output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], + &usable_area, false); + arrange_layer(output->wlr_output, + &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], + &usable_area, false); } static void handle_output_destroy(struct wl_listener *listener, void *data) { struct roots_layer_surface *layer = 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_surface_commit(struct wl_listener *listener, void *data) { struct roots_layer_surface *layer = wl_container_of(listener, layer, surface_commit); @@ -183,6 +235,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { unmap(layer->layer_surface); } wl_list_remove(&layer->output_destroy.link); + wl_list_remove(&layer->output_mode.link); arrange_layers(layer->layer_surface->output); free(layer); } @@ -205,10 +258,11 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { struct wlr_layer_surface *layer_surface = data; struct roots_desktop *desktop = wl_container_of(listener, desktop, layer_shell_surface); - wlr_log(L_DEBUG, "new layer surface: namespace %s layer %d anchor %d %dx%d %d,%d,%d,%d", + wlr_log(L_DEBUG, "new layer surface: namespace %s layer %d anchor %d " + "size %dx%d margin %d,%d,%d,%d", layer_surface->namespace, layer_surface->layer, layer_surface->layer, - layer_surface->client_pending.width, - layer_surface->client_pending.height, + layer_surface->client_pending.desired_width, + layer_surface->client_pending.desired_height, layer_surface->client_pending.margin.top, layer_surface->client_pending.margin.right, layer_surface->client_pending.margin.bottom, @@ -228,6 +282,10 @@ 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->destroy.notify = handle_destroy; wl_signal_add(&layer_surface->events.destroy, &roots_surface->destroy); roots_surface->map.notify = handle_map; diff --git a/types/wlr_layer_shell.c b/types/wlr_layer_shell.c index 59f8d568..04c8fbd5 100644 --- a/types/wlr_layer_shell.c +++ b/types/wlr_layer_shell.c @@ -66,21 +66,17 @@ static void layer_surface_handle_ack_configure(struct wl_client *client, surface->configured = true; surface->configure_serial = serial; - - surface->current.anchor = configure->state.anchor; - surface->current.exclusive_zone = configure->state.exclusive_zone; - surface->current.margin = configure->state.margin; - surface->current.width = configure->state.width; - surface->current.height = configure->state.height; + surface->current.actual_width = configure->state.actual_width; + surface->current.actual_height = configure->state.actual_height; layer_surface_configure_destroy(configure); } static void layer_surface_handle_set_size(struct wl_client *client, - struct wl_resource *resource, int32_t width, int32_t height) { + struct wl_resource *resource, uint32_t width, uint32_t height) { struct wlr_layer_surface *surface = layer_surface_from_resource(resource); - surface->client_pending.width = width; - surface->client_pending.height = height; + surface->client_pending.desired_width = width; + surface->client_pending.desired_height = height; } static void layer_surface_handle_set_anchor(struct wl_client *client, @@ -100,7 +96,7 @@ static void layer_surface_handle_set_anchor(struct wl_client *client, } static void layer_surface_handle_set_exclusive_zone(struct wl_client *client, - struct wl_resource *resource, uint32_t zone) { + struct wl_resource *resource, int32_t zone) { struct wlr_layer_surface *surface = layer_surface_from_resource(resource); surface->client_pending.exclusive_zone = zone; } @@ -188,8 +184,9 @@ static bool wlr_layer_surface_state_changed(struct wlr_layer_surface *surface) { state = &configure->state; } - return !memcmp(state, &surface->server_pending, - sizeof(struct wlr_layer_surface_state)); + bool changed = state->actual_width != surface->server_pending.actual_width + || state->actual_height != surface->server_pending.actual_height; + return changed; } static void wlr_layer_surface_send_configure(void *user_data) { @@ -204,10 +201,12 @@ static void wlr_layer_surface_send_configure(void *user_data) { wl_list_insert(surface->configure_list.prev, &configure->link); configure->serial = surface->configure_next_serial; - configure->state = surface->server_pending; + configure->state.actual_width = surface->server_pending.actual_width; + configure->state.actual_height = surface->server_pending.actual_height; zwlr_layer_surface_v1_send_configure(surface->resource, - configure->serial, configure->state.width, configure->state.height); + configure->serial, configure->state.actual_width, + configure->state.actual_height); } static uint32_t wlr_layer_surface_schedule_configure( @@ -239,8 +238,8 @@ static uint32_t wlr_layer_surface_schedule_configure( void wlr_layer_surface_configure(struct wlr_layer_surface *surface, uint32_t width, uint32_t height) { - surface->server_pending.width = width; - surface->server_pending.height = height; + surface->server_pending.actual_width = width; + surface->server_pending.actual_height = height; wlr_layer_surface_schedule_configure(surface); } @@ -271,8 +270,8 @@ static void handle_wlr_surface_committed(struct wlr_surface *wlr_surface, surface->current.margin = surface->client_pending.margin; surface->current.keyboard_interactive = surface->client_pending.keyboard_interactive; - surface->current.width = surface->client_pending.width; - surface->current.height = surface->client_pending.height; + surface->current.desired_width = surface->client_pending.desired_width; + surface->current.desired_height = surface->client_pending.desired_height; if (!surface->added) { surface->added = true; diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 93f6d872..9793df74 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -1257,8 +1257,9 @@ bool wlr_seat_touch_has_grab(struct wlr_seat *seat) { } bool wlr_seat_validate_grab_serial(struct wlr_seat *seat, uint32_t serial) { - return serial == seat->pointer_state.grab_serial || - serial == seat->touch_state.grab_serial; + return true; + //return serial == seat->pointer_state.grab_serial || + // serial == seat->touch_state.grab_serial; } struct wlr_seat_client *wlr_seat_client_from_resource( -- cgit v1.2.3 From 0e318df13d4d98ffc69f2390562fc03aeca36f3b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 26 Mar 2018 18:44:36 -0400 Subject: Add margin animation to the example demo --- examples/layer-shell.c | 27 ++++++++++++++++++++++----- rootston/layer_shell.c | 28 +++++++++++++++++++++------- 2 files changed, 43 insertions(+), 12 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 3518a56f..4c501d3d 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -14,6 +14,7 @@ static struct wl_compositor *compositor = NULL; static struct zwlr_layer_shell_v1 *layer_shell = NULL; +struct zwlr_layer_surface_v1 *layer_surface; static struct wl_output *wl_output = NULL; struct wl_surface *wl_surface; @@ -26,8 +27,11 @@ static uint32_t output = 0; static uint32_t layer = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; static uint32_t anchor = 0; static uint32_t width = 256, height = 256; +static int32_t margin_top = 0; static double alpha = 1.0; static bool run_display = true; +static bool animate = false; +static double frame = 0; static struct { struct timespec last_frame; @@ -67,6 +71,18 @@ static void draw(void) { demo.dec = inc; } + if (animate) { + frame += ms / 50.0; + 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); + } + } + glViewport(0, 0, width, height); glClearColor(demo.color[0], demo.color[1], demo.color[2], alpha); glClear(GL_COLOR_BUFFER_BIT); @@ -136,11 +152,10 @@ int main(int argc, char **argv) { wlr_log_init(L_DEBUG, NULL); char *namespace = "wlroots"; int exclusive_zone = 0; - int32_t margin_top = 0, margin_right = 0, - margin_bottom = 0, margin_left = 0; + int32_t margin_right = 0, margin_bottom = 0, margin_left = 0; bool found; int c; - while ((c = getopt(argc, argv, "w:h:o:l:a:x:m:t:")) != -1) { + while ((c = getopt(argc, argv, "nw:h:o:l:a:x:m:t:")) != -1) { switch (c) { case 'o': output = atoi(optarg); @@ -217,6 +232,9 @@ int main(int argc, char **argv) { assert(!*endptr); break; } + case 'n': + animate = true; + break; default: break; } @@ -253,8 +271,7 @@ int main(int argc, char **argv) { wl_surface = wl_compositor_create_surface(compositor); assert(wl_surface); - struct zwlr_layer_surface_v1 *layer_surface = - zwlr_layer_shell_v1_get_layer_surface(layer_shell, + layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, wl_surface, wl_output, layer, namespace); assert(layer_surface); zwlr_layer_surface_v1_set_size(layer_surface, width, height); diff --git a/rootston/layer_shell.c b/rootston/layer_shell.c index e2d5b9f0..35896228 100644 --- a/rootston/layer_shell.c +++ b/rootston/layer_shell.c @@ -12,7 +12,9 @@ #include "rootston/server.h" static void apply_exclusive(struct wlr_box *usable_area, - uint32_t anchor, int32_t exclusive) { + uint32_t anchor, int32_t exclusive, + int32_t margin_top, int32_t margin_right, + int32_t margin_bottom, int32_t margin_left) { if (exclusive <= 0) { return; } @@ -20,6 +22,7 @@ static void apply_exclusive(struct wlr_box *usable_area, uint32_t anchors; int *positive_axis; int *negative_axis; + int margin; } edges[] = { { .anchors = @@ -28,6 +31,7 @@ static void apply_exclusive(struct wlr_box *usable_area, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, .positive_axis = &usable_area->y, .negative_axis = &usable_area->height, + .margin = margin_top, }, { .anchors = @@ -36,6 +40,7 @@ static void apply_exclusive(struct wlr_box *usable_area, ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, .positive_axis = NULL, .negative_axis = &usable_area->height, + .margin = margin_bottom, }, { .anchors = @@ -44,6 +49,7 @@ static void apply_exclusive(struct wlr_box *usable_area, ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, .positive_axis = &usable_area->x, .negative_axis = &usable_area->width, + .margin = margin_left, }, { .anchors = @@ -52,15 +58,16 @@ static void apply_exclusive(struct wlr_box *usable_area, ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, .positive_axis = NULL, .negative_axis = &usable_area->width, + .margin = margin_right, }, }; for (size_t i = 0; i < sizeof(edges) / sizeof(edges[0]); ++i) { if ((anchor & edges[i].anchors) == edges[i].anchors) { if (edges[i].positive_axis) { - *edges[i].positive_axis += exclusive; + *edges[i].positive_axis += exclusive + edges[i].margin; } if (edges[i].negative_axis) { - *edges[i].negative_axis -= exclusive; + *edges[i].negative_axis -= exclusive + edges[i].margin; } } } @@ -121,15 +128,15 @@ static void arrange_layer(struct wlr_output *output, struct wl_list *list, box.y = bounds.y + ((bounds.height / 2) - (box.height / 2)); } // Margin - if ((state->anchor & both_horiz)) { + if ((state->anchor & both_horiz) == both_horiz) { box.x += state->margin.left; box.width -= state->margin.left + state->margin.right; } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { - box.x += state->margin.bottom; + box.x += state->margin.left; } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { box.x -= state->margin.right; } - if ((state->anchor & both_vert)) { + if ((state->anchor & both_vert) == both_vert) { box.y += state->margin.top; box.height -= state->margin.top + state->margin.bottom; } else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { @@ -139,7 +146,11 @@ static void arrange_layer(struct wlr_output *output, struct wl_list *list, } // Apply roots_surface->geo = box; - apply_exclusive(usable_area, state->anchor, state->exclusive_zone); + 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); } } @@ -212,6 +223,9 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { struct roots_output *output = wlr_output->data; output_damage_from_local_surface(output, layer_surface->surface, layer->geo.x, layer->geo.y, 0); + arrange_layers(wlr_output); + output_damage_from_local_surface(output, layer_surface->surface, + layer->geo.x, layer->geo.y, 0); } } -- 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 'examples') 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 13edb19a6ca89da3fcbafd3be01d89251658178d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 27 Mar 2018 15:49:44 -0400 Subject: Fix issue starting up client EGL on X11 backend --- examples/layer-shell.c | 1 - include/wlr/render/egl.h | 1 + render/egl.c | 6 ++++-- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index e559121e..70407888 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -247,7 +247,6 @@ int main(int argc, char **argv) { struct wl_registry *registry = wl_display_get_registry(display); wl_registry_add_listener(registry, ®istry_listener, NULL); - wl_display_dispatch(display); wl_display_roundtrip(display); if (compositor == NULL) { diff --git a/include/wlr/render/egl.h b/include/wlr/render/egl.h index 9f4c0334..b5f2d67c 100644 --- a/include/wlr/render/egl.h +++ b/include/wlr/render/egl.h @@ -20,6 +20,7 @@ struct wlr_egl { bool swap_buffers_with_damage; bool dmabuf_import; bool dmabuf_import_modifiers; + bool bind_wayland_display; } egl_exts; struct wl_display *wl_display; diff --git a/render/egl.c b/render/egl.c index 315eb098..7201ac9f 100644 --- a/render/egl.c +++ b/render/egl.c @@ -160,8 +160,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, wlr_log(L_INFO, "Supported EGL extensions: %s", egl->exts_str); wlr_log(L_INFO, "EGL vendor: %s", eglQueryString(egl->display, EGL_VENDOR)); - if (!check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display") || - !check_egl_ext(egl->exts_str, "EGL_KHR_image_base")) { + if (!check_egl_ext(egl->exts_str, "EGL_KHR_image_base")) { wlr_log(L_ERROR, "Required egl extensions not supported"); goto error; } @@ -177,6 +176,9 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, egl->egl_exts.dmabuf_import_modifiers = check_egl_ext(egl->exts_str, "EGL_EXT_image_dma_buf_import_modifiers") && eglQueryDmaBufFormatsEXT && eglQueryDmaBufModifiersEXT; + + egl->egl_exts.bind_wayland_display = + check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display"); print_dmabuf_formats(egl); return true; -- cgit v1.2.3 From a35a5786b0e40cb1ffa87344d3cb21dff9fd99f4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 10:46:50 -0400 Subject: Remove width_mm from wlr_pointer events --- backend/libinput/pointer.c | 5 ++--- backend/wayland/wl_seat.c | 6 ++---- backend/x11/backend.c | 12 ++++-------- examples/multi-pointer.c | 3 +-- examples/pointer.c | 6 +++--- examples/support/shared.c | 4 ++-- include/wlr/types/wlr_cursor.h | 2 +- include/wlr/types/wlr_pointer.h | 4 ++-- rootston/cursor.c | 4 ++-- types/wlr_cursor.c | 6 +++--- 10 files changed, 22 insertions(+), 30 deletions(-) (limited to 'examples') diff --git a/backend/libinput/pointer.c b/backend/libinput/pointer.c index 8a31d312..9ccda634 100644 --- a/backend/libinput/pointer.c +++ b/backend/libinput/pointer.c @@ -53,9 +53,8 @@ void handle_pointer_motion_abs(struct libinput_event *event, wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_pointer_get_time_usec(pevent)); - wlr_event.x_mm = libinput_event_pointer_get_absolute_x(pevent); - wlr_event.y_mm = libinput_event_pointer_get_absolute_y(pevent); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); + wlr_event.x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1); + wlr_event.y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1); wlr_signal_emit_safe(&wlr_dev->pointer->events.motion_absolute, &wlr_event); } diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 6ca59130..2d4f76de 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -80,10 +80,8 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, struct wlr_event_pointer_motion_absolute wlr_event; wlr_event.device = dev; wlr_event.time_msec = time; - wlr_event.width_mm = layout_box.width; - wlr_event.height_mm = layout_box.height; - wlr_event.x_mm = transformed.x + wlr_output->lx - layout_box.x; - wlr_event.y_mm = transformed.y + wlr_output->ly - layout_box.y; + wlr_event.x = transformed.x / layout_box.width; + wlr_event.y = transformed.y / layout_box.height; wlr_signal_emit_safe(&dev->pointer->events.motion_absolute, &wlr_event); } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 36d72d9e..f534676d 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -108,10 +108,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e struct wlr_event_pointer_motion_absolute abs = { .device = &x11->pointer_dev, .time_msec = ev->time, - .x_mm = ev->event_x, - .y_mm = ev->event_y, - .width_mm = output->wlr_output.width, - .height_mm = output->wlr_output.height, + .x = (double)ev->event_x / output->wlr_output.width, + .y = (double)ev->event_y / output->wlr_output.height, }; wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); @@ -136,10 +134,8 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e struct wlr_event_pointer_motion_absolute abs = { .device = &x11->pointer_dev, .time_msec = x11->time, - .x_mm = pointer->root_x, - .y_mm = pointer->root_y, - .width_mm = output->wlr_output.width, - .height_mm = output->wlr_output.height, + .x = (double)pointer->root_x / output->wlr_output.width, + .y = (double)pointer->root_y / output->wlr_output.height, }; wlr_signal_emit_safe(&x11->pointer.events.motion_absolute, &abs); diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index 1f869f50..46f0e78f 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -118,8 +118,7 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, struct sample_cursor *cursor = wl_container_of(listener, cursor, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data; - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); } static void handle_input_add(struct compositor_state *state, diff --git a/examples/pointer.c b/examples/pointer.c index 9794e6e5..12312092 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -154,8 +154,8 @@ static void handle_cursor_motion_absolute(struct wl_listener *listener, wl_container_of(listener, sample, cursor_motion_absolute); struct wlr_event_pointer_motion_absolute *event = data; - sample->cur_x = event->x_mm; - sample->cur_y = event->y_mm; + sample->cur_x = event->x; + sample->cur_y = event->y; wlr_cursor_warp_absolute(sample->cursor, event->device, sample->cur_x, sample->cur_y); @@ -252,7 +252,7 @@ static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) { if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { wlr_cursor_warp_absolute(sample->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + event->x_mm / event->width_mm, event->y_mm / event->height_mm); } } diff --git a/examples/support/shared.c b/examples/support/shared.c index e6233206..c6460374 100644 --- a/examples/support/shared.c +++ b/examples/support/shared.c @@ -108,8 +108,8 @@ static void pointer_motion_absolute_notify(struct wl_listener *listener, void *d struct wlr_event_pointer_motion_absolute *event = data; struct pointer_state *pstate = wl_container_of(listener, pstate, motion_absolute); if (pstate->compositor->pointer_motion_absolute_cb) { - pstate->compositor->pointer_motion_absolute_cb(pstate, - event->x_mm, event->y_mm); + pstate->compositor->pointer_motion_absolute_cb( + pstate, event->x, event->y); } } diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 70dca9f7..ffe149c9 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -73,7 +73,7 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, double x, double y); void wlr_cursor_warp_absolute(struct wlr_cursor *cur, - struct wlr_input_device *dev, double x_mm, double y_mm); + struct wlr_input_device *dev, double x, double y); /** * Move the cursor in the direction of the given x and y coordinates. diff --git a/include/wlr/types/wlr_pointer.h b/include/wlr/types/wlr_pointer.h index e7ac9b46..a8969b9e 100644 --- a/include/wlr/types/wlr_pointer.h +++ b/include/wlr/types/wlr_pointer.h @@ -29,8 +29,8 @@ struct wlr_event_pointer_motion { struct wlr_event_pointer_motion_absolute { struct wlr_input_device *device; uint32_t time_msec; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; }; struct wlr_event_pointer_button { diff --git a/rootston/cursor.c b/rootston/cursor.c index 52439dff..c1fd7d31 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -288,8 +288,8 @@ void roots_cursor_handle_motion(struct roots_cursor *cursor, void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, struct wlr_event_pointer_motion_absolute *event) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(cursor->cursor, + event->device, event->x, event->y); roots_cursor_update_position(cursor, event->time_msec); } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 20acebf1..ed1a67da 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -254,7 +254,7 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev, } void wlr_cursor_warp_absolute(struct wlr_cursor *cur, - struct wlr_input_device *dev, double x_mm, double y_mm) { + struct wlr_input_device *dev, double x, double y) { assert(cur->state->layout); struct wlr_box *mapping = get_mapping(cur, dev); @@ -262,8 +262,8 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } - double x = x_mm > 0 ? mapping->width * x_mm + mapping->x : cur->x; - double y = y_mm > 0 ? mapping->height * y_mm + mapping->y : cur->y; + x = x > 0 ? mapping->width * x + mapping->x : cur->x; + y = y > 0 ? mapping->height * y + mapping->y : cur->y; wlr_cursor_warp_unchecked(cur, x, y); } -- cgit v1.2.3 From 324b9d910dc237151fd71c01bef015d0080be191 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 11:04:40 -0400 Subject: Remove width_mm from wlr_touch events --- backend/drm/legacy.c | 2 +- backend/libinput/touch.c | 10 ++++------ examples/pointer.c | 8 ++++---- examples/support/shared.c | 8 ++++---- examples/support/shared.h | 8 ++++---- examples/touch.c | 16 ++++++++-------- include/wlr/types/wlr_cursor.h | 2 +- include/wlr/types/wlr_touch.h | 8 ++++---- rootston/cursor.c | 9 +++------ types/wlr_cursor.c | 12 ++++-------- 10 files changed, 37 insertions(+), 46 deletions(-) (limited to 'examples') diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index 88a01b89..7c45ae21 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -47,7 +47,7 @@ bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, if (drmModeSetCursor(drm->fd, crtc->id, gbm_bo_get_handle(bo).u32, plane->surf.width, plane->surf.height)) { - wlr_log_errno(L_ERROR, "Failed to set hardware cursor"); + wlr_log_errno(L_DEBUG, "Failed to set hardware cursor"); return false; } diff --git a/backend/libinput/touch.c b/backend/libinput/touch.c index 2b87f9cd..419c11ea 100644 --- a/backend/libinput/touch.c +++ b/backend/libinput/touch.c @@ -35,9 +35,8 @@ void handle_touch_down(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_touch_get_time_usec(tevent)); wlr_event.touch_id = libinput_event_touch_get_slot(tevent); - wlr_event.x_mm = libinput_event_touch_get_x(tevent); - wlr_event.y_mm = libinput_event_touch_get_y(tevent); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); + wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1); + wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1); wlr_signal_emit_safe(&wlr_dev->touch->events.down, &wlr_event); } @@ -74,9 +73,8 @@ void handle_touch_motion(struct libinput_event *event, wlr_event.time_msec = usec_to_msec(libinput_event_touch_get_time_usec(tevent)); wlr_event.touch_id = libinput_event_touch_get_slot(tevent); - wlr_event.x_mm = libinput_event_touch_get_x(tevent); - wlr_event.y_mm = libinput_event_touch_get_y(tevent); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); + wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1); + wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1); wlr_signal_emit_safe(&wlr_dev->touch->events.motion, &wlr_event); } diff --git a/examples/pointer.c b/examples/pointer.c index 12312092..2c598b9a 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -217,8 +217,8 @@ static void handle_touch_down(struct wl_listener *listener, void *data) { struct wlr_event_touch_down *event = data; struct touch_point *point = calloc(1, sizeof(struct touch_point)); point->touch_id = event->touch_id; - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; + point->x = event->x; + point->y = event->y; wl_list_insert(&sample->touch_points, &point->link); warp_to_touch(sample, event->device); @@ -232,8 +232,8 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { struct touch_point *point; wl_list_for_each(point, &sample->touch_points, link) { if (point->touch_id == event->touch_id) { - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; + point->x = event->x; + point->y = event->y; break; } } diff --git a/examples/support/shared.c b/examples/support/shared.c index c6460374..02b324f5 100644 --- a/examples/support/shared.c +++ b/examples/support/shared.c @@ -167,8 +167,8 @@ static void touch_down_notify(struct wl_listener *listener, void *data) { struct wlr_event_touch_down *event = data; struct touch_state *tstate = wl_container_of(listener, tstate, down); if (tstate->compositor->touch_down_cb) { - tstate->compositor->touch_down_cb(tstate, event->touch_id, - event->x_mm, event->y_mm, event->width_mm, event->height_mm); + tstate->compositor->touch_down_cb(tstate, + event->touch_id, event->x, event->y); } } @@ -176,8 +176,8 @@ static void touch_motion_notify(struct wl_listener *listener, void *data) { struct wlr_event_touch_motion *event = data; struct touch_state *tstate = wl_container_of(listener, tstate, motion); if (tstate->compositor->touch_motion_cb) { - tstate->compositor->touch_motion_cb(tstate, event->touch_id, - event->x_mm, event->y_mm, event->width_mm, event->height_mm); + tstate->compositor->touch_motion_cb(tstate, + event->touch_id, event->x, event->y); } } diff --git a/examples/support/shared.h b/examples/support/shared.h index d00e75b3..2079a9ef 100644 --- a/examples/support/shared.h +++ b/examples/support/shared.h @@ -102,10 +102,10 @@ struct compositor_state { enum wlr_axis_source source, enum wlr_axis_orientation orientation, double delta); - void (*touch_down_cb)(struct touch_state *s, int32_t touch_id, - double x, double y, double width, double height); - void (*touch_motion_cb)(struct touch_state *s, int32_t touch_id, - double x, double y, double width, double height); + void (*touch_down_cb)(struct touch_state *s, + int32_t touch_id, double x, double y); + void (*touch_motion_cb)(struct touch_state *s, + int32_t touch_id, double x, double y); void (*touch_up_cb)(struct touch_state *s, int32_t touch_id); void (*touch_cancel_cb)(struct touch_state *s, int32_t touch_id); void (*tool_axis_cb)(struct tablet_tool_state *s, diff --git a/examples/touch.c b/examples/touch.c index 7639165c..e9dcf29c 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -60,13 +60,13 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts wlr_output_swap_buffers(wlr_output, NULL, NULL); } -static void handle_touch_down(struct touch_state *tstate, int32_t touch_id, - double x, double y, double width, double height) { +static void handle_touch_down(struct touch_state *tstate, + int32_t touch_id, double x, double y) { struct sample_state *sample = tstate->compositor->data; struct touch_point *point = calloc(1, sizeof(struct touch_point)); point->touch_id = touch_id; - point->x = x / width; - point->y = y / height; + point->x = x; + point->y = y; wl_list_insert(&sample->touch_points, &point->link); } @@ -81,14 +81,14 @@ static void handle_touch_up(struct touch_state *tstate, int32_t touch_id) { } } -static void handle_touch_motion(struct touch_state *tstate, int32_t touch_id, - double x, double y, double width, double height) { +static void handle_touch_motion(struct touch_state *tstate, + int32_t touch_id, double x, double y) { struct sample_state *sample = tstate->compositor->data; struct touch_point *point; wl_list_for_each(point, &sample->touch_points, link) { if (point->touch_id == touch_id) { - point->x = x / width; - point->y = y / height; + point->x = x; + point->y = y; break; } } diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index ffe149c9..fc541271 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -156,6 +156,6 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, */ bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, struct wlr_input_device *device, double x_mm, double y_mm, - double width_mm, double height_mm, double *lx, double *ly); + double *lx, double *ly); #endif diff --git a/include/wlr/types/wlr_touch.h b/include/wlr/types/wlr_touch.h index 8ea293eb..70070f84 100644 --- a/include/wlr/types/wlr_touch.h +++ b/include/wlr/types/wlr_touch.h @@ -23,8 +23,8 @@ struct wlr_event_touch_down { struct wlr_input_device *device; uint32_t time_msec; int32_t touch_id; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; }; struct wlr_event_touch_up { @@ -37,8 +37,8 @@ struct wlr_event_touch_motion { struct wlr_input_device *device; uint32_t time_msec; int32_t touch_id; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; }; struct wlr_event_touch_cancel { diff --git a/rootston/cursor.c b/rootston/cursor.c index c1fd7d31..786dff0e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -310,10 +310,8 @@ void roots_cursor_handle_touch_down(struct roots_cursor *cursor, struct roots_desktop *desktop = cursor->seat->input->server->desktop; struct wlr_surface *surface = NULL; double lx, ly; - bool result = - wlr_cursor_absolute_to_layout_coords(cursor->cursor, - event->device, event->x_mm, event->y_mm, event->width_mm, - event->height_mm, &lx, &ly); + bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, + event->device, event->x, event->y, &lx, &ly); if (!result) { return; } @@ -365,8 +363,7 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, double lx, ly; bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor, - event->device, event->x_mm, event->y_mm, event->width_mm, - event->height_mm, &lx, &ly); + event->device, event->x, event->y, &lx, &ly); if (!result) { return; } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index ed1a67da..5142513b 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -640,19 +640,15 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur, } bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur, - struct wlr_input_device *device, double x_mm, double y_mm, - double width_mm, double height_mm, double *lx, double *ly) { - if (width_mm <= 0 || height_mm <= 0) { - return false; - } - + struct wlr_input_device *device, double x, double y, + double *lx, double *ly) { struct wlr_box *mapping = get_mapping(cur, device); if (!mapping) { mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } - *lx = x_mm > 0 ? mapping->width * (x_mm / width_mm) + mapping->x : cur->x; - *ly = y_mm > 0 ? mapping->height * (y_mm / height_mm) + mapping->y : cur->y; + *lx = x > 0 ? mapping->width * x + mapping->x : cur->x; + *ly = y > 0 ? mapping->height * y + mapping->y : cur->y; return true; } -- cgit v1.2.3 From ac219cbda6dc3122fcc7f1bfa89b7e8fbb03b8ce Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 11:40:35 -0400 Subject: Remove width_mm from tablet events --- backend/libinput/events.c | 2 ++ backend/libinput/tablet_tool.c | 5 ++--- examples/pointer.c | 4 ++-- examples/tablet.c | 27 +++++++++++++++++++-------- include/wlr/types/wlr_input_device.h | 2 ++ include/wlr/types/wlr_tablet_tool.h | 12 ++++++------ rootston/cursor.c | 8 +++----- 7 files changed, 36 insertions(+), 24 deletions(-) (limited to 'examples') diff --git a/backend/libinput/events.c b/backend/libinput/events.c index d92de830..da7b2be4 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -46,6 +46,8 @@ static struct wlr_input_device *allocate_device( return NULL; } struct wlr_input_device *wlr_dev = &wlr_libinput_dev->wlr_input_device; + libinput_device_get_size(libinput_dev, + &wlr_dev->width_mm, &wlr_dev->height_mm); wl_list_insert(wlr_devices, &wlr_dev->link); wlr_libinput_dev->handle = libinput_dev; libinput_device_ref(libinput_dev); diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 27cf7c81..815c4daf 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -34,14 +34,13 @@ void handle_tablet_tool_axis(struct libinput_event *event, wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent)); - libinput_device_get_size(libinput_dev, &wlr_event.width_mm, &wlr_event.height_mm); if (libinput_event_tablet_tool_x_has_changed(tevent)) { wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_X; - wlr_event.x_mm = libinput_event_tablet_tool_get_x(tevent); + wlr_event.x = libinput_event_tablet_tool_get_x_transformed(tevent, 1); } if (libinput_event_tablet_tool_y_has_changed(tevent)) { wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_Y; - wlr_event.y_mm = libinput_event_tablet_tool_get_y(tevent); + wlr_event.y = libinput_event_tablet_tool_get_y_transformed(tevent, 1); } if (libinput_event_tablet_tool_pressure_has_changed(tevent)) { wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_PRESSURE; diff --git a/examples/pointer.c b/examples/pointer.c index 2c598b9a..aaaad841 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -251,8 +251,8 @@ static void handle_tablet_tool_axis(struct wl_listener *listener, void *data) { struct wlr_event_tablet_tool_axis *event = data; if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(sample->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(sample->cursor, + event->device, event->x, event->y); } } diff --git a/examples/tablet.c b/examples/tablet.c index 9379fac3..be428f86 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -28,7 +28,7 @@ struct sample_state { bool proximity, tap, button; double distance; double pressure; - double x_mm, y_mm; + double x, y; double x_tilt, y_tilt; double width_mm, height_mm; double ring; @@ -69,8 +69,8 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts if (sample->proximity) { struct wlr_box box = { - .x = sample->x_mm * scale - 8 * (sample->pressure + 1) + left, - .y = sample->y_mm * scale - 8 * (sample->pressure + 1) + top, + .x = (sample->x * pad_width) - 8 * (sample->pressure + 1) + left, + .y = (sample->y * pad_height) - 8 * (sample->pressure + 1) + top, .width = 16 * (sample->pressure + 1), .height = 16 * (sample->pressure + 1), }; @@ -94,13 +94,11 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts static void handle_tool_axis(struct tablet_tool_state *tstate, struct wlr_event_tablet_tool_axis *event) { struct sample_state *sample = tstate->compositor->data; - sample->width_mm = event->width_mm; - sample->height_mm = event->height_mm; if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) { - sample->x_mm = event->x_mm; + sample->x = event->x; } if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - sample->y_mm = event->y_mm; + sample->y = event->y; } if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_DISTANCE)) { sample->distance = event->distance; @@ -164,13 +162,24 @@ static void handle_pad_ring(struct tablet_pad_state *pstate, } } +static void handle_input_add(struct compositor_state *cstate, + struct wlr_input_device *inputdev) { + struct sample_state *sample = cstate->data; + if (inputdev->type == WLR_INPUT_DEVICE_TABLET_TOOL) { + sample->width_mm = inputdev->width_mm == 0 ? + 20 : inputdev->width_mm; + sample->height_mm = inputdev->height_mm == 0 ? + 10 : inputdev->height_mm; + } +} + int main(int argc, char *argv[]) { wlr_log_init(L_DEBUG, NULL); struct sample_state state = { .tool_color = { 1, 1, 1, 1 }, .pad_color = { 0.5, 0.5, 0.5, 1.0 } }; - struct compositor_state compositor = { 0, + struct compositor_state compositor = { .data = &state, .output_frame_cb = handle_output_frame, .tool_axis_cb = handle_tool_axis, @@ -178,6 +187,8 @@ int main(int argc, char *argv[]) { .tool_button_cb = handle_tool_button, .pad_button_cb = handle_pad_button, .pad_ring_cb = handle_pad_ring, + .input_add_cb = handle_input_add, + 0 }; compositor_init(&compositor); diff --git a/include/wlr/types/wlr_input_device.h b/include/wlr/types/wlr_input_device.h index 6d8e3631..d65172c1 100644 --- a/include/wlr/types/wlr_input_device.h +++ b/include/wlr/types/wlr_input_device.h @@ -29,6 +29,8 @@ struct wlr_input_device { enum wlr_input_device_type type; int vendor, product; char *name; + // Or 0 if not applicable to this device + double width_mm, height_mm; /* wlr_input_device.type determines which of these is valid */ union { diff --git a/include/wlr/types/wlr_tablet_tool.h b/include/wlr/types/wlr_tablet_tool.h index 59e49ef8..22bf2649 100644 --- a/include/wlr/types/wlr_tablet_tool.h +++ b/include/wlr/types/wlr_tablet_tool.h @@ -36,8 +36,8 @@ struct wlr_event_tablet_tool_axis { struct wlr_input_device *device; uint32_t time_msec; uint32_t updated_axes; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; double pressure; double distance; double tilt_x, tilt_y; @@ -54,8 +54,8 @@ enum wlr_tablet_tool_proximity_state { struct wlr_event_tablet_tool_proximity { struct wlr_input_device *device; uint32_t time_msec; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; enum wlr_tablet_tool_proximity_state state; }; @@ -67,8 +67,8 @@ enum wlr_tablet_tool_tip_state { struct wlr_event_tablet_tool_tip { struct wlr_input_device *device; uint32_t time_msec; - double x_mm, y_mm; - double width_mm, height_mm; + // From 0..1 + double x, y; enum wlr_tablet_tool_tip_state state; }; diff --git a/rootston/cursor.c b/rootston/cursor.c index 786dff0e..a5953e4a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -392,15 +392,13 @@ void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); + event->x, event->y); roots_cursor_update_position(cursor, event->time_msec); } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - event->x_mm / event->width_mm, -1); + wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, -1); roots_cursor_update_position(cursor, event->time_msec); } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(cursor->cursor, event->device, - -1, event->y_mm / event->height_mm); + wlr_cursor_warp_absolute(cursor->cursor, event->device, -1, event->y); roots_cursor_update_position(cursor, event->time_msec); } } -- cgit v1.2.3 From e3eb487dc2c3ed51b974212ddb15ce839289eba2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 17:26:58 -0400 Subject: Add pointer support to layer shell example --- examples/layer-shell.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++--- examples/meson.build | 3 +- rootston/desktop.c | 11 ++-- 3 files changed, 148 insertions(+), 15 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 70407888..6e293f55 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -7,12 +7,17 @@ #include #include #include +#include #include #include #include #include "wlr-layer-shell-unstable-v1-client-protocol.h" static struct wl_compositor *compositor = NULL; +static struct wl_seat *seat = NULL; +static struct wl_shm *shm = NULL; +static struct wl_pointer *pointer = NULL; +//static struct wl_keyboard *keyboard = NULL; static struct zwlr_layer_shell_v1 *layer_shell = NULL; struct zwlr_layer_surface_v1 *layer_surface; static struct wl_output *wl_output = NULL; @@ -32,6 +37,12 @@ static double alpha = 1.0; static bool run_display = true; static bool animate = false; static double frame = 0; +static int cur_x = -1, cur_y = -1; +static int buttons = 0; + +struct wl_cursor_theme *cursor_theme; +struct wl_cursor_image *cursor_image; +struct wl_surface *cursor_surface; static struct { struct timespec last_frame; @@ -62,13 +73,15 @@ static void draw(void) { (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 (!buttons) { + 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; + if (demo.color[demo.dec] < 0.0f) { + demo.color[inc] = 1.0f; + demo.color[demo.dec] = 0.0f; + demo.dec = inc; + } } if (animate) { @@ -83,9 +96,21 @@ static void draw(void) { } glViewport(0, 0, width, height); - glClearColor(demo.color[0], demo.color[1], demo.color[2], alpha); + if (buttons) { + glClearColor(1, 1, 1, alpha); + } else { + glClearColor(demo.color[0], demo.color[1], demo.color[2], alpha); + } glClear(GL_COLOR_BUFFER_BIT); + if (cur_x != -1 && cur_y != -1) { + glEnable(GL_SCISSOR_TEST); + glScissor(cur_x, height - cur_y, 5, 5); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); + } + frame_callback = wl_surface_frame(wl_surface); wl_callback_add_listener(frame_callback, &frame_listener, NULL); @@ -119,11 +144,101 @@ struct zwlr_layer_surface_v1_listener layer_surface_listener = { .closed = layer_surface_closed, }; +static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t surface_x, wl_fixed_t surface_y) { + wl_surface_attach(cursor_surface, + wl_cursor_image_get_buffer(cursor_image), 0, 0); + wl_pointer_set_cursor(wl_pointer, serial, cursor_surface, + cursor_image->hotspot_x, cursor_image->hotspot_y); + wl_surface_commit(cursor_surface); +} + +static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, struct wl_surface *surface) { + cur_x = cur_y = -1; +} + +static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { + cur_x = (int)wl_fixed_to_double(surface_x); + cur_y = (int)wl_fixed_to_double(surface_y); +} + +static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { + if (state == WL_POINTER_BUTTON_STATE_PRESSED) { + buttons++; + } else { + buttons--; + } +} + +static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) { + // Who cares +} + +static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { + // Who cares +} + +static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, + uint32_t axis_source) { + // Who cares +} + +static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis) { + // Who cares +} + +static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, + uint32_t axis, int32_t discrete) { + // Who cares +} + +struct wl_pointer_listener pointer_listener = { + .enter = wl_pointer_enter, + .leave = wl_pointer_leave, + .motion = wl_pointer_motion, + .button = wl_pointer_button, + .axis = wl_pointer_axis, + .frame = wl_pointer_frame, + .axis_source = wl_pointer_axis_source, + .axis_stop = wl_pointer_axis_stop, + .axis_discrete = wl_pointer_axis_discrete, +}; + +static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, + enum wl_seat_capability caps) { + if ((caps & WL_SEAT_CAPABILITY_POINTER)) { + pointer = wl_seat_get_pointer(wl_seat); + wl_pointer_add_listener(pointer, &pointer_listener, NULL); + } + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { + // TODO + } +} + +static void seat_handle_name(void *data, struct wl_seat *wl_seat, + const char *name) { + // Who cares +} + +const struct wl_seat_listener seat_listener = { + .capabilities = seat_handle_capabilities, + .name = seat_handle_name, +}; + static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { if (strcmp(interface, "wl_compositor") == 0) { compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); + } else if (strcmp(interface, wl_shm_interface.name) == 0) { + shm = wl_registry_bind(registry, name, + &wl_shm_interface, 1); } else if (strcmp(interface, "wl_output") == 0) { if (output == 0 && !wl_output) { wl_output = wl_registry_bind(registry, name, @@ -131,6 +246,10 @@ static void handle_global(void *data, struct wl_registry *registry, } else { output--; } + } else if (strcmp(interface, wl_seat_interface.name) == 0) { + seat = wl_registry_bind(registry, name, + &wl_seat_interface, 1); + wl_seat_add_listener(seat, &seat_listener, NULL); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { layer_shell = wl_registry_bind( registry, name, &zwlr_layer_shell_v1_interface, 1); @@ -250,11 +369,15 @@ int main(int argc, char **argv) { wl_display_roundtrip(display); if (compositor == NULL) { - fprintf(stderr, "wl-compositor not available\n"); + fprintf(stderr, "wl_compositor not available\n"); + return 1; + } + if (shm == NULL) { + fprintf(stderr, "wl_shm not available\n"); return 1; } if (layer_shell == NULL) { - fprintf(stderr, "layer-shell not available\n"); + fprintf(stderr, "layer_shell not available\n"); return 1; } if (wl_output == NULL) { @@ -262,6 +385,12 @@ int main(int argc, char **argv) { return 1; } + assert(cursor_theme = wl_cursor_theme_load(NULL, 16, shm)); + struct wl_cursor *cursor; + assert(cursor = wl_cursor_theme_get_cursor(cursor_theme, "left_ptr")); + cursor_image = cursor->images[0]; + assert(cursor_surface = wl_compositor_create_surface(compositor)); + EGLint attribs[] = { EGL_ALPHA_SIZE, 8, EGL_NONE }; wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs, WL_SHM_FORMAT_ARGB8888); @@ -294,5 +423,7 @@ int main(int argc, char **argv) { while (wl_display_dispatch(display) != -1 && run_display) { // This space intentionally left blank } + + wl_cursor_theme_destroy(cursor_theme); return 0; } diff --git a/examples/meson.build b/examples/meson.build index 558af4ac..9e60c37a 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -6,6 +6,7 @@ lib_shared = static_library( ) threads = dependency('threads') +wayland_cursor = dependency('wayland-cursor') executable('simple', 'simple.c', dependencies: wlroots, link_with: lib_shared) executable('pointer', 'pointer.c', dependencies: wlroots, link_with: lib_shared) @@ -52,5 +53,5 @@ executable( executable( 'layer-shell', 'layer-shell.c', - dependencies: [wayland_client, wlr_protos, wlroots] + dependencies: [wayland_cursor, wayland_client, wlr_protos, wlroots] ) diff --git a/rootston/desktop.c b/rootston/desktop.c index aa06000c..45bf8105 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -669,12 +669,13 @@ static struct wlr_surface *layer_surface_at(struct roots_output *output, double _sx = ox - roots_surface->geo.x; double _sy = oy - roots_surface->geo.y; struct wlr_box box = { - .x = 0, .y = 0, - .width = roots_surface->geo.width, - .height = roots_surface->geo.height, + .x = roots_surface->geo.x, + .y = roots_surface->geo.y, + .width = wlr_surface->current->width, + .height = wlr_surface->current->height, }; // TODO: Test popups/subsurfaces - if (wlr_box_contains_point(&box, _sx, _sy) && + if (wlr_box_contains_point(&box, ox, oy) && pixman_region32_contains_point(&wlr_surface->current->input, _sx, _sy, NULL)) { *sx = _sx; @@ -692,7 +693,7 @@ struct wlr_surface *desktop_surface_at(struct roots_desktop *desktop, struct wlr_output *wlr_output = wlr_output_layout_output_at(desktop->layout, lx, ly); struct roots_output *roots_output; - double ox, oy; + double ox = lx, oy = ly; if (wlr_output) { roots_output = wlr_output->data; wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); -- cgit v1.2.3 From 168f65fb7a336c7f7067bfd56413b2d19556c8bf Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 18:28:21 -0400 Subject: Minor bugfixes --- examples/layer-shell.c | 1 + rootston/desktop.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 6e293f55..3f955be4 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -157,6 +157,7 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) { cur_x = cur_y = -1; + buttons = 0; } static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, diff --git a/rootston/desktop.c b/rootston/desktop.c index 45bf8105..7ee2c69a 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -694,6 +694,8 @@ struct wlr_surface *desktop_surface_at(struct roots_desktop *desktop, wlr_output_layout_output_at(desktop->layout, lx, ly); struct roots_output *roots_output; double ox = lx, oy = ly; + *view = NULL; + if (wlr_output) { roots_output = wlr_output->data; wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); @@ -710,7 +712,6 @@ struct wlr_surface *desktop_surface_at(struct roots_desktop *desktop, } } - *view = NULL; struct roots_view *_view; if ((_view = desktop_view_at(desktop, lx, ly, &surface, sx, sy))) { if (view) { -- cgit v1.2.3 From 746e3759b7a350a5e9124f365cac0279810781d1 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 19:33:57 -0400 Subject: Address review feedback --- examples/layer-shell.c | 4 ++-- rootston/cursor.c | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 3f955be4..89fa9ea9 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -162,8 +162,8 @@ static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - cur_x = (int)wl_fixed_to_double(surface_x); - cur_y = (int)wl_fixed_to_double(surface_y); + cur_x = wl_fixed_to_int(surface_x); + cur_y = wl_fixed_to_int(surface_y); } static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, diff --git a/rootston/cursor.c b/rootston/cursor.c index 1a7526d1..1ee195c2 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -101,18 +101,21 @@ static void seat_view_deco_button(struct roots_seat_view *view, double sx, static void roots_passthrough_cursor(struct roots_cursor *cursor, uint32_t time) { - struct roots_view *view; double sx, sy; - + struct roots_view *view = NULL; struct roots_seat *seat = cursor->seat; struct roots_desktop *desktop = seat->input->server->desktop; struct wlr_surface *surface = desktop_surface_at(desktop, cursor->cursor->x, cursor->cursor->y, &sx, &sy, &view); + struct wl_client *client = NULL; + if (surface) { + client = wl_resource_get_client(surface->resource); + } - if (!surface && cursor->cursor_client) { + if (cursor->cursor_client != client) { wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, cursor->default_xcursor, cursor->cursor); - cursor->cursor_client = NULL; + cursor->cursor_client = client; } if (view) { -- cgit v1.2.3 From 2053a4c144bdde2df5cb7b6b7036cde008372493 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 21:02:28 -0400 Subject: Add more exotic cursor for layer shell example So it's more obvious that it's being set --- examples/layer-shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 89fa9ea9..f084d10f 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -388,7 +388,7 @@ int main(int argc, char **argv) { assert(cursor_theme = wl_cursor_theme_load(NULL, 16, shm)); struct wl_cursor *cursor; - assert(cursor = wl_cursor_theme_get_cursor(cursor_theme, "left_ptr")); + assert(cursor = wl_cursor_theme_get_cursor(cursor_theme, "crosshair")); cursor_image = cursor->images[0]; assert(cursor_surface = wl_compositor_create_surface(compositor)); -- cgit v1.2.3 From 33a2eb4b7775d1a3ab2b767739c1f1f054683d22 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 31 Mar 2018 18:49:43 -0400 Subject: Untie wlr_backend from wlr_renderer --- backend/drm/renderer.c | 2 +- backend/headless/backend.c | 2 +- backend/wayland/backend.c | 2 +- backend/x11/backend.c | 2 +- examples/output-layout.c | 3 ++- examples/rotation.c | 3 ++- examples/tablet.c | 3 ++- examples/touch.c | 3 ++- include/wlr/render/gles2.h | 3 ++- render/gles2/renderer.c | 5 ++--- 10 files changed, 16 insertions(+), 12 deletions(-) (limited to 'examples') diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index c1531ce3..f06de1ee 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -31,7 +31,7 @@ bool wlr_drm_renderer_init(struct wlr_drm_backend *drm, goto error_gbm; } - renderer->wlr_rend = wlr_gles2_renderer_create(&drm->backend); + renderer->wlr_rend = wlr_gles2_renderer_create(&renderer->egl); if (!renderer->wlr_rend) { wlr_log(L_ERROR, "Failed to create WLR renderer"); goto error_egl; diff --git a/backend/headless/backend.c b/backend/headless/backend.c index 663bc13b..5bc48240 100644 --- a/backend/headless/backend.c +++ b/backend/headless/backend.c @@ -114,7 +114,7 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display) { return NULL; } - backend->renderer = wlr_gles2_renderer_create(&backend->backend); + backend->renderer = wlr_gles2_renderer_create(&backend->egl); if (backend->renderer == NULL) { wlr_log(L_ERROR, "Failed to create renderer"); } diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index abb25df5..0135f7c5 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -212,7 +212,7 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, const char backend->remote_display, NULL, WL_SHM_FORMAT_ARGB8888); wlr_egl_bind_display(&backend->egl, backend->local_display); - backend->renderer = wlr_gles2_renderer_create(&backend->backend); + backend->renderer = wlr_gles2_renderer_create(&backend->egl); if (backend->renderer == NULL) { wlr_log_errno(L_ERROR, "Could not create renderer"); } diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 90658f26..f598aea1 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -314,7 +314,7 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, goto error_event; } - x11->renderer = wlr_gles2_renderer_create(&x11->backend); + x11->renderer = wlr_gles2_renderer_create(&x11->egl); if (x11->renderer == NULL) { wlr_log(L_ERROR, "Failed to create renderer"); goto error_egl; diff --git a/examples/output-layout.c b/examples/output-layout.c index c1392a30..53aae7f0 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -196,7 +196,8 @@ int main(int argc, char *argv[]) { compositor.keyboard_key_cb = handle_keyboard_key; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); state.cat_texture = wlr_texture_from_pixels(state.renderer, WL_SHM_FORMAT_ABGR8888, cat_tex.width * 4, cat_tex.width, cat_tex.height, cat_tex.pixel_data); diff --git a/examples/rotation.c b/examples/rotation.c index dfafeeca..37873797 100644 --- a/examples/rotation.c +++ b/examples/rotation.c @@ -137,7 +137,8 @@ int main(int argc, char *argv[]) { compositor.keyboard_key_cb = handle_keyboard_key; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/examples/tablet.c b/examples/tablet.c index be428f86..d80b4b2f 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -192,7 +192,8 @@ int main(int argc, char *argv[]) { }; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/examples/touch.c b/examples/touch.c index e9dcf29c..16024fc8 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -108,7 +108,8 @@ int main(int argc, char *argv[]) { }; compositor_init(&compositor); - state.renderer = wlr_gles2_renderer_create(compositor.backend); + struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); + state.renderer = wlr_gles2_renderer_create(egl); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/include/wlr/render/gles2.h b/include/wlr/render/gles2.h index b3b43ab2..a59956bd 100644 --- a/include/wlr/render/gles2.h +++ b/include/wlr/render/gles2.h @@ -5,6 +5,7 @@ #include struct wlr_egl; -struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend); + +struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl); #endif diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index c8094847..77af0ab7 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -400,7 +399,7 @@ extern const GLchar tex_fragment_src_rgba[]; extern const GLchar tex_fragment_src_rgbx[]; extern const GLchar tex_fragment_src_external[]; -struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend) { +struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) { struct wlr_gles2_renderer *renderer = calloc(1, sizeof(struct wlr_gles2_renderer)); if (renderer == NULL) { @@ -408,7 +407,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend) { } wlr_renderer_init(&renderer->wlr_renderer, &renderer_impl); - renderer->egl = wlr_backend_get_egl(backend); + renderer->egl = egl; wlr_egl_make_current(renderer->egl, EGL_NO_SURFACE, NULL); renderer->exts_str = (const char*) glGetString(GL_EXTENSIONS); -- cgit v1.2.3 From f63a5d881d7662ced11057e7d2c38435f40310d6 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 1 Apr 2018 16:57:29 -0400 Subject: examples: get wlr_renderer from the backend --- examples/output-layout.c | 4 +--- examples/rotation.c | 4 +--- examples/tablet.c | 4 +--- examples/touch.c | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) (limited to 'examples') diff --git a/examples/output-layout.c b/examples/output-layout.c index 53aae7f0..b04e86b7 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -196,8 +195,7 @@ int main(int argc, char *argv[]) { compositor.keyboard_key_cb = handle_keyboard_key; compositor_init(&compositor); - struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); - state.renderer = wlr_gles2_renderer_create(egl); + state.renderer = wlr_backend_get_renderer(compositor.backend); state.cat_texture = wlr_texture_from_pixels(state.renderer, WL_SHM_FORMAT_ABGR8888, cat_tex.width * 4, cat_tex.width, cat_tex.height, cat_tex.pixel_data); diff --git a/examples/rotation.c b/examples/rotation.c index 37873797..c7bbc99a 100644 --- a/examples/rotation.c +++ b/examples/rotation.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -137,8 +136,7 @@ int main(int argc, char *argv[]) { compositor.keyboard_key_cb = handle_keyboard_key; compositor_init(&compositor); - struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); - state.renderer = wlr_gles2_renderer_create(egl); + state.renderer = wlr_backend_get_renderer(compositor.backend); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/examples/tablet.c b/examples/tablet.c index d80b4b2f..ca9d782c 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -192,8 +191,7 @@ int main(int argc, char *argv[]) { }; compositor_init(&compositor); - struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); - state.renderer = wlr_gles2_renderer_create(egl); + state.renderer = wlr_backend_get_renderer(compositor.backend); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); diff --git a/examples/touch.c b/examples/touch.c index 16024fc8..949d209d 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -108,8 +107,7 @@ int main(int argc, char *argv[]) { }; compositor_init(&compositor); - struct wlr_egl *egl = wlr_backend_get_egl(compositor.backend); - state.renderer = wlr_gles2_renderer_create(egl); + state.renderer = wlr_backend_get_renderer(compositor.backend); if (!state.renderer) { wlr_log(L_ERROR, "Could not start compositor, OOM"); exit(EXIT_FAILURE); -- cgit v1.2.3