From a7446792a1a0fd9fe3391f041d7bbfe9e2b11255 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 22 Oct 2017 23:19:21 -0400 Subject: Consider scale factor when rendering views --- include/rootston/config.h | 1 + include/rootston/view.h | 1 + include/wlr/types/wlr_surface.h | 6 +++++- rootston/config.c | 4 ++++ rootston/output.c | 3 +++ types/wlr_output.c | 4 ++-- types/wlr_surface.c | 19 ++++++++++++++++--- 7 files changed, 32 insertions(+), 6 deletions(-) diff --git a/include/rootston/config.h b/include/rootston/config.h index 75c04619..e0466117 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -8,6 +8,7 @@ struct output_config { char *name; enum wl_output_transform transform; int x, y; + int scale; struct wl_list link; struct { int width, height; diff --git a/include/rootston/view.h b/include/rootston/view.h index 993ff654..4a5e8d08 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -48,6 +48,7 @@ enum roots_view_type { struct roots_view { struct roots_desktop *desktop; + struct roots_output *output; double x, y; float rotation; // TODO: Something for roots-enforced width/height diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index ea4184aa..e1a07566 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -1,10 +1,10 @@ #ifndef WLR_TYPES_WLR_SURFACE_H #define WLR_TYPES_WLR_SURFACE_H - #include #include #include #include +#include struct wlr_frame_callback { struct wl_resource *resource; @@ -135,4 +135,8 @@ struct wlr_surface *wlr_surface_get_main_surface(struct wlr_surface *surface); */ struct wlr_subsurface *wlr_surface_subsurface_at(struct wlr_surface *surface, double sx, double sy, double *sub_x, double *sub_y); + +void wlr_surface_send_enter(struct wlr_surface *surface, + struct wlr_output *output); + #endif diff --git a/rootston/config.c b/rootston/config.c index 18138ab0..983117ba 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -220,6 +220,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, oc = calloc(1, sizeof(struct output_config)); oc->name = strdup(output_name); oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; + oc->scale = 1; wl_list_insert(&config->outputs, &oc->link); } @@ -227,6 +228,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, oc->x = strtol(value, NULL, 10); } else if (strcmp(name, "y") == 0) { oc->y = strtol(value, NULL, 10); + } else if (strcmp(name, "scale") == 0) { + oc->scale = strtol(value, NULL, 10); + assert(oc->scale >= 1); } else if (strcmp(name, "rotate") == 0) { if (strcmp(value, "90") == 0) { oc->transform = WL_OUTPUT_TRANSFORM_90; diff --git a/rootston/output.c b/rootston/output.c index baa7b6cc..faf39e74 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -27,6 +27,8 @@ static void render_surface(struct wlr_surface *surface, if (wlr_output_layout_intersects(desktop->layout, wlr_output, lx, ly, lx + width, ly + height)) { + // TODO: accomodate for mismatched scale, which can happen, for + // example, when a view is rendered over two outputs float matrix[16]; float translate_origin[16]; @@ -217,6 +219,7 @@ void output_add_notify(struct wl_listener *listener, void *data) { if (output_config->mode.width) { set_mode(wlr_output, output_config); } + wlr_output->scale = output_config->scale; wlr_output_transform(wlr_output, output_config->transform); wlr_output_layout_add(desktop->layout, wlr_output, output_config->x, output_config->y); diff --git a/types/wlr_output.c b/types/wlr_output.c index 44d24ae3..2f5e3086 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -29,8 +29,7 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { if (version >= WL_OUTPUT_MODE_SINCE_VERSION) { struct wlr_output_mode *mode; wl_list_for_each(mode, &output->modes, link) { - // TODO: mode->flags should just be preferred - uint32_t flags = mode->flags; + uint32_t flags = mode->flags & ~WL_OUTPUT_MODE_PREFERRED; if (output->current_mode == mode) { flags |= WL_OUTPUT_MODE_CURRENT; } @@ -45,6 +44,7 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { } } if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) { + wlr_log(L_DEBUG, "Sending scale"); wl_output_send_scale(resource, output->scale); } if (version >= WL_OUTPUT_DONE_SINCE_VERSION) { diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 2a8c4d04..28f3d05b 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -649,14 +649,14 @@ void wlr_surface_get_matrix(struct wlr_surface *surface, float (*matrix)[16], const float (*projection)[16], const float (*transform)[16]) { - int width = surface->texture->width / surface->current->scale; - int height = surface->texture->height / surface->current->scale; + int width = surface->texture->width; + int height = surface->texture->height; float scale[16]; wlr_matrix_identity(matrix); if (transform) { wlr_matrix_mul(matrix, transform, matrix); } - wlr_matrix_scale(&scale, width, height, 1); + wlr_matrix_scale(&scale, width, height, surface->current->scale); wlr_matrix_mul(matrix, &scale, matrix); wlr_matrix_mul(projection, matrix, matrix); } @@ -894,3 +894,16 @@ struct wlr_subsurface *wlr_surface_subsurface_at(struct wlr_surface *surface, return NULL; } + +void wlr_surface_send_enter(struct wlr_surface *surface, + struct wlr_output *output) { + struct wl_client *client = wl_resource_get_client(surface->resource); + struct wl_resource *resource; + wl_resource_for_each(resource, &output->wl_resources) { + if (client == wl_resource_get_client(resource)) { + wlr_log(L_DEBUG, "sending output enter"); + wl_surface_send_enter(surface->resource, resource); + break; + } + } +} -- cgit v1.2.3 From 9861add146af54836ca85dd5769ab3b966346432 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 24 Oct 2017 08:37:30 -0400 Subject: Send surface enter output events to clients --- rootston/desktop.c | 32 ++++- types/wlr_output.c | 416 ++++++++++++++++++++++++----------------------------- 2 files changed, 213 insertions(+), 235 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index f93d1df8..37022ca4 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -45,14 +45,35 @@ void view_get_size(struct roots_view *view, struct wlr_box *box) { box->height = view->wlr_surface->current->height; } +static void view_update_output(struct roots_view *view) { + struct roots_desktop *desktop = view->desktop; + struct roots_output *output = NULL, *_output; + struct wlr_box box; + view_get_size(view, &box); + wl_list_for_each(_output, &desktop->outputs, link) { + if (!wlr_output_layout_intersects(desktop->layout, _output->wlr_output, + view->x, view->y, view->x + box.width, view->x + box.height)) { + continue; + } + if (output == NULL + || output->wlr_output->scale < _output->wlr_output->scale) { + output = _output; + } + } + if (output && output != view->output) { + view->output = output; + wlr_surface_send_enter(view->wlr_surface, output->wlr_output); + } +} + void view_set_position(struct roots_view *view, double x, double y) { if (view->set_position) { view->set_position(view, x, y); - return; + } else { + view->x = x; + view->y = y; } - - view->x = x; - view->y = y; + view_update_output(view); } void view_activate(struct roots_view *view, bool activate) { @@ -65,6 +86,7 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { if (view->resize) { view->resize(view, width, height); } + view_update_output(view); } void view_close(struct roots_view *view) { @@ -111,6 +133,8 @@ void view_setup(struct roots_view *view) { struct roots_input *input = view->desktop->server->input; set_view_focus(input, view->desktop, view); + wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); + view_update_output(view); } void view_teardown(struct roots_view *view) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 2f5e3086..dd7e8d6a 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -136,9 +135,7 @@ static void wlr_output_update_matrix(struct wlr_output *output) { } void wlr_output_enable(struct wlr_output *output, bool enable) { - if (output->impl->enable) { - output->impl->enable(output, enable); - } + output->impl->enable(output, enable); } bool wlr_output_set_mode(struct wlr_output *output, @@ -191,199 +188,94 @@ void wlr_output_set_position(struct wlr_output *output, int32_t lx, } } -void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, - const struct wlr_output_impl *impl) { - assert(impl->make_current && impl->swap_buffers && impl->transform); - output->backend = backend; - output->impl = impl; - wl_list_init(&output->modes); - output->transform = WL_OUTPUT_TRANSFORM_NORMAL; - output->scale = 1; - wl_list_init(&output->cursors); - wl_signal_init(&output->events.frame); - wl_signal_init(&output->events.swap_buffers); - wl_signal_init(&output->events.resolution); - wl_signal_init(&output->events.destroy); -} - -void wlr_output_destroy(struct wlr_output *output) { - if (!output) { - return; - } - - wl_signal_emit(&output->events.destroy, output); - - struct wlr_output_mode *mode, *tmp_mode; - wl_list_for_each_safe(mode, tmp_mode, &output->modes, link) { - free(mode); - } - wl_list_remove(&output->modes); - if (output->impl && output->impl->destroy) { - output->impl->destroy(output); - } else { - free(output); +static bool set_cursor(struct wlr_output *output, const uint8_t *buf, + int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, + int32_t hotspot_y) { + if (output->impl->set_cursor + && output->impl->set_cursor(output, buf, stride, width, height, + hotspot_x, hotspot_y, true)) { + output->cursor.is_sw = false; + return true; } -} -void wlr_output_effective_resolution(struct wlr_output *output, - int *width, int *height) { - // TODO: Scale factor - if (output->transform % 2 == 1) { - *width = output->height; - *height = output->width; - } else { - *width = output->width; - *height = output->height; - } -} - -void wlr_output_make_current(struct wlr_output *output) { - output->impl->make_current(output); -} + wlr_log(L_INFO, "Falling back to software cursor"); -static void output_cursor_get_box(struct wlr_output_cursor *cursor, - struct wlr_box *box) { - box->x = cursor->x - cursor->hotspot_x; - box->y = cursor->y - cursor->hotspot_y; - box->width = cursor->width; - box->height = cursor->height; -} + output->cursor.is_sw = true; + output->cursor.width = width; + output->cursor.height = height; -static void output_cursor_render(struct wlr_output_cursor *cursor) { - struct wlr_texture *texture = cursor->texture; - struct wlr_renderer *renderer = cursor->renderer; - if (cursor->surface != NULL) { - // Some clients commit a cursor surface with a NULL buffer to hide it. - if (!wlr_surface_has_buffer(cursor->surface)) { - return; + if (!output->cursor.renderer) { + output->cursor.renderer = wlr_gles2_renderer_create(output->backend); + if (!output->cursor.renderer) { + return false; } - texture = cursor->surface->texture; - renderer = cursor->surface->renderer; } - if (texture == NULL || renderer == NULL) { - return; - } - - struct wlr_box output_box; - output_box.x = output_box.y = 0; - output_box.width = cursor->output->width; - output_box.height = cursor->output->height; - - struct wlr_box cursor_box; - output_cursor_get_box(cursor, &cursor_box); - - struct wlr_box intersection; - struct wlr_box *intersection_ptr = &intersection; - if (!wlr_box_intersection(&output_box, &cursor_box, &intersection_ptr)) { - return; - } - - glViewport(0, 0, cursor->output->width, cursor->output->height); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - float matrix[16]; - wlr_texture_get_matrix(texture, &matrix, - &cursor->output->transform_matrix, cursor->x - cursor->hotspot_x, - cursor->y - cursor->hotspot_y); - wlr_render_with_matrix(renderer, texture, &matrix); -} - -void wlr_output_swap_buffers(struct wlr_output *output) { - struct wlr_output_cursor *cursor; - wl_list_for_each(cursor, &output->cursors, link) { - if (output->hardware_cursor == cursor) { - continue; + if (!output->cursor.texture) { + output->cursor.texture = + wlr_render_texture_create(output->cursor.renderer); + if (!output->cursor.texture) { + return false; } - output_cursor_render(cursor); } - wl_signal_emit(&output->events.swap_buffers, &output); - - output->impl->swap_buffers(output); + return wlr_texture_upload_pixels(output->cursor.texture, + WL_SHM_FORMAT_ARGB8888, stride, width, height, buf); } -void wlr_output_set_gamma(struct wlr_output *output, - uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) { - if (output->impl->set_gamma) { - output->impl->set_gamma(output, size, r, g, b); +bool wlr_output_set_cursor(struct wlr_output *output, + const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height, + int32_t hotspot_x, int32_t hotspot_y) { + if (output->cursor.surface) { + wl_list_remove(&output->cursor.surface_commit.link); + wl_list_remove(&output->cursor.surface_destroy.link); + output->cursor.surface = NULL; } -} -uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { - if (!output->impl->get_gamma_size) { - return 0; - } - return output->impl->get_gamma_size(output); + output->cursor.hotspot_x = hotspot_x; + output->cursor.hotspot_y = hotspot_y; + + return set_cursor(output, buf, stride, width, height, hotspot_x, hotspot_y); } -static void output_cursor_reset(struct wlr_output_cursor *cursor) { - if (cursor->surface != NULL) { - wl_list_remove(&cursor->surface_commit.link); - wl_list_remove(&cursor->surface_destroy.link); - cursor->surface = NULL; - } +static inline int64_t timespec_to_msec(const struct timespec *a) { + return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; } -bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, - const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, - int32_t hotspot_x, int32_t hotspot_y) { - output_cursor_reset(cursor); - - cursor->width = width; - cursor->height = height; - cursor->hotspot_x = hotspot_x; - cursor->hotspot_y = hotspot_y; - - if (cursor->output->hardware_cursor == NULL && - cursor->output->impl->set_cursor) { - int ok = cursor->output->impl->set_cursor(cursor->output, pixels, - stride, width, height, hotspot_x, hotspot_y, true); - if (ok) { - cursor->output->hardware_cursor = cursor; - return true; - } +static void commit_cursor_surface(struct wlr_output *output, + struct wlr_surface *surface) { + if (output->cursor.is_sw) { + return; } - wlr_log(L_INFO, "Falling back to software cursor"); - - if (cursor->renderer == NULL) { - cursor->renderer = wlr_gles2_renderer_create(cursor->output->backend); - if (cursor->renderer == NULL) { - return false; - } + struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current->buffer); + if (buffer == NULL) { + return; } - if (cursor->texture == NULL) { - cursor->texture = wlr_render_texture_create(cursor->renderer); - if (cursor->texture == NULL) { - return false; - } + uint32_t format = wl_shm_buffer_get_format(buffer); + if (format != WL_SHM_FORMAT_ARGB8888) { + return; } - return wlr_texture_upload_pixels(cursor->texture, WL_SHM_FORMAT_ARGB8888, - stride, width, height, pixels); -} - -static void output_cursor_commit(struct wlr_output_cursor *cursor) { - cursor->width = cursor->surface->current->width; - cursor->height = cursor->surface->current->height; - - // TODO: if hardware cursor, upload pixels + void *buffer_data = wl_shm_buffer_get_data(buffer); + int32_t width = wl_shm_buffer_get_width(buffer); + int32_t height = wl_shm_buffer_get_height(buffer); + int32_t stride = wl_shm_buffer_get_stride(buffer); + wl_shm_buffer_begin_access(buffer); + wlr_output_set_cursor(output, buffer_data, stride/4, width, height, + output->cursor.hotspot_x - surface->current->sx, + output->cursor.hotspot_y - surface->current->sy); + wl_shm_buffer_end_access(buffer); } -static inline int64_t timespec_to_msec(const struct timespec *a) { - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; -} - -static void output_cursor_handle_commit(struct wl_listener *listener, +static void handle_cursor_surface_commit(struct wl_listener *listener, void *data) { - struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, - surface_commit); + struct wlr_output *output = wl_container_of(listener, output, + cursor.surface_commit); struct wlr_surface *surface = data; - output_cursor_commit(cursor); + commit_cursor_surface(output, surface); struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); @@ -396,107 +288,169 @@ static void output_cursor_handle_commit(struct wl_listener *listener, } } -static void output_cursor_handle_destroy(struct wl_listener *listener, +static void handle_cursor_surface_destroy(struct wl_listener *listener, void *data) { - struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, - surface_destroy); - output_cursor_reset(cursor); + struct wlr_output *output = wl_container_of(listener, output, + cursor.surface_destroy); + + wl_list_remove(&output->cursor.surface_commit.link); + wl_list_remove(&output->cursor.surface_destroy.link); + output->cursor.surface = NULL; } -void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, +void wlr_output_set_cursor_surface(struct wlr_output *output, struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y) { if (surface && strcmp(surface->role, "wl_pointer-cursor") != 0) { return; } - if (surface) { - cursor->width = surface->current->width; - cursor->height = surface->current->height; - } - cursor->hotspot_x = hotspot_x; - cursor->hotspot_y = hotspot_y; + output->cursor.hotspot_x = hotspot_x; + output->cursor.hotspot_y = hotspot_y; - if (surface && surface == cursor->surface) { - if (cursor->output->hardware_cursor == cursor && - cursor->output->impl->set_cursor) { - // If the surface hasn't changed and it's an hardware cursor, only - // update the hotspot - cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, - hotspot_x, hotspot_y, false); + if (surface && surface == output->cursor.surface) { + if (output->impl->set_cursor && !output->cursor.is_sw) { + // Only update the hotspot + output->impl->set_cursor(output, NULL, 0, 0, 0, hotspot_x, + hotspot_y, false); } return; } - output_cursor_reset(cursor); + if (output->cursor.surface) { + wl_list_remove(&output->cursor.surface_commit.link); + wl_list_remove(&output->cursor.surface_destroy.link); + output->cursor.surface = NULL; + } - // Disable hardware cursor for surfaces + // Disable hardware cursor // TODO: support hardware cursors - if (cursor->output->hardware_cursor == cursor && - cursor->output->impl->set_cursor) { - cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, 0, 0, + output->cursor.is_sw = true; + if (output->impl->set_cursor) { + output->impl->set_cursor(output, NULL, 0, 0, 0, hotspot_x, hotspot_y, true); - cursor->output->hardware_cursor = NULL; } - cursor->surface = surface; + //output->cursor.is_sw = output->impl->set_cursor == NULL; + output->cursor.surface = surface; if (surface != NULL) { - wl_signal_add(&surface->events.commit, &cursor->surface_commit); - wl_signal_add(&surface->events.destroy, &cursor->surface_destroy); - output_cursor_commit(cursor); + wl_signal_add(&surface->events.commit, &output->cursor.surface_commit); + wl_signal_add(&surface->events.destroy, + &output->cursor.surface_destroy); + commit_cursor_surface(output, surface); } else { - // TODO: if hardware cursor, disable cursor + set_cursor(output, NULL, 0, 0, 0, hotspot_x, hotspot_y); } } -bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { - cursor->x = x; - cursor->y = y; +bool wlr_output_move_cursor(struct wlr_output *output, int x, int y) { + output->cursor.x = x; + output->cursor.y = y; - if (cursor->output->hardware_cursor != cursor) { + if (output->cursor.is_sw) { return true; } - if (!cursor->output->impl->move_cursor) { + if (!output->impl->move_cursor) { return false; } - return cursor->output->impl->move_cursor(cursor->output, x, y); + + return output->impl->move_cursor(output, x, y); } -struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output) { - struct wlr_output_cursor *cursor = - calloc(1, sizeof(struct wlr_output_cursor)); - if (cursor == NULL) { - return NULL; - } - cursor->output = output; - wl_list_init(&cursor->surface_commit.link); - cursor->surface_commit.notify = output_cursor_handle_commit; - wl_list_init(&cursor->surface_destroy.link); - cursor->surface_destroy.notify = output_cursor_handle_destroy; - wl_list_insert(&output->cursors, &cursor->link); - return cursor; +void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, + const struct wlr_output_impl *impl) { + output->backend = backend; + output->impl = impl; + wl_list_init(&output->modes); + output->transform = WL_OUTPUT_TRANSFORM_NORMAL; + output->scale = 1; + wl_signal_init(&output->events.frame); + wl_signal_init(&output->events.swap_buffers); + wl_signal_init(&output->events.resolution); + wl_signal_init(&output->events.destroy); + + wl_list_init(&output->cursor.surface_commit.link); + output->cursor.surface_commit.notify = handle_cursor_surface_commit; + wl_list_init(&output->cursor.surface_destroy.link); + output->cursor.surface_destroy.notify = handle_cursor_surface_destroy; } -void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) { - if (cursor == NULL) { +void wlr_output_destroy(struct wlr_output *output) { + if (!output) { return; } - output_cursor_reset(cursor); - if (cursor->output->hardware_cursor == cursor) { - // If this cursor was the hardware cursor, disable it - if (cursor->output->impl->set_cursor) { - cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, 0, - 0, true); + + wl_signal_emit(&output->events.destroy, output); + + wlr_texture_destroy(output->cursor.texture); + wlr_renderer_destroy(output->cursor.renderer); + + struct wlr_output_mode *mode, *tmp_mode; + wl_list_for_each_safe(mode, tmp_mode, &output->modes, link) { + free(mode); + } + wl_list_remove(&output->modes); + if (output->impl && output->impl->destroy) { + output->impl->destroy(output); + } else { + free(output); + } +} + +void wlr_output_effective_resolution(struct wlr_output *output, + int *width, int *height) { + if (output->transform % 2 == 1) { + *width = output->height; + *height = output->width; + } else { + *width = output->width; + *height = output->height; + } +} + +void wlr_output_make_current(struct wlr_output *output) { + output->impl->make_current(output); +} + +void wlr_output_swap_buffers(struct wlr_output *output) { + if (output->cursor.is_sw) { + glViewport(0, 0, output->width, output->height); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + struct wlr_texture *texture = output->cursor.texture; + struct wlr_renderer *renderer = output->cursor.renderer; + if (output->cursor.surface) { + texture = output->cursor.surface->texture; + renderer = output->cursor.surface->renderer; + } + + // We check texture->valid because some clients set a cursor surface + // with a NULL buffer to hide it + if (renderer && texture && texture->valid) { + float matrix[16]; + wlr_texture_get_matrix(texture, &matrix, &output->transform_matrix, + output->cursor.x, output->cursor.y); + wlr_render_with_matrix(renderer, texture, &matrix); } - cursor->output->hardware_cursor = NULL; } - if (cursor->texture != NULL) { - wlr_texture_destroy(cursor->texture); + + wl_signal_emit(&output->events.swap_buffers, &output); + + output->impl->swap_buffers(output); +} + +void wlr_output_set_gamma(struct wlr_output *output, + uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) { + if (output->impl->set_gamma) { + output->impl->set_gamma(output, size, r, g, b); } - if (cursor->renderer != NULL) { - wlr_renderer_destroy(cursor->renderer); +} + +uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { + if (!output->impl->get_gamma_size) { + return 0; } - wl_list_remove(&cursor->link); - free(cursor); + return output->impl->get_gamma_size(output); } -- cgit v1.2.3 From a6930cd8ea2424f12aafc8d0b67426d0e5161c44 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 25 Oct 2017 22:37:02 -0400 Subject: Handle output enter/leave correctly --- include/rootston/view.h | 5 ++-- include/wlr/types/wlr_surface.h | 3 +++ rootston/desktop.c | 59 +++++++++++++++++++++++------------------ rootston/xdg_shell_v6.c | 2 +- types/wlr_output.c | 1 - types/wlr_surface.c | 13 ++++++++- 6 files changed, 51 insertions(+), 32 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 4a5e8d08..79d61ba6 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -48,7 +48,6 @@ enum roots_view_type { struct roots_view { struct roots_desktop *desktop; - struct roots_output *output; double x, y; float rotation; // TODO: Something for roots-enforced width/height @@ -72,14 +71,14 @@ struct roots_view { // configure event from the xdg_shell // If not then this should follow the typical type/impl pattern we use // elsewhere - void (*get_size)(struct roots_view *view, struct wlr_box *box); + void (*get_size)(const struct roots_view *view, struct wlr_box *box); void (*activate)(struct roots_view *view, bool active); void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); void (*set_position)(struct roots_view *view, double x, double y); void (*close)(struct roots_view *view); }; -void view_get_size(struct roots_view *view, struct wlr_box *box); +void view_get_size(const struct roots_view *view, struct wlr_box *box); void view_activate(struct roots_view *view, bool active); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); void view_set_position(struct roots_view *view, double x, double y); diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index e1a07566..cea53109 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -139,4 +139,7 @@ struct wlr_subsurface *wlr_surface_subsurface_at(struct wlr_surface *surface, void wlr_surface_send_enter(struct wlr_surface *surface, struct wlr_output *output); +void wlr_surface_send_leave(struct wlr_surface *surface, + struct wlr_output *output); + #endif diff --git a/rootston/desktop.c b/rootston/desktop.c index 37022ca4..0cc2180d 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -35,45 +35,52 @@ void view_destroy(struct roots_view *view) { free(view); } -void view_get_size(struct roots_view *view, struct wlr_box *box) { +void view_get_size(const struct roots_view *view, struct wlr_box *box) { if (view->get_size) { view->get_size(view, box); - return; + } else { + box->width = view->wlr_surface->current->width; + box->height = view->wlr_surface->current->height; } - box->x = box->y = 0; - box->width = view->wlr_surface->current->width; - box->height = view->wlr_surface->current->height; + box->x = view->x; + box->y = view->y; } -static void view_update_output(struct roots_view *view) { +static void view_update_output(const struct roots_view *view, + const struct wlr_box *before) { struct roots_desktop *desktop = view->desktop; - struct roots_output *output = NULL, *_output; + struct roots_output *output; struct wlr_box box; view_get_size(view, &box); - wl_list_for_each(_output, &desktop->outputs, link) { - if (!wlr_output_layout_intersects(desktop->layout, _output->wlr_output, - view->x, view->y, view->x + box.width, view->x + box.height)) { - continue; + wl_list_for_each(output, &desktop->outputs, link) { + bool intersected = before->x != -1 && wlr_output_layout_intersects( + desktop->layout, output->wlr_output, + before->x, before->y, before->x + before->width, + before->y + before->height); + bool intersects = wlr_output_layout_intersects( + desktop->layout, output->wlr_output, + view->x, view->y, view->x + box.width, view->y + box.height); + if (intersected && !intersects) { + wlr_log(L_DEBUG, "Leaving output %s", output->wlr_output->name); + wlr_surface_send_leave(view->wlr_surface, output->wlr_output); } - if (output == NULL - || output->wlr_output->scale < _output->wlr_output->scale) { - output = _output; + if (!intersected && intersects) { + wlr_log(L_DEBUG, "Entering output %s", output->wlr_output->name); + wlr_surface_send_enter(view->wlr_surface, output->wlr_output); } } - if (output && output != view->output) { - view->output = output; - wlr_surface_send_enter(view->wlr_surface, output->wlr_output); - } } void view_set_position(struct roots_view *view, double x, double y) { + struct wlr_box before; + view_get_size(view, &before); if (view->set_position) { view->set_position(view, x, y); } else { view->x = x; view->y = y; } - view_update_output(view); + view_update_output(view, &before); } void view_activate(struct roots_view *view, bool activate) { @@ -83,10 +90,12 @@ void view_activate(struct roots_view *view, bool activate) { } void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { + struct wlr_box before; + view_get_size(view, &before); if (view->resize) { view->resize(view, width, height); } - view_update_output(view); + view_update_output(view, &before); } void view_close(struct roots_view *view) { @@ -96,8 +105,8 @@ void view_close(struct roots_view *view) { } bool view_center(struct roots_view *view) { - struct wlr_box size; - view_get_size(view, &size); + struct wlr_box box; + view_get_size(view, &box); struct roots_desktop *desktop = view->desktop; struct wlr_cursor *cursor = desktop->server->input->cursor; @@ -122,16 +131,14 @@ bool view_center(struct roots_view *view) { double view_x = (double)(width - size.width) / 2 + l_output->x; double view_y = (double)(height - size.height) / 2 + l_output->y; - view_set_position(view, view_x, view_y); return true; } -void view_setup(struct roots_view *view) { - view_center(view); - +void view_initialize(struct roots_view *view) { struct roots_input *input = view->desktop->server->input; + view_center(view); set_view_focus(input, view->desktop, view); wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); view_update_output(view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 704ccb1e..2d83019f 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -10,7 +10,7 @@ #include "rootston/server.h" #include "rootston/input.h" -static void get_size(struct roots_view *view, struct wlr_box *box) { +static void get_size(const struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; // TODO: surf->geometry can be NULL diff --git a/types/wlr_output.c b/types/wlr_output.c index dd7e8d6a..d6efd9bf 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -43,7 +43,6 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { } } if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) { - wlr_log(L_DEBUG, "Sending scale"); wl_output_send_scale(resource, output->scale); } if (version >= WL_OUTPUT_DONE_SINCE_VERSION) { diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 28f3d05b..a21be8de 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -901,9 +901,20 @@ void wlr_surface_send_enter(struct wlr_surface *surface, struct wl_resource *resource; wl_resource_for_each(resource, &output->wl_resources) { if (client == wl_resource_get_client(resource)) { - wlr_log(L_DEBUG, "sending output enter"); wl_surface_send_enter(surface->resource, resource); break; } } } + +void wlr_surface_send_leave(struct wlr_surface *surface, + struct wlr_output *output) { + struct wl_client *client = wl_resource_get_client(surface->resource); + struct wl_resource *resource; + wl_resource_for_each(resource, &output->wl_resources) { + if (client == wl_resource_get_client(resource)) { + wl_surface_send_leave(surface->resource, resource); + break; + } + } +} -- cgit v1.2.3 From bafb97087121dbeab83ffc7d2e571d4c53d1f000 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 25 Oct 2017 22:46:20 -0400 Subject: View view_at (and pointer events) for hidpi --- rootston/desktop.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index 0cc2180d..f7f12eff 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -61,11 +61,9 @@ static void view_update_output(const struct roots_view *view, desktop->layout, output->wlr_output, view->x, view->y, view->x + box.width, view->y + box.height); if (intersected && !intersects) { - wlr_log(L_DEBUG, "Leaving output %s", output->wlr_output->name); wlr_surface_send_leave(view->wlr_surface, output->wlr_output); } if (!intersected && intersects) { - wlr_log(L_DEBUG, "Entering output %s", output->wlr_output->name); wlr_surface_send_enter(view->wlr_surface, output->wlr_output); } } @@ -167,14 +165,15 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, continue; } - double view_sx = lx - view->x; - double view_sy = ly - view->y; + int scale = view->wlr_surface->current->scale; + double view_sx = (lx - view->x) / (double)scale; + double view_sy = (ly - view->y) / (double)scale; struct wlr_box box = { .x = 0, .y = 0, - .width = view->wlr_surface->current->buffer_width, - .height = view->wlr_surface->current->buffer_height, + .width = view->wlr_surface->current->buffer_width * scale, + .height = view->wlr_surface->current->buffer_height * scale, }; if (view->rotation != 0.0) { // Coordinates relative to the center of the view -- cgit v1.2.3 From c8f97a3a2c43948147e4225e09437884a848fa9d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 25 Oct 2017 23:03:30 -0400 Subject: Use surface matrix for software cursors A similar change should probably be applied to hardware cursors, though more complicated. Also, this doesn't actually fix the issue where the cursor is too small when over a scale=2 surface. Apparently they don't set their cursor scales to 2. Seems like a client bug? idk --- types/wlr_output.c | 13 +++++++++++-- types/wlr_surface.c | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/types/wlr_output.c b/types/wlr_output.c index d6efd9bf..4bc9d6aa 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -429,8 +429,17 @@ void wlr_output_swap_buffers(struct wlr_output *output) { // with a NULL buffer to hide it if (renderer && texture && texture->valid) { float matrix[16]; - wlr_texture_get_matrix(texture, &matrix, &output->transform_matrix, - output->cursor.x, output->cursor.y); + if (output->cursor.surface) { + float translation[16]; + wlr_matrix_translate(&translation, + output->cursor.x, output->cursor.y, 0); + wlr_surface_get_matrix(output->cursor.surface, + &matrix, &output->transform_matrix, &translation); + } else { + wlr_texture_get_matrix(texture, + &matrix, &output->transform_matrix, + output->cursor.x, output->cursor.y); + } wlr_render_with_matrix(renderer, texture, &matrix); } } diff --git a/types/wlr_surface.c b/types/wlr_surface.c index a21be8de..a6f91d47 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -656,7 +656,7 @@ void wlr_surface_get_matrix(struct wlr_surface *surface, if (transform) { wlr_matrix_mul(matrix, transform, matrix); } - wlr_matrix_scale(&scale, width, height, surface->current->scale); + wlr_matrix_scale(&scale, width, height, 1); wlr_matrix_mul(matrix, &scale, matrix); wlr_matrix_mul(projection, matrix, matrix); } -- cgit v1.2.3 From 8c0929cfb3e97a71a00210fc299fb7c65703e053 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 25 Oct 2017 23:27:12 -0400 Subject: Fix backwards bit banging --- types/wlr_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/wlr_output.c b/types/wlr_output.c index 4bc9d6aa..7a56eab6 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -28,7 +28,7 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { if (version >= WL_OUTPUT_MODE_SINCE_VERSION) { struct wlr_output_mode *mode; wl_list_for_each(mode, &output->modes, link) { - uint32_t flags = mode->flags & ~WL_OUTPUT_MODE_PREFERRED; + uint32_t flags = mode->flags & WL_OUTPUT_MODE_PREFERRED; if (output->current_mode == mode) { flags |= WL_OUTPUT_MODE_CURRENT; } -- cgit v1.2.3 From 7f76f463181872f39356e5a4d6e2e34fd9a0a1bb Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 25 Oct 2017 23:48:54 -0400 Subject: Adjust rendering to compensate for disparate scale Something about my math is off, but I'm not certain what. Would appreciate a second opinion. --- rootston/output.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rootston/output.c b/rootston/output.c index faf39e74..37af1e2d 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -20,29 +20,35 @@ static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { if (surface->texture->valid) { - int width = surface->current->buffer_width; - int height = surface->current->buffer_height; + float scale_factor = (float)wlr_output->scale / surface->current->scale; + int width = surface->current->buffer_width * scale_factor; + int height = surface->current->buffer_height * scale_factor; double ox = lx, oy = ly; wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); if (wlr_output_layout_intersects(desktop->layout, wlr_output, lx, ly, lx + width, ly + height)) { - // TODO: accomodate for mismatched scale, which can happen, for - // example, when a view is rendered over two outputs float matrix[16]; float translate_origin[16]; wlr_matrix_translate(&translate_origin, (int)ox + width / 2, (int)oy + height / 2, 0); + float rotate[16]; wlr_matrix_rotate(&rotate, rotation); + float translate_center[16]; wlr_matrix_translate(&translate_center, -width / 2, -height / 2, 0); + + float scale[16]; + wlr_matrix_scale(&scale, width, height, 1); + float transform[16]; wlr_matrix_mul(&translate_origin, &rotate, &transform); wlr_matrix_mul(&transform, &translate_center, &transform); - wlr_surface_get_matrix(surface, &matrix, - &wlr_output->transform_matrix, &transform); + wlr_matrix_mul(&transform, &scale, &transform); + wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix); + wlr_render_with_matrix(desktop->server->renderer, surface->texture, &matrix); -- cgit v1.2.3 From ed74f473d60bb577aca9c7309664ae07d3ccf09b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 1 Nov 2017 08:57:30 -0400 Subject: Fix various rebase-related bugs --- rootston/desktop.c | 10 +- types/wlr_output.c | 428 +++++++++++++++++++++++++++++------------------------ 2 files changed, 239 insertions(+), 199 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index f7f12eff..a724a40c 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -127,19 +127,21 @@ bool view_center(struct roots_view *view) { int width, height; wlr_output_effective_resolution(output, &width, &height); - double view_x = (double)(width - size.width) / 2 + l_output->x; - double view_y = (double)(height - size.height) / 2 + l_output->y; + double view_x = (double)(width - box.width) / 2 + l_output->x; + double view_y = (double)(height - box.height) / 2 + l_output->y; view_set_position(view, view_x, view_y); return true; } -void view_initialize(struct roots_view *view) { +void view_setup(struct roots_view *view) { struct roots_input *input = view->desktop->server->input; view_center(view); set_view_focus(input, view->desktop, view); wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); - view_update_output(view); + struct wlr_box before; + view_get_size(view, &before); + view_update_output(view, &before); } void view_teardown(struct roots_view *view) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 7a56eab6..44d24ae3 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,8 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { if (version >= WL_OUTPUT_MODE_SINCE_VERSION) { struct wlr_output_mode *mode; wl_list_for_each(mode, &output->modes, link) { - uint32_t flags = mode->flags & WL_OUTPUT_MODE_PREFERRED; + // TODO: mode->flags should just be preferred + uint32_t flags = mode->flags; if (output->current_mode == mode) { flags |= WL_OUTPUT_MODE_CURRENT; } @@ -134,7 +136,9 @@ static void wlr_output_update_matrix(struct wlr_output *output) { } void wlr_output_enable(struct wlr_output *output, bool enable) { - output->impl->enable(output, enable); + if (output->impl->enable) { + output->impl->enable(output, enable); + } } bool wlr_output_set_mode(struct wlr_output *output, @@ -187,94 +191,199 @@ void wlr_output_set_position(struct wlr_output *output, int32_t lx, } } -static bool set_cursor(struct wlr_output *output, const uint8_t *buf, - int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, - int32_t hotspot_y) { - if (output->impl->set_cursor - && output->impl->set_cursor(output, buf, stride, width, height, - hotspot_x, hotspot_y, true)) { - output->cursor.is_sw = false; - return true; +void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, + const struct wlr_output_impl *impl) { + assert(impl->make_current && impl->swap_buffers && impl->transform); + output->backend = backend; + output->impl = impl; + wl_list_init(&output->modes); + output->transform = WL_OUTPUT_TRANSFORM_NORMAL; + output->scale = 1; + wl_list_init(&output->cursors); + wl_signal_init(&output->events.frame); + wl_signal_init(&output->events.swap_buffers); + wl_signal_init(&output->events.resolution); + wl_signal_init(&output->events.destroy); +} + +void wlr_output_destroy(struct wlr_output *output) { + if (!output) { + return; } - wlr_log(L_INFO, "Falling back to software cursor"); + wl_signal_emit(&output->events.destroy, output); - output->cursor.is_sw = true; - output->cursor.width = width; - output->cursor.height = height; + struct wlr_output_mode *mode, *tmp_mode; + wl_list_for_each_safe(mode, tmp_mode, &output->modes, link) { + free(mode); + } + wl_list_remove(&output->modes); + if (output->impl && output->impl->destroy) { + output->impl->destroy(output); + } else { + free(output); + } +} - if (!output->cursor.renderer) { - output->cursor.renderer = wlr_gles2_renderer_create(output->backend); - if (!output->cursor.renderer) { - return false; - } +void wlr_output_effective_resolution(struct wlr_output *output, + int *width, int *height) { + // TODO: Scale factor + if (output->transform % 2 == 1) { + *width = output->height; + *height = output->width; + } else { + *width = output->width; + *height = output->height; } +} - if (!output->cursor.texture) { - output->cursor.texture = - wlr_render_texture_create(output->cursor.renderer); - if (!output->cursor.texture) { - return false; +void wlr_output_make_current(struct wlr_output *output) { + output->impl->make_current(output); +} + +static void output_cursor_get_box(struct wlr_output_cursor *cursor, + struct wlr_box *box) { + box->x = cursor->x - cursor->hotspot_x; + box->y = cursor->y - cursor->hotspot_y; + box->width = cursor->width; + box->height = cursor->height; +} + +static void output_cursor_render(struct wlr_output_cursor *cursor) { + struct wlr_texture *texture = cursor->texture; + struct wlr_renderer *renderer = cursor->renderer; + if (cursor->surface != NULL) { + // Some clients commit a cursor surface with a NULL buffer to hide it. + if (!wlr_surface_has_buffer(cursor->surface)) { + return; } + texture = cursor->surface->texture; + renderer = cursor->surface->renderer; } - return wlr_texture_upload_pixels(output->cursor.texture, - WL_SHM_FORMAT_ARGB8888, stride, width, height, buf); + if (texture == NULL || renderer == NULL) { + return; + } + + struct wlr_box output_box; + output_box.x = output_box.y = 0; + output_box.width = cursor->output->width; + output_box.height = cursor->output->height; + + struct wlr_box cursor_box; + output_cursor_get_box(cursor, &cursor_box); + + struct wlr_box intersection; + struct wlr_box *intersection_ptr = &intersection; + if (!wlr_box_intersection(&output_box, &cursor_box, &intersection_ptr)) { + return; + } + + glViewport(0, 0, cursor->output->width, cursor->output->height); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + float matrix[16]; + wlr_texture_get_matrix(texture, &matrix, + &cursor->output->transform_matrix, cursor->x - cursor->hotspot_x, + cursor->y - cursor->hotspot_y); + wlr_render_with_matrix(renderer, texture, &matrix); } -bool wlr_output_set_cursor(struct wlr_output *output, - const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height, - int32_t hotspot_x, int32_t hotspot_y) { - if (output->cursor.surface) { - wl_list_remove(&output->cursor.surface_commit.link); - wl_list_remove(&output->cursor.surface_destroy.link); - output->cursor.surface = NULL; +void wlr_output_swap_buffers(struct wlr_output *output) { + struct wlr_output_cursor *cursor; + wl_list_for_each(cursor, &output->cursors, link) { + if (output->hardware_cursor == cursor) { + continue; + } + output_cursor_render(cursor); } - output->cursor.hotspot_x = hotspot_x; - output->cursor.hotspot_y = hotspot_y; + wl_signal_emit(&output->events.swap_buffers, &output); - return set_cursor(output, buf, stride, width, height, hotspot_x, hotspot_y); + output->impl->swap_buffers(output); } -static inline int64_t timespec_to_msec(const struct timespec *a) { - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; +void wlr_output_set_gamma(struct wlr_output *output, + uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) { + if (output->impl->set_gamma) { + output->impl->set_gamma(output, size, r, g, b); + } } -static void commit_cursor_surface(struct wlr_output *output, - struct wlr_surface *surface) { - if (output->cursor.is_sw) { - return; +uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { + if (!output->impl->get_gamma_size) { + return 0; } + return output->impl->get_gamma_size(output); +} - struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current->buffer); - if (buffer == NULL) { - return; +static void output_cursor_reset(struct wlr_output_cursor *cursor) { + if (cursor->surface != NULL) { + wl_list_remove(&cursor->surface_commit.link); + wl_list_remove(&cursor->surface_destroy.link); + cursor->surface = NULL; } +} - uint32_t format = wl_shm_buffer_get_format(buffer); - if (format != WL_SHM_FORMAT_ARGB8888) { - return; +bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, + const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, + int32_t hotspot_x, int32_t hotspot_y) { + output_cursor_reset(cursor); + + cursor->width = width; + cursor->height = height; + cursor->hotspot_x = hotspot_x; + cursor->hotspot_y = hotspot_y; + + if (cursor->output->hardware_cursor == NULL && + cursor->output->impl->set_cursor) { + int ok = cursor->output->impl->set_cursor(cursor->output, pixels, + stride, width, height, hotspot_x, hotspot_y, true); + if (ok) { + cursor->output->hardware_cursor = cursor; + return true; + } } - void *buffer_data = wl_shm_buffer_get_data(buffer); - int32_t width = wl_shm_buffer_get_width(buffer); - int32_t height = wl_shm_buffer_get_height(buffer); - int32_t stride = wl_shm_buffer_get_stride(buffer); - wl_shm_buffer_begin_access(buffer); - wlr_output_set_cursor(output, buffer_data, stride/4, width, height, - output->cursor.hotspot_x - surface->current->sx, - output->cursor.hotspot_y - surface->current->sy); - wl_shm_buffer_end_access(buffer); + wlr_log(L_INFO, "Falling back to software cursor"); + + if (cursor->renderer == NULL) { + cursor->renderer = wlr_gles2_renderer_create(cursor->output->backend); + if (cursor->renderer == NULL) { + return false; + } + } + + if (cursor->texture == NULL) { + cursor->texture = wlr_render_texture_create(cursor->renderer); + if (cursor->texture == NULL) { + return false; + } + } + + return wlr_texture_upload_pixels(cursor->texture, WL_SHM_FORMAT_ARGB8888, + stride, width, height, pixels); } -static void handle_cursor_surface_commit(struct wl_listener *listener, +static void output_cursor_commit(struct wlr_output_cursor *cursor) { + cursor->width = cursor->surface->current->width; + cursor->height = cursor->surface->current->height; + + // TODO: if hardware cursor, upload pixels +} + +static inline int64_t timespec_to_msec(const struct timespec *a) { + return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; +} + +static void output_cursor_handle_commit(struct wl_listener *listener, void *data) { - struct wlr_output *output = wl_container_of(listener, output, - cursor.surface_commit); + struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, + surface_commit); struct wlr_surface *surface = data; - commit_cursor_surface(output, surface); + output_cursor_commit(cursor); struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); @@ -287,178 +396,107 @@ static void handle_cursor_surface_commit(struct wl_listener *listener, } } -static void handle_cursor_surface_destroy(struct wl_listener *listener, +static void output_cursor_handle_destroy(struct wl_listener *listener, void *data) { - struct wlr_output *output = wl_container_of(listener, output, - cursor.surface_destroy); - - wl_list_remove(&output->cursor.surface_commit.link); - wl_list_remove(&output->cursor.surface_destroy.link); - output->cursor.surface = NULL; + struct wlr_output_cursor *cursor = wl_container_of(listener, cursor, + surface_destroy); + output_cursor_reset(cursor); } -void wlr_output_set_cursor_surface(struct wlr_output *output, +void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y) { if (surface && strcmp(surface->role, "wl_pointer-cursor") != 0) { return; } - output->cursor.hotspot_x = hotspot_x; - output->cursor.hotspot_y = hotspot_y; + if (surface) { + cursor->width = surface->current->width; + cursor->height = surface->current->height; + } + cursor->hotspot_x = hotspot_x; + cursor->hotspot_y = hotspot_y; - if (surface && surface == output->cursor.surface) { - if (output->impl->set_cursor && !output->cursor.is_sw) { - // Only update the hotspot - output->impl->set_cursor(output, NULL, 0, 0, 0, hotspot_x, - hotspot_y, false); + if (surface && surface == cursor->surface) { + if (cursor->output->hardware_cursor == cursor && + cursor->output->impl->set_cursor) { + // If the surface hasn't changed and it's an hardware cursor, only + // update the hotspot + cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, + hotspot_x, hotspot_y, false); } return; } - if (output->cursor.surface) { - wl_list_remove(&output->cursor.surface_commit.link); - wl_list_remove(&output->cursor.surface_destroy.link); - output->cursor.surface = NULL; - } + output_cursor_reset(cursor); - // Disable hardware cursor + // Disable hardware cursor for surfaces // TODO: support hardware cursors - output->cursor.is_sw = true; - if (output->impl->set_cursor) { - output->impl->set_cursor(output, NULL, 0, 0, 0, hotspot_x, hotspot_y, + if (cursor->output->hardware_cursor == cursor && + cursor->output->impl->set_cursor) { + cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, 0, 0, true); + cursor->output->hardware_cursor = NULL; } - //output->cursor.is_sw = output->impl->set_cursor == NULL; - output->cursor.surface = surface; + cursor->surface = surface; if (surface != NULL) { - wl_signal_add(&surface->events.commit, &output->cursor.surface_commit); - wl_signal_add(&surface->events.destroy, - &output->cursor.surface_destroy); - commit_cursor_surface(output, surface); + wl_signal_add(&surface->events.commit, &cursor->surface_commit); + wl_signal_add(&surface->events.destroy, &cursor->surface_destroy); + output_cursor_commit(cursor); } else { - set_cursor(output, NULL, 0, 0, 0, hotspot_x, hotspot_y); + // TODO: if hardware cursor, disable cursor } } -bool wlr_output_move_cursor(struct wlr_output *output, int x, int y) { - output->cursor.x = x; - output->cursor.y = y; +bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { + cursor->x = x; + cursor->y = y; - if (output->cursor.is_sw) { + if (cursor->output->hardware_cursor != cursor) { return true; } - if (!output->impl->move_cursor) { + if (!cursor->output->impl->move_cursor) { return false; } - - return output->impl->move_cursor(output, x, y); + return cursor->output->impl->move_cursor(cursor->output, x, y); } -void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, - const struct wlr_output_impl *impl) { - output->backend = backend; - output->impl = impl; - wl_list_init(&output->modes); - output->transform = WL_OUTPUT_TRANSFORM_NORMAL; - output->scale = 1; - wl_signal_init(&output->events.frame); - wl_signal_init(&output->events.swap_buffers); - wl_signal_init(&output->events.resolution); - wl_signal_init(&output->events.destroy); - - wl_list_init(&output->cursor.surface_commit.link); - output->cursor.surface_commit.notify = handle_cursor_surface_commit; - wl_list_init(&output->cursor.surface_destroy.link); - output->cursor.surface_destroy.notify = handle_cursor_surface_destroy; +struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output) { + struct wlr_output_cursor *cursor = + calloc(1, sizeof(struct wlr_output_cursor)); + if (cursor == NULL) { + return NULL; + } + cursor->output = output; + wl_list_init(&cursor->surface_commit.link); + cursor->surface_commit.notify = output_cursor_handle_commit; + wl_list_init(&cursor->surface_destroy.link); + cursor->surface_destroy.notify = output_cursor_handle_destroy; + wl_list_insert(&output->cursors, &cursor->link); + return cursor; } -void wlr_output_destroy(struct wlr_output *output) { - if (!output) { +void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor) { + if (cursor == NULL) { return; } - - wl_signal_emit(&output->events.destroy, output); - - wlr_texture_destroy(output->cursor.texture); - wlr_renderer_destroy(output->cursor.renderer); - - struct wlr_output_mode *mode, *tmp_mode; - wl_list_for_each_safe(mode, tmp_mode, &output->modes, link) { - free(mode); - } - wl_list_remove(&output->modes); - if (output->impl && output->impl->destroy) { - output->impl->destroy(output); - } else { - free(output); - } -} - -void wlr_output_effective_resolution(struct wlr_output *output, - int *width, int *height) { - if (output->transform % 2 == 1) { - *width = output->height; - *height = output->width; - } else { - *width = output->width; - *height = output->height; - } -} - -void wlr_output_make_current(struct wlr_output *output) { - output->impl->make_current(output); -} - -void wlr_output_swap_buffers(struct wlr_output *output) { - if (output->cursor.is_sw) { - glViewport(0, 0, output->width, output->height); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - struct wlr_texture *texture = output->cursor.texture; - struct wlr_renderer *renderer = output->cursor.renderer; - if (output->cursor.surface) { - texture = output->cursor.surface->texture; - renderer = output->cursor.surface->renderer; - } - - // We check texture->valid because some clients set a cursor surface - // with a NULL buffer to hide it - if (renderer && texture && texture->valid) { - float matrix[16]; - if (output->cursor.surface) { - float translation[16]; - wlr_matrix_translate(&translation, - output->cursor.x, output->cursor.y, 0); - wlr_surface_get_matrix(output->cursor.surface, - &matrix, &output->transform_matrix, &translation); - } else { - wlr_texture_get_matrix(texture, - &matrix, &output->transform_matrix, - output->cursor.x, output->cursor.y); - } - wlr_render_with_matrix(renderer, texture, &matrix); + output_cursor_reset(cursor); + if (cursor->output->hardware_cursor == cursor) { + // If this cursor was the hardware cursor, disable it + if (cursor->output->impl->set_cursor) { + cursor->output->impl->set_cursor(cursor->output, NULL, 0, 0, 0, 0, + 0, true); } + cursor->output->hardware_cursor = NULL; } - - wl_signal_emit(&output->events.swap_buffers, &output); - - output->impl->swap_buffers(output); -} - -void wlr_output_set_gamma(struct wlr_output *output, - uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) { - if (output->impl->set_gamma) { - output->impl->set_gamma(output, size, r, g, b); + if (cursor->texture != NULL) { + wlr_texture_destroy(cursor->texture); } -} - -uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { - if (!output->impl->get_gamma_size) { - return 0; + if (cursor->renderer != NULL) { + wlr_renderer_destroy(cursor->renderer); } - return output->impl->get_gamma_size(output); + wl_list_remove(&cursor->link); + free(cursor); } -- cgit v1.2.3 From 53021f8ed428a1a023769339e6162bfebbe4c7a2 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 2 Nov 2017 20:13:10 -0400 Subject: rootston: break up input.h --- include/rootston/input.h | 52 ------------------------------------------ include/rootston/keyboard.h | 22 ++++++++++++++++++ include/rootston/pointer.h | 16 +++++++++++++ include/rootston/tablet_tool.h | 20 ++++++++++++++++ include/rootston/touch.h | 22 ++++++++++++++++++ rootston/config.c | 1 + rootston/cursor.c | 4 ++++ rootston/input.c | 4 ++++ rootston/keyboard.c | 1 + rootston/pointer.c | 1 + rootston/tablet_tool.c | 1 + rootston/touch.c | 1 + 12 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 include/rootston/keyboard.h create mode 100644 include/rootston/pointer.h create mode 100644 include/rootston/tablet_tool.h create mode 100644 include/rootston/touch.h diff --git a/include/rootston/input.h b/include/rootston/input.h index 20b73c8a..6d07de43 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -1,6 +1,5 @@ #ifndef _ROOTSTON_INPUT_H #define _ROOTSTON_INPUT_H -#include #include #include #include @@ -10,41 +9,6 @@ #include "rootston/view.h" #include "rootston/server.h" -#define ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP 32 - -struct roots_keyboard { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener key; - struct wl_listener modifiers; - struct wl_list link; - - xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; -}; - -struct roots_pointer { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -struct roots_touch { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -// TODO: tablet pad -struct roots_tablet_tool { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener axis; - struct wl_listener proximity; - struct wl_listener tip; - struct wl_listener button; - struct wl_list link; -}; - enum roots_cursor_mode { ROOTS_CURSOR_PASSTHROUGH = 0, ROOTS_CURSOR_MOVE = 1, @@ -77,13 +41,6 @@ struct roots_drag_icon { struct wl_listener surface_commit; }; -struct roots_touch_point { - struct roots_touch *device; - int32_t slot; - double x, y; - struct wl_list link; -}; - struct roots_input { struct roots_config *config; struct roots_server *server; @@ -138,15 +95,6 @@ struct roots_input *input_create(struct roots_server *server, struct roots_config *config); void input_destroy(struct roots_input *input); -void pointer_add(struct wlr_input_device *device, struct roots_input *input); -void pointer_remove(struct wlr_input_device *device, struct roots_input *input); -void keyboard_add(struct wlr_input_device *device, struct roots_input *input); -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); -void touch_add(struct wlr_input_device *device, struct roots_input *input); -void touch_remove(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); - void cursor_initialize(struct roots_input *input); void cursor_load_config(struct roots_config *config, struct wlr_cursor *cursor, diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h new file mode 100644 index 00000000..33017b56 --- /dev/null +++ b/include/rootston/keyboard.h @@ -0,0 +1,22 @@ +#ifndef _ROOTSTON_KEYBOARD_H +#define _ROOTSTON_KEYBOARD_H + +#include +#include "rootston/input.h" + +#define ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP 32 + +struct roots_keyboard { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_listener key; + struct wl_listener modifiers; + struct wl_list link; + + xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; +}; + +void keyboard_add(struct wlr_input_device *device, struct roots_input *input); +void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/pointer.h b/include/rootston/pointer.h new file mode 100644 index 00000000..b3fc8c3a --- /dev/null +++ b/include/rootston/pointer.h @@ -0,0 +1,16 @@ +#ifndef _ROOTSTON_POINTER_H +#define _ROOTSTON_POINTER_H + +#include +#include + +struct roots_pointer { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_list link; +}; + +void pointer_add(struct wlr_input_device *device, struct roots_input *input); +void pointer_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/tablet_tool.h b/include/rootston/tablet_tool.h new file mode 100644 index 00000000..72ebf6d8 --- /dev/null +++ b/include/rootston/tablet_tool.h @@ -0,0 +1,20 @@ +#ifndef _ROOTSTON_TABLET_TOOL_H +#define _ROOTSTON_TABLET_TOOL_H + +#include +#include "rootston/input.h" + +struct roots_tablet_tool { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_listener axis; + struct wl_listener proximity; + struct wl_listener tip; + struct wl_listener button; + struct wl_list link; +}; + +void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); +void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/include/rootston/touch.h b/include/rootston/touch.h new file mode 100644 index 00000000..1624c3ad --- /dev/null +++ b/include/rootston/touch.h @@ -0,0 +1,22 @@ +#ifndef _ROOTSTON_TOUCH_H +#define _ROOTSTON_TOUCH_H + +#include + +struct roots_touch { + struct roots_input *input; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch_point { + struct roots_touch *device; + int32_t slot; + double x, y; + struct wl_list link; +}; + +void touch_add(struct wlr_input_device *device, struct roots_input *input); +void touch_remove(struct wlr_input_device *device, struct roots_input *input); + +#endif diff --git a/rootston/config.c b/rootston/config.c index dc7a4b1d..a3ae78be 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -13,6 +13,7 @@ #include #include "rootston/config.h" #include "rootston/input.h" +#include "rootston/keyboard.h" #include "rootston/ini.h" static void usage(const char *name, int ret) { diff --git a/rootston/cursor.c b/rootston/cursor.c index 31001a9f..61dcae7a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -18,6 +18,10 @@ #include "rootston/input.h" #include "rootston/desktop.h" #include "rootston/view.h" +#include "rootston/keyboard.h" +#include "rootston/pointer.h" +#include "rootston/tablet_tool.h" +#include "rootston/touch.h" const struct roots_input_event *get_input_event(struct roots_input *input, uint32_t serial) { diff --git a/rootston/input.c b/rootston/input.c index 5d367a5e..c8d46a69 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -8,6 +8,10 @@ #include "rootston/server.h" #include "rootston/config.h" #include "rootston/input.h" +#include "rootston/tablet_tool.h" +#include "rootston/keyboard.h" +#include "rootston/pointer.h" +#include "rootston/touch.h" static const char *device_type(enum wlr_input_device_type type) { switch (type) { diff --git a/rootston/keyboard.c b/rootston/keyboard.c index e174b731..9458a05c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { diff --git a/rootston/pointer.c b/rootston/pointer.c index 299ecdfc..cb099264 100644 --- a/rootston/pointer.c +++ b/rootston/pointer.c @@ -3,6 +3,7 @@ #include #include #include "rootston/input.h" +#include "rootston/pointer.h" void pointer_add(struct wlr_input_device *device, struct roots_input *input) { struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); diff --git a/rootston/tablet_tool.c b/rootston/tablet_tool.c index a612e683..3327115d 100644 --- a/rootston/tablet_tool.c +++ b/rootston/tablet_tool.c @@ -4,6 +4,7 @@ #include #include #include "rootston/input.h" +#include "rootston/tablet_tool.h" void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input) { struct roots_tablet_tool *tool = calloc(sizeof(struct roots_tablet_tool), 1); diff --git a/rootston/touch.c b/rootston/touch.c index f6d9b11a..069853ab 100644 --- a/rootston/touch.c +++ b/rootston/touch.c @@ -3,6 +3,7 @@ #include #include #include "rootston/input.h" +#include "rootston/touch.h" // TODO: we'll likely want touch events to both control the cursor *and* be // submitted directly to the seat. -- cgit v1.2.3 From ca8cf7d48dc8de94494e23292c1687c1dad766f2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 2 Nov 2017 23:17:39 -0400 Subject: Rethink HiDPI output layouts, fixes everything Except for subsurfaces not rendering at the right scale. But that part is (somewhat) easy. --- rootston/desktop.c | 9 ++++----- rootston/output.c | 2 ++ types/wlr_output.c | 5 ++++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index a724a40c..f87be11e 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -167,15 +167,14 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, continue; } - int scale = view->wlr_surface->current->scale; - double view_sx = (lx - view->x) / (double)scale; - double view_sy = (ly - view->y) / (double)scale; + double view_sx = lx - view->x; + double view_sy = ly - view->y; struct wlr_box box = { .x = 0, .y = 0, - .width = view->wlr_surface->current->buffer_width * scale, - .height = view->wlr_surface->current->buffer_height * scale, + .width = view->wlr_surface->current->buffer_width, + .height = view->wlr_surface->current->buffer_height, }; if (view->rotation != 0.0) { // Coordinates relative to the center of the view diff --git a/rootston/output.c b/rootston/output.c index 37af1e2d..c21c6781 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -25,6 +25,8 @@ static void render_surface(struct wlr_surface *surface, int height = surface->current->buffer_height * scale_factor; double ox = lx, oy = ly; wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); + ox *= wlr_output->scale; + oy *= wlr_output->scale; if (wlr_output_layout_intersects(desktop->layout, wlr_output, lx, ly, lx + width, ly + height)) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 44d24ae3..82e805b4 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -227,7 +227,6 @@ void wlr_output_destroy(struct wlr_output *output) { void wlr_output_effective_resolution(struct wlr_output *output, int *width, int *height) { - // TODO: Scale factor if (output->transform % 2 == 1) { *width = output->height; *height = output->width; @@ -235,6 +234,8 @@ void wlr_output_effective_resolution(struct wlr_output *output, *width = output->width; *height = output->height; } + *width /= output->scale; + *height /= output->scale; } void wlr_output_make_current(struct wlr_output *output) { @@ -450,6 +451,8 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, } bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { + x *= cursor->output->scale; + y *= cursor->output->scale; cursor->x = x; cursor->y = y; -- cgit v1.2.3 From 975b9dc365d5a7bec531522320a1506323575525 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 2 Nov 2017 23:33:06 -0400 Subject: Fix view centering on HiDPI outputs --- rootston/desktop.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rootston/desktop.c b/rootston/desktop.c index f87be11e..fe95426f 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -126,6 +126,8 @@ bool view_center(struct roots_view *view) { int width, height; wlr_output_effective_resolution(output, &width, &height); + width /= output->scale; + height /= output->scale; double view_x = (double)(width - box.width) / 2 + l_output->x; double view_y = (double)(height - box.height) / 2 + l_output->y; -- cgit v1.2.3 From 447c561d1588226fd6aeb6668c7adb352cb77725 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 06:08:37 -0400 Subject: rootston: seat config by device --- include/rootston/config.h | 1 + rootston/config.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/rootston/config.h b/include/rootston/config.h index 75c04619..58fb1a1c 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -19,6 +19,7 @@ struct device_config { char *name; char *mapped_output; struct wlr_box *mapped_box; + char *seat; struct wl_list link; }; diff --git a/rootston/config.c b/rootston/config.c index a3ae78be..815040bf 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -289,6 +289,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, if (!found) { dc = calloc(1, sizeof(struct device_config)); dc->name = strdup(device_name); + dc->seat = strdup("seat0"); wl_list_insert(&config->devices, &dc->link); } @@ -298,6 +299,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(name, "geometry") == 0) { free(dc->mapped_box); dc->mapped_box = parse_geometry(value); + } else if (strcmp(name, "seat") == 0) { + free(dc->seat); + dc->seat = strdup(value); } else { wlr_log(L_ERROR, "got unknown device config: %s", name); } @@ -387,6 +391,7 @@ void roots_config_destroy(struct roots_config *config) { struct device_config *dc, *dtmp = NULL; wl_list_for_each_safe(dc, dtmp, &config->devices, link) { free(dc->name); + free(dc->seat); free(dc->mapped_output); free(dc->mapped_box); free(dc); -- cgit v1.2.3 From 9bd0f47efd9a0c851d1715f3b9427b5f51b6d8a3 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 06:18:20 -0400 Subject: rootston: refactor keyboard --- include/rootston/keyboard.h | 10 ++++++++-- rootston/input.c | 4 ++-- rootston/keyboard.c | 35 ++++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 33017b56..f4acc0aa 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -16,7 +16,13 @@ struct roots_keyboard { xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; -void keyboard_add(struct wlr_input_device *device, struct roots_input *input); -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input); +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input); +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event); + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/rootston/input.c b/rootston/input.c index c8d46a69..2f50c708 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -36,7 +36,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) { device->vendor, device->product, device_type(device->type)); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_add(device, input); + roots_keyboard_create(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); @@ -57,7 +57,7 @@ static void input_remove_notify(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, input_remove); switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - keyboard_remove(device, input); + roots_keyboard_destroy(device, input); break; case WLR_INPUT_DEVICE_POINTER: pointer_remove(device, input); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9458a05c..ece95245 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -123,10 +123,8 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -static void keyboard_key_notify(struct wl_listener *listener, void *data) { - struct wlr_event_keyboard_key *event = data; - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - +void roots_keyboard_handle_key(struct roots_keyboard *keyboard, + struct wlr_event_keyboard_key *event) { uint32_t keycode = event->keycode + 8; const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, @@ -149,9 +147,13 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } } -static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->input->wl_seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); @@ -160,7 +162,12 @@ static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) keyboard->modifiers.latched, keyboard->modifiers.locked, keyboard->modifiers.group); +} +static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { + struct roots_keyboard *r_keyboard = + wl_container_of(listener, r_keyboard, modifiers); + roots_keyboard_handle_modifiers(r_keyboard); } static void keyboard_config_merge(struct keyboard_config *config, @@ -185,19 +192,19 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { - return; + return NULL; } device->data = keyboard; keyboard->device = device; keyboard->input = input; - keyboard->key.notify = keyboard_key_notify; + keyboard->key.notify = handle_keyboard_key; wl_signal_add(&device->keyboard->events.key, &keyboard->key); - keyboard->modifiers.notify = keyboard_modifiers_notify; + keyboard->modifiers.notify = handle_keyboard_modifiers; wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); wl_list_insert(&input->keyboards, &keyboard->link); @@ -226,14 +233,16 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) { struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); - return; + return NULL; } wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); xkb_context_unref(context); + + return keyboard; } -void keyboard_remove(struct wlr_input_device *device, struct roots_input *input) { +void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->key.link); wl_list_remove(&keyboard->modifiers.link); -- cgit v1.2.3 From 6d8e1abfc0a266e8ff1a8c9ba1a004faeaac79d5 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 4 Nov 2017 01:35:12 -0400 Subject: Improve input sensitivity We now use doubles until the last minute, which makes it so we can move the pointer more precisely. This also includes a fix for tablet tools, which move absolutely and sometimes do not update the X or Y axis. --- backend/libinput/tablet_tool.c | 2 ++ include/wlr/types/wlr_output.h | 5 +++-- rootston/cursor.c | 9 +++++++++ types/wlr_cursor.c | 4 ++-- types/wlr_output.c | 6 ++++-- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/backend/libinput/tablet_tool.c b/backend/libinput/tablet_tool.c index 3caaf3f7..3d5fafc3 100644 --- a/backend/libinput/tablet_tool.c +++ b/backend/libinput/tablet_tool.c @@ -70,6 +70,8 @@ void handle_tablet_tool_axis(struct libinput_event *event, wlr_event.updated_axes |= WLR_TABLET_TOOL_AXIS_WHEEL; wlr_event.wheel_delta = libinput_event_tablet_tool_get_wheel_delta(tevent); } + wlr_log(L_DEBUG, "Tablet tool axis event %d @ %f,%f", + wlr_event.updated_axes, wlr_event.x_mm, wlr_event.y_mm); wl_signal_emit(&wlr_dev->tablet_tool->events.axis, &wlr_event); } diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index e6323f9c..df123639 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -14,7 +14,7 @@ struct wlr_output_mode { struct wlr_output_cursor { struct wlr_output *output; - int32_t x, y; + double x, y; bool enabled; uint32_t width, height; int32_t hotspot_x, hotspot_y; @@ -95,7 +95,8 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, int32_t hotspot_x, int32_t hotspot_y); void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y); -bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y); +bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, + double x, double y); void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor); #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 31001a9f..aa8e5122 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -378,11 +378,20 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { static void handle_tool_axis(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, cursor_tool_axis); 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(input->cursor, event->device, event->x_mm / event->width_mm, event->y_mm / event->height_mm); cursor_update_position(input, event->time_msec); + } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X)) { + wlr_cursor_warp_absolute(input->cursor, event->device, + event->x_mm / event->width_mm, -1); + cursor_update_position(input, event->time_msec); + } else if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { + wlr_cursor_warp_absolute(input->cursor, event->device, + -1, event->y_mm / event->height_mm); + cursor_update_position(input, event->time_msec); } } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 83d36d14..dfaccb53 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -261,8 +261,8 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, mapping = wlr_output_layout_get_box(cur->state->layout, NULL); } - double x = mapping->width * x_mm + mapping->x; - double y = mapping->height * y_mm + mapping->y; + 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; wlr_cursor_warp_unchecked(cur, x, y); } diff --git a/types/wlr_output.c b/types/wlr_output.c index ff8b07be..3ad69ce3 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -472,9 +472,11 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, } } -bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { +bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, + double x, double y) { x *= cursor->output->scale; y *= cursor->output->scale; + wlr_log(L_DEBUG, "Moving cursor to %f,%f", x, y); cursor->x = x; cursor->y = y; @@ -486,7 +488,7 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, int x, int y) { if (!cursor->output->impl->move_cursor) { return false; } - return cursor->output->impl->move_cursor(cursor->output, x, y); + return cursor->output->impl->move_cursor(cursor->output, (int)x, (int)y); } struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output) { -- cgit v1.2.3 From 5354fe8729b8c52f8f3ff63f23f932c49bf8c880 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 3 Nov 2017 09:01:34 -0400 Subject: move keyboard to seat --- backend/libinput/keyboard.c | 1 + backend/wayland/wl_seat.c | 12 +++++-- backend/x11/backend.c | 1 + include/rootston/input.h | 1 + include/rootston/keyboard.h | 15 +++++--- include/rootston/seat.h | 26 ++++++++++++++ include/wlr/interfaces/wlr_keyboard.h | 3 +- include/wlr/types/wlr_keyboard.h | 11 ++++++ rootston/input.c | 33 ++++++++++++++++-- rootston/keyboard.c | 38 ++++++-------------- rootston/meson.build | 1 + rootston/seat.c | 66 +++++++++++++++++++++++++++++++++++ types/wlr_keyboard.c | 11 +++--- 13 files changed, 176 insertions(+), 43 deletions(-) create mode 100644 include/rootston/seat.h create mode 100644 rootston/seat.c diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 065d8ead..9a24c791 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,6 +54,7 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; + wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index deed215e..146296ae 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,6 +151,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; + wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -162,8 +163,15 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, - mods_locked, group); + struct wlr_event_keyboard_modifiers wlr_event; + wlr_event.device = dev; + wlr_event.keyboard = dev->keyboard; + wlr_event.mods_depressed = mods_depressed; + wlr_event.mods_latched = mods_latched; + wlr_event.mods_locked = mods_locked; + wlr_event.group = group; + + wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 97b0dd8c..f76b314e 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,6 +50,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { + .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/input.h b/include/rootston/input.h index 6d07de43..7b1358f8 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -67,6 +67,7 @@ struct roots_input { struct wl_list pointers; struct wl_list touch; struct wl_list tablet_tools; + struct wl_list seats; struct wl_listener input_add; struct wl_listener input_remove; diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index f4acc0aa..cb639ba1 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -8,21 +8,28 @@ struct roots_keyboard { struct roots_input *input; + struct roots_seat *seat; struct wlr_input_device *device; - struct wl_listener key; - struct wl_listener modifiers; + struct wl_list seat_link; + // XXX temporary struct wl_list link; + struct wl_listener keyboard_key; + struct wl_listener keyboard_modifiers; + xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input); + +void roots_keyboard_destroy(struct wlr_input_device *device, + struct roots_input *input); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h new file mode 100644 index 00000000..f6db63cc --- /dev/null +++ b/include/rootston/seat.h @@ -0,0 +1,26 @@ +#ifndef _ROOTSTON_SEAT_H +#define _ROOTSTON_SEAT_H + +#include + +#include "rootston/input.h" +#include "rootston/keyboard.h" + +struct roots_seat { + struct roots_input *input; + struct wlr_seat *seat; + struct wl_list keyboards; + struct wl_list link; +}; + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name); + +void roots_seat_destroy(struct roots_seat *seat); + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard); + +#endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 570f5721..5848416d 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,7 +14,6 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); + struct wlr_event_keyboard_modifiers *event); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af837ff5..c42cea9c 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -63,12 +63,23 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; +struct wlr_event_keyboard_modifiers { + struct wlr_input_device *device; + struct wlr_keyboard *keyboard; + uint32_t mods_depressed; + uint32_t mods_latched; + uint32_t mods_locked; + uint32_t group; +}; + void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/input.c b/rootston/input.c index 2f50c708..51a64720 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -12,6 +12,7 @@ #include "rootston/keyboard.h" #include "rootston/pointer.h" #include "rootston/touch.h" +#include "rootston/seat.h" static const char *device_type(enum wlr_input_device_type type) { switch (type) { @@ -29,15 +30,42 @@ static const char *device_type(enum wlr_input_device_type type) { return NULL; } +static struct roots_seat *input_get_seat(struct roots_input *input, char *name) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (strcmp(seat->seat->name, name) == 0) { + return seat; + } + } + + seat = roots_seat_create(input, name); + return seat; +} + static void input_add_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; struct roots_input *input = wl_container_of(listener, input, input_add); + + char *seat_name = "seat0"; + struct device_config *dc = config_get_device(input->config, device); + if (dc) { + seat_name = dc->seat; + } + + struct roots_seat *seat = input_get_seat(input, seat_name); + if (!seat) { + wlr_log(L_ERROR, "could not create roots seat"); + return; + } + wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, device->vendor, device->product, device_type(device->type)); switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - roots_keyboard_create(device, input); + case WLR_INPUT_DEVICE_KEYBOARD: { + struct roots_keyboard *keyboard = roots_keyboard_create(device, input); + roots_seat_add_keyboard(seat, keyboard); break; + } case WLR_INPUT_DEVICE_POINTER: pointer_add(device, input); break; @@ -123,6 +151,7 @@ struct roots_input *input_create(struct roots_server *server, wl_list_init(&input->pointers); wl_list_init(&input->touch); wl_list_init(&input->tablet_tools); + wl_list_init(&input->seats); input->input_add.notify = input_add_notify; wl_signal_add(&server->backend->events.input_add, &input->input_add); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ece95245..0865f551 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -10,6 +10,7 @@ #include #include #include "rootston/input.h" +#include "rootston/seat.h" #include "rootston/keyboard.h" static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, @@ -85,8 +86,8 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, } if (keysym == XKB_KEY_Escape) { - wlr_seat_pointer_end_grab(keyboard->input->wl_seat); - wlr_seat_keyboard_end_grab(keyboard->input->wl_seat); + wlr_seat_pointer_end_grab(keyboard->seat->seat); + wlr_seat_keyboard_end_grab(keyboard->seat->seat); } uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); @@ -141,20 +142,15 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } if (!handled) { - wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); - wlr_seat_keyboard_notify_key(keyboard->input->wl_seat, event->time_msec, + wlr_seat_set_keyboard(keyboard->seat->seat, keyboard->device); + wlr_seat_keyboard_notify_key(keyboard->seat->seat, event->time_msec, event->keycode, event->state); } } -static void handle_keyboard_key(struct wl_listener *listener, void *data) { - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); - struct wlr_event_keyboard_key *event = data; - roots_keyboard_handle_key(keyboard, event); -} - -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { - struct wlr_seat *seat = r_keyboard->input->wl_seat; +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, + struct wlr_event_keyboard_modifiers *event) { + struct wlr_seat *seat = r_keyboard->seat->seat; struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat, @@ -164,12 +160,6 @@ void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { keyboard->modifiers.group); } -static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); - roots_keyboard_handle_modifiers(r_keyboard); -} - static void keyboard_config_merge(struct keyboard_config *config, struct keyboard_config *fallback) { if (fallback == NULL) { @@ -192,7 +182,8 @@ static void keyboard_config_merge(struct keyboard_config *config, } } -struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input) { +struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, + struct roots_input *input) { struct roots_keyboard *keyboard = calloc(sizeof(struct roots_keyboard), 1); if (keyboard == NULL) { return NULL; @@ -201,12 +192,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st keyboard->device = device; keyboard->input = input; - keyboard->key.notify = handle_keyboard_key; - wl_signal_add(&device->keyboard->events.key, &keyboard->key); - - keyboard->modifiers.notify = handle_keyboard_modifiers; - wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); - + // XXX temporary wl_list_insert(&input->keyboards, &keyboard->link); struct keyboard_config config; @@ -244,8 +230,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, st void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; - wl_list_remove(&keyboard->key.link); - wl_list_remove(&keyboard->modifiers.link); wl_list_remove(&keyboard->link); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index d84422d8..0367e43f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -8,6 +8,7 @@ sources = [ 'main.c', 'output.c', 'pointer.c', + 'seat.c', 'tablet_tool.c', 'touch.c', 'xcursor.c', diff --git a/rootston/seat.c b/rootston/seat.c new file mode 100644 index 00000000..2103e0d2 --- /dev/null +++ b/rootston/seat.c @@ -0,0 +1,66 @@ +#include +#include + +#include "rootston/input.h" +#include "rootston/seat.h" +#include "rootston/keyboard.h" + +static void handle_keyboard_key(struct wl_listener *listener, void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_key); + struct wlr_event_keyboard_key *event = data; + roots_keyboard_handle_key(keyboard, event); +} + +static void handle_keyboard_modifiers(struct wl_listener *listener, + void *data) { + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, keyboard_modifiers); + struct wlr_event_keyboard_modifiers *event = data; + roots_keyboard_handle_modifiers(keyboard, event); +} + +struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { + struct roots_seat *seat = calloc(1, sizeof(struct roots_seat)); + if (!seat) { + return NULL; + } + + seat->seat = wlr_seat_create(input->server->wl_display, name); + wlr_seat_set_capabilities(seat->seat, + WL_SEAT_CAPABILITY_KEYBOARD | + WL_SEAT_CAPABILITY_POINTER | + WL_SEAT_CAPABILITY_TOUCH); + seat->input = input; + wl_list_insert(&input->seats, &seat->link); + wl_list_init(&seat->keyboards); + + return seat; +} + +void roots_seat_destroy(struct roots_seat *seat) { + // TODO +} + +void roots_seat_add_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + if (keyboard->seat) { + roots_seat_remove_keyboard(keyboard->seat, keyboard); + } + keyboard->seat = seat; + wl_list_insert(&seat->keyboards, &keyboard->seat_link); + + keyboard->keyboard_key.notify = handle_keyboard_key; + wl_signal_add(&keyboard->device->keyboard->events.key, + &keyboard->keyboard_key); + + keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; + wl_signal_add(&keyboard->device->keyboard->events.modifiers, + &keyboard->keyboard_modifiers); +} + +void roots_seat_remove_keyboard(struct roots_seat *seat, + struct roots_keyboard *keyboard) { + // TODO +} + diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c27264ef..c2fd9e0c 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,19 +41,18 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; - - wl_signal_emit(&keyboard->events.modifiers, keyboard); } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { + struct wlr_event_keyboard_modifiers *event) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, - mods_locked, 0, 0, group); + xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, + event->mods_latched, event->mods_locked, 0, 0, event->group); keyboard_modifier_update(keyboard); + + wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, -- cgit v1.2.3 From 2f6cfe4057fbef41977159e24fea0d19fbeeb052 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 4 Nov 2017 11:47:34 -0400 Subject: Fix software cursors on scaled outputs There was an issue where it would only work within the boundaries of the unscaled resolution. --- backend/wayland/output.c | 2 +- types/wlr_output.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 90f8b39a..c4301617 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -249,7 +249,7 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) { wlr_output_init(&output->wlr_output, &backend->backend, &output_impl); struct wlr_output *wlr_output = &output->wlr_output; - wlr_output_update_size(wlr_output, 640, 480); + wlr_output_update_size(wlr_output, 1280, 720); strncpy(wlr_output->make, "wayland", sizeof(wlr_output->make)); strncpy(wlr_output->model, "wayland", sizeof(wlr_output->model)); snprintf(wlr_output->name, sizeof(wlr_output->name), "WL-%d", diff --git a/types/wlr_output.c b/types/wlr_output.c index 3ad69ce3..df02afec 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -270,6 +270,8 @@ static void output_cursor_render(struct wlr_output_cursor *cursor) { output_box.x = output_box.y = 0; wlr_output_effective_resolution(cursor->output, &output_box.width, &output_box.height); + output_box.width *= cursor->output->scale; + output_box.height *= cursor->output->scale; struct wlr_box cursor_box; output_cursor_get_box(cursor, &cursor_box); @@ -476,7 +478,6 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, double x, double y) { x *= cursor->output->scale; y *= cursor->output->scale; - wlr_log(L_DEBUG, "Moving cursor to %f,%f", x, y); cursor->x = x; cursor->y = y; -- cgit v1.2.3 From 704f0f158a669689b78311cde35a736057f983b4 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 4 Nov 2017 13:12:35 -0400 Subject: rootston: move device init to seat --- include/rootston/pointer.h | 16 --- include/rootston/seat.h | 54 ++++++++- include/rootston/tablet_tool.h | 20 ---- include/rootston/touch.h | 22 ---- rootston/cursor.c | 4 +- rootston/input.c | 44 ++------ rootston/meson.build | 3 - rootston/pointer.c | 24 ---- rootston/seat.c | 241 +++++++++++++++++++++++++++++++++++++++-- rootston/tablet_tool.c | 25 ----- rootston/touch.c | 27 ----- 11 files changed, 292 insertions(+), 188 deletions(-) delete mode 100644 include/rootston/pointer.h delete mode 100644 include/rootston/tablet_tool.h delete mode 100644 include/rootston/touch.h delete mode 100644 rootston/pointer.c delete mode 100644 rootston/tablet_tool.c delete mode 100644 rootston/touch.c diff --git a/include/rootston/pointer.h b/include/rootston/pointer.h deleted file mode 100644 index b3fc8c3a..00000000 --- a/include/rootston/pointer.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _ROOTSTON_POINTER_H -#define _ROOTSTON_POINTER_H - -#include -#include - -struct roots_pointer { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -void pointer_add(struct wlr_input_device *device, struct roots_input *input); -void pointer_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h index f6db63cc..e4130e5a 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -9,7 +9,53 @@ struct roots_seat { struct roots_input *input; struct wlr_seat *seat; + struct wlr_cursor *cursor; + struct wl_list link; + struct wl_list keyboards; + struct wl_list pointers; + struct wl_list touch; + struct wl_list tablet_tools; + + struct wl_listener cursor_motion; + struct wl_listener cursor_motion_absolute; + struct wl_listener cursor_button; + struct wl_listener cursor_axis; + + struct wl_listener cursor_touch_down; + struct wl_listener cursor_touch_up; + struct wl_listener cursor_touch_motion; + + struct wl_listener cursor_tool_axis; + struct wl_listener cursor_tool_tip; +}; + +struct roots_pointer { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_list link; +}; + +struct roots_touch_point { + struct roots_touch *device; + int32_t slot; + double x, y; + struct wl_list link; +}; + +struct roots_tablet_tool { + struct roots_seat *seat; + struct wlr_input_device *device; + struct wl_listener axis; + struct wl_listener proximity; + struct wl_listener tip; + struct wl_listener button; struct wl_list link; }; @@ -17,10 +63,10 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name); void roots_seat_destroy(struct roots_seat *seat); -void roots_seat_add_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard); +void roots_seat_add_device(struct roots_seat *seat, + struct wlr_input_device *device); -void roots_seat_remove_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard); +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device); #endif diff --git a/include/rootston/tablet_tool.h b/include/rootston/tablet_tool.h deleted file mode 100644 index 72ebf6d8..00000000 --- a/include/rootston/tablet_tool.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _ROOTSTON_TABLET_TOOL_H -#define _ROOTSTON_TABLET_TOOL_H - -#include -#include "rootston/input.h" - -struct roots_tablet_tool { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_listener axis; - struct wl_listener proximity; - struct wl_listener tip; - struct wl_listener button; - struct wl_list link; -}; - -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input); -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/include/rootston/touch.h b/include/rootston/touch.h deleted file mode 100644 index 1624c3ad..00000000 --- a/include/rootston/touch.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _ROOTSTON_TOUCH_H -#define _ROOTSTON_TOUCH_H - -#include - -struct roots_touch { - struct roots_input *input; - struct wlr_input_device *device; - struct wl_list link; -}; - -struct roots_touch_point { - struct roots_touch *device; - int32_t slot; - double x, y; - struct wl_list link; -}; - -void touch_add(struct wlr_input_device *device, struct roots_input *input); -void touch_remove(struct wlr_input_device *device, struct roots_input *input); - -#endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 61dcae7a..9028c5bb 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -19,9 +19,7 @@ #include "rootston/desktop.h" #include "rootston/view.h" #include "rootston/keyboard.h" -#include "rootston/pointer.h" -#include "rootston/tablet_tool.h" -#include "rootston/touch.h" +#include "rootston/seat.h" const struct roots_input_event *get_input_event(struct roots_input *input, uint32_t serial) { diff --git a/rootston/input.c b/rootston/input.c index 51a64720..4a567763 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -8,10 +8,7 @@ #include "rootston/server.h" #include "rootston/config.h" #include "rootston/input.h" -#include "rootston/tablet_tool.h" #include "rootston/keyboard.h" -#include "rootston/pointer.h" -#include "rootston/touch.h" #include "rootston/seat.h" static const char *device_type(enum wlr_input_device_type type) { @@ -60,44 +57,17 @@ static void input_add_notify(struct wl_listener *listener, void *data) { wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, device->vendor, device->product, device_type(device->type)); - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: { - struct roots_keyboard *keyboard = roots_keyboard_create(device, input); - roots_seat_add_keyboard(seat, keyboard); - break; - } - case WLR_INPUT_DEVICE_POINTER: - pointer_add(device, input); - break; - case WLR_INPUT_DEVICE_TOUCH: - touch_add(device, input); - break; - case WLR_INPUT_DEVICE_TABLET_TOOL: - tablet_tool_add(device, input); - break; - default: - break; - } + + roots_seat_add_device(seat, device); } static void input_remove_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; - struct roots_input *input = wl_container_of(listener, input, input_remove); - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - roots_keyboard_destroy(device, input); - break; - case WLR_INPUT_DEVICE_POINTER: - pointer_remove(device, input); - break; - case WLR_INPUT_DEVICE_TOUCH: - touch_remove(device, input); - break; - case WLR_INPUT_DEVICE_TABLET_TOOL: - tablet_tool_remove(device, input); - break; - default: - break; + struct roots_input *input = wl_container_of(listener, input, input_add); + + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_remove_device(seat, device); } } diff --git a/rootston/meson.build b/rootston/meson.build index 0367e43f..9c543c4f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -7,10 +7,7 @@ sources = [ 'keyboard.c', 'main.c', 'output.c', - 'pointer.c', 'seat.c', - 'tablet_tool.c', - 'touch.c', 'xcursor.c', 'xdg_shell_v6.c', 'wl_shell.c', diff --git a/rootston/pointer.c b/rootston/pointer.c deleted file mode 100644 index cb099264..00000000 --- a/rootston/pointer.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/pointer.h" - -void pointer_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); - device->data = pointer; - pointer->device = device; - pointer->input = input; - wl_list_insert(&input->pointers, &pointer->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void pointer_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_pointer *pointer = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&pointer->link); - free(pointer); -} diff --git a/rootston/seat.c b/rootston/seat.c index 2103e0d2..c8f689bc 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,5 +1,8 @@ #include #include +#include + +#include #include "rootston/input.h" #include "rootston/seat.h" @@ -20,18 +23,175 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, roots_keyboard_handle_modifiers(keyboard, event); } +static void handle_cursor_motion(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_button(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_cursor_axis(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_down(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_up(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_touch_motion(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_tool_axis(struct wl_listener *listener, void *data) { + // TODO +} + +static void handle_tool_tip(struct wl_listener *listener, void *data) { + // TODO +} + +static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { + struct wlr_cursor *cursor = seat->cursor; + struct roots_config *config = seat->input->config; + + wlr_cursor_map_input_to_output(cursor, device, NULL); + struct device_config *dconfig; + if ((dconfig = config_get_device(config, device))) { + wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); + } +} + +static void seat_set_device_output_mappings(struct roots_seat *seat, + struct wlr_input_device *device, struct wlr_output *output) { + struct wlr_cursor *cursor = seat->cursor; + struct roots_config *config = seat->input->config; + struct device_config *dconfig; + dconfig = config_get_device(config, device); + if (dconfig && dconfig->mapped_output && + strcmp(dconfig->mapped_output, output->name) == 0) { + wlr_cursor_map_input_to_output(cursor, device, output); + } +} + +static void roots_seat_configure_cursor(struct roots_seat *seat) { + struct roots_config *config = seat->input->config; + struct roots_desktop *desktop = seat->input->server->desktop; + struct wlr_cursor *cursor = seat->cursor; + + struct roots_pointer *pointer; + struct roots_touch *touch; + struct roots_tablet_tool *tablet_tool; + struct roots_output *output; + + // reset mappings + wlr_cursor_map_to_output(cursor, NULL); + wl_list_for_each(pointer, &seat->pointers, link) { + seat_reset_device_mappings(seat, pointer->device); + } + wl_list_for_each(touch, &seat->touch, link) { + seat_reset_device_mappings(seat, touch->device); + } + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + seat_reset_device_mappings(seat, tablet_tool->device); + } + + // configure device to output mappings + const char *mapped_output = config->cursor.mapped_output; + wl_list_for_each(output, &desktop->outputs, link) { + if (mapped_output && strcmp(mapped_output, output->wlr_output->name) == 0) { + wlr_cursor_map_to_output(cursor, output->wlr_output); + } + + wl_list_for_each(pointer, &seat->pointers, link) { + seat_set_device_output_mappings(seat, pointer->device, output->wlr_output); + } + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + seat_set_device_output_mappings(seat, tablet_tool->device, output->wlr_output); + } + wl_list_for_each(touch, &seat->touch, link) { + seat_set_device_output_mappings(seat, touch->device, output->wlr_output); + } + } +} + +static void roots_seat_init_cursor(struct roots_seat *seat) { + struct wlr_cursor *cursor = wlr_cursor_create(); + if (!cursor) { + return; + } + seat->cursor = cursor; + + // add output layout and configure + struct roots_desktop *desktop = seat->input->server->desktop; + wlr_cursor_attach_output_layout(cursor, desktop->layout); + roots_seat_configure_cursor(seat); + // TODO configure cursor by seat + + // add input signals + wl_signal_add(&cursor->events.motion, &seat->cursor_motion); + seat->cursor_motion.notify = handle_cursor_motion; + + wl_signal_add(&cursor->events.motion_absolute, + &seat->cursor_motion_absolute); + seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; + + wl_signal_add(&cursor->events.button, &seat->cursor_button); + seat->cursor_button.notify = handle_cursor_button; + + wl_signal_add(&cursor->events.axis, &seat->cursor_axis); + seat->cursor_axis.notify = handle_cursor_axis; + + wl_signal_add(&cursor->events.touch_down, &seat->cursor_touch_down); + seat->cursor_touch_down.notify = handle_touch_down; + + wl_signal_add(&cursor->events.touch_up, &seat->cursor_touch_up); + seat->cursor_touch_up.notify = handle_touch_up; + + wl_signal_add(&cursor->events.touch_motion, &seat->cursor_touch_motion); + seat->cursor_touch_motion.notify = handle_touch_motion; + + wl_signal_add(&cursor->events.tablet_tool_axis, &seat->cursor_tool_axis); + seat->cursor_tool_axis.notify = handle_tool_axis; + + wl_signal_add(&cursor->events.tablet_tool_tip, &seat->cursor_tool_tip); + seat->cursor_tool_tip.notify = handle_tool_tip; +} + struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { struct roots_seat *seat = calloc(1, sizeof(struct roots_seat)); if (!seat) { return NULL; } + roots_seat_init_cursor(seat); + if (!seat->cursor) { + free(seat); + return NULL; + } + seat->seat = wlr_seat_create(input->server->wl_display, name); + if (!seat->seat) { + free(seat); + wlr_cursor_destroy(seat->cursor); + return NULL; + } + wlr_seat_set_capabilities(seat->seat, WL_SEAT_CAPABILITY_KEYBOARD | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); + seat->input = input; + wl_list_insert(&input->seats, &seat->link); wl_list_init(&seat->keyboards); @@ -42,12 +202,10 @@ void roots_seat_destroy(struct roots_seat *seat) { // TODO } -void roots_seat_add_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard) { - if (keyboard->seat) { - roots_seat_remove_keyboard(keyboard->seat, keyboard); - } +static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; + wl_list_insert(&seat->keyboards, &keyboard->seat_link); keyboard->keyboard_key.notify = handle_keyboard_key; @@ -59,8 +217,77 @@ void roots_seat_add_keyboard(struct roots_seat *seat, &keyboard->keyboard_modifiers); } -void roots_seat_remove_keyboard(struct roots_seat *seat, - struct roots_keyboard *keyboard) { +static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_pointer *pointer = calloc(sizeof(struct roots_pointer), 1); + if (!pointer) { + wlr_log(L_ERROR, "could not allocate pointer for seat"); + return; + } + + device->data = pointer; + pointer->device = device; + pointer->seat = seat; + wl_list_insert(&seat->pointers, &pointer->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1); + if (!touch) { + wlr_log(L_ERROR, "could not allocate touch for seat"); + return; + } + + device->data = touch; + touch->device = device; + touch->seat = seat; + wl_list_insert(&seat->touch, &touch->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +static void seat_add_tablet_pad(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } +static void seat_add_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { + struct roots_tablet_tool *tablet_tool = calloc(sizeof(struct roots_tablet_tool), 1); + if (!tablet_tool) { + wlr_log(L_ERROR, "could not allocate tablet_tool for seat"); + return; + } + + device->data = tablet_tool; + tablet_tool->device = device; + tablet_tool->seat = seat; + wl_list_insert(&seat->tablet_tools, &tablet_tool->link); + wlr_cursor_attach_input_device(seat->cursor, device); + roots_seat_configure_cursor(seat); +} + +void roots_seat_add_device(struct roots_seat *seat, + struct wlr_input_device *device) { + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + seat_add_keyboard(seat, device); + break; + case WLR_INPUT_DEVICE_POINTER: + seat_add_pointer(seat, device); + break; + case WLR_INPUT_DEVICE_TOUCH: + seat_add_touch(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_PAD: + seat_add_tablet_pad(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_TOOL: + seat_add_tablet_tool(seat, device); + break; + } +} + +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} diff --git a/rootston/tablet_tool.c b/rootston/tablet_tool.c deleted file mode 100644 index 3327115d..00000000 --- a/rootston/tablet_tool.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/tablet_tool.h" - -void tablet_tool_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_tablet_tool *tool = calloc(sizeof(struct roots_tablet_tool), 1); - device->data = tool; - tool->device = device; - tool->input = input; - wl_list_insert(&input->tablet_tools, &tool->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void tablet_tool_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_tablet_tool *tablet_tool = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&tablet_tool->link); - free(tablet_tool); -} diff --git a/rootston/touch.c b/rootston/touch.c deleted file mode 100644 index 069853ab..00000000 --- a/rootston/touch.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include -#include "rootston/input.h" -#include "rootston/touch.h" - -// TODO: we'll likely want touch events to both control the cursor *and* be -// submitted directly to the seat. - -void touch_add(struct wlr_input_device *device, struct roots_input *input) { - struct roots_touch *touch = calloc(sizeof(struct roots_touch), 1); - device->data = touch; - touch->device = device; - touch->input = input; - wl_list_insert(&input->touch, &touch->link); - wlr_cursor_attach_input_device(input->cursor, device); - cursor_load_config(input->server->config, input->cursor, - input, input->server->desktop); -} - -void touch_remove(struct wlr_input_device *device, struct roots_input *input) { - struct roots_touch *touch = device->data; - wlr_cursor_detach_input_device(input->cursor, device); - wl_list_remove(&touch->link); - free(touch); -} -- cgit v1.2.3 From 1cee782fec090a19a390aec96e88475303dacafc Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 5 Nov 2017 13:00:27 +0100 Subject: Fix pointer axis delta in Wayland backend --- backend/wayland/wl_seat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index deed215e..a2da8df5 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -90,7 +90,7 @@ static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, struct wlr_event_pointer_axis wlr_event; wlr_event.device = dev; - wlr_event.delta = value; + wlr_event.delta = wl_fixed_to_double(value); wlr_event.orientation = axis; wlr_event.time_msec = time; wlr_event.source = wlr_wl_pointer->axis_source; -- cgit v1.2.3 From 2280928bb2859b8a5e71e81b99a396ff7a3f9efa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 5 Nov 2017 09:20:11 -0500 Subject: rootston: roots_cursor --- include/rootston/cursor.h | 54 +++++++++++++++++++++ include/rootston/seat.h | 14 +----- rootston/meson.build | 1 + rootston/roots_cursor.c | 65 +++++++++++++++++++++++++ rootston/seat.c | 118 ++++++++++++++++++++++++++++------------------ 5 files changed, 194 insertions(+), 58 deletions(-) create mode 100644 include/rootston/cursor.h create mode 100644 rootston/roots_cursor.c diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h new file mode 100644 index 00000000..8a8d33f2 --- /dev/null +++ b/include/rootston/cursor.h @@ -0,0 +1,54 @@ +#ifndef _ROOTSTON_CURSOR_H +#define _ROOTSTON_CURSOR_H + +#include "rootston/seat.h" + +struct roots_cursor { + struct roots_seat *seat; + struct wlr_cursor *cursor; + + struct wl_listener motion; + struct wl_listener motion_absolute; + struct wl_listener button; + struct wl_listener axis; + + struct wl_listener touch_down; + struct wl_listener touch_up; + struct wl_listener touch_motion; + + struct wl_listener tool_axis; + struct wl_listener tool_tip; +}; + +struct roots_cursor *roots_cursor_create(struct roots_seat *seat); + +void roots_cursor_destroy(struct roots_cursor *cursor); + +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event); + +void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, + struct wlr_event_pointer_motion_absolute *event); + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event); + +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event); + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event); + +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event); + +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event); + +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event); + +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event); + +#endif diff --git a/include/rootston/seat.h b/include/rootston/seat.h index e4130e5a..b7c8b477 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -9,25 +9,13 @@ struct roots_seat { struct roots_input *input; struct wlr_seat *seat; - struct wlr_cursor *cursor; + struct roots_cursor *cursor; struct wl_list link; struct wl_list keyboards; struct wl_list pointers; struct wl_list touch; struct wl_list tablet_tools; - - struct wl_listener cursor_motion; - struct wl_listener cursor_motion_absolute; - struct wl_listener cursor_button; - struct wl_listener cursor_axis; - - struct wl_listener cursor_touch_down; - struct wl_listener cursor_touch_up; - struct wl_listener cursor_touch_motion; - - struct wl_listener cursor_tool_axis; - struct wl_listener cursor_tool_tip; }; struct roots_pointer { diff --git a/rootston/meson.build b/rootston/meson.build index 9c543c4f..baed5330 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,6 +1,7 @@ sources = [ 'config.c', 'cursor.c', + 'roots_cursor.c', 'desktop.c', 'ini.c', 'input.c', diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c new file mode 100644 index 00000000..72eff996 --- /dev/null +++ b/rootston/roots_cursor.c @@ -0,0 +1,65 @@ +#include +#include +#include "rootston/cursor.h" + +struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { + struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); + if (!cursor) { + return NULL; + } + cursor->cursor = wlr_cursor_create(); + if (!cursor->cursor) { + return NULL; + } + + return cursor; +} + +void roots_cursor_destroy(struct roots_cursor *cursor) { + // TODO +} + +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event) { + wlr_log(L_DEBUG, "TODO: cursor handle motion"); +} + +void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, + struct wlr_event_pointer_motion_absolute *event) { + wlr_log(L_DEBUG, "TODO: cursor handle motion absolute"); +} + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event) { + wlr_log(L_DEBUG, "TODO: cursor handle button"); +} + +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event) { + wlr_log(L_DEBUG, "TODO: cursor handle axis"); +} + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch down"); +} + +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch up"); +} + +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event) { + wlr_log(L_DEBUG, "TODO: cursor handle touch motion"); +} + +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event) { + wlr_log(L_DEBUG, "TODO: cursor handle tool axis"); +} + +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event) { + wlr_log(L_DEBUG, "TODO: cursor handle tool tip"); +} diff --git a/rootston/seat.c b/rootston/seat.c index c8f689bc..957843ec 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -7,6 +7,7 @@ #include "rootston/input.h" #include "rootston/seat.h" #include "rootston/keyboard.h" +#include "rootston/cursor.h" static void handle_keyboard_key(struct wl_listener *listener, void *data) { struct roots_keyboard *keyboard = @@ -24,43 +25,70 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, } static void handle_cursor_motion(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, motion); + struct wlr_event_pointer_motion *event = data; + roots_cursor_handle_motion(cursor, event); } static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, motion_absolute); + struct wlr_event_pointer_motion_absolute *event = data; + roots_cursor_handle_motion_absolute(cursor, event); } static void handle_cursor_button(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, button); + struct wlr_event_pointer_button *event = data; + roots_cursor_handle_button(cursor, event); } static void handle_cursor_axis(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, axis); + struct wlr_event_pointer_axis *event = data; + roots_cursor_handle_axis(cursor, event); } static void handle_touch_down(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_down); + struct wlr_event_touch_down *event = data; + roots_cursor_handle_touch_down(cursor, event); } static void handle_touch_up(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_up); + struct wlr_event_touch_up *event = data; + roots_cursor_handle_touch_up(cursor, event); } static void handle_touch_motion(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, touch_motion); + struct wlr_event_touch_motion *event = data; + roots_cursor_handle_touch_motion(cursor, event); } static void handle_tool_axis(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, tool_axis); + struct wlr_event_tablet_tool_axis *event = data; + roots_cursor_handle_tool_axis(cursor, event); } static void handle_tool_tip(struct wl_listener *listener, void *data) { - // TODO + struct roots_cursor *cursor = + wl_container_of(listener, cursor, tool_tip); + struct wlr_event_tablet_tool_tip *event = data; + roots_cursor_handle_tool_tip(cursor, event); } static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; wlr_cursor_map_input_to_output(cursor, device, NULL); @@ -72,7 +100,7 @@ static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input static void seat_set_device_output_mappings(struct roots_seat *seat, struct wlr_input_device *device, struct wlr_output *output) { - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; struct device_config *dconfig; dconfig = config_get_device(config, device); @@ -85,7 +113,7 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, static void roots_seat_configure_cursor(struct roots_seat *seat) { struct roots_config *config = seat->input->config; struct roots_desktop *desktop = seat->input->server->desktop; - struct wlr_cursor *cursor = seat->cursor; + struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_pointer *pointer; struct roots_touch *touch; @@ -124,46 +152,42 @@ static void roots_seat_configure_cursor(struct roots_seat *seat) { } static void roots_seat_init_cursor(struct roots_seat *seat) { - struct wlr_cursor *cursor = wlr_cursor_create(); - if (!cursor) { + seat->cursor = roots_cursor_create(seat); + if (!seat->cursor) { return; } - seat->cursor = cursor; - - // add output layout and configure + struct wlr_cursor *wlr_cursor = seat->cursor->cursor; struct roots_desktop *desktop = seat->input->server->desktop; - wlr_cursor_attach_output_layout(cursor, desktop->layout); - roots_seat_configure_cursor(seat); - // TODO configure cursor by seat + wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); // add input signals - wl_signal_add(&cursor->events.motion, &seat->cursor_motion); - seat->cursor_motion.notify = handle_cursor_motion; + wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); + seat->cursor->motion.notify = handle_cursor_motion; - wl_signal_add(&cursor->events.motion_absolute, - &seat->cursor_motion_absolute); - seat->cursor_motion_absolute.notify = handle_cursor_motion_absolute; + wl_signal_add(&wlr_cursor->events.motion_absolute, + &seat->cursor->motion_absolute); + seat->cursor->motion_absolute.notify = handle_cursor_motion_absolute; - wl_signal_add(&cursor->events.button, &seat->cursor_button); - seat->cursor_button.notify = handle_cursor_button; + wl_signal_add(&wlr_cursor->events.button, &seat->cursor->button); + seat->cursor->button.notify = handle_cursor_button; - wl_signal_add(&cursor->events.axis, &seat->cursor_axis); - seat->cursor_axis.notify = handle_cursor_axis; + wl_signal_add(&wlr_cursor->events.axis, &seat->cursor->axis); + seat->cursor->axis.notify = handle_cursor_axis; - wl_signal_add(&cursor->events.touch_down, &seat->cursor_touch_down); - seat->cursor_touch_down.notify = handle_touch_down; + wl_signal_add(&wlr_cursor->events.touch_down, &seat->cursor->touch_down); + seat->cursor->touch_down.notify = handle_touch_down; - wl_signal_add(&cursor->events.touch_up, &seat->cursor_touch_up); - seat->cursor_touch_up.notify = handle_touch_up; + wl_signal_add(&wlr_cursor->events.touch_up, &seat->cursor->touch_up); + seat->cursor->touch_up.notify = handle_touch_up; - wl_signal_add(&cursor->events.touch_motion, &seat->cursor_touch_motion); - seat->cursor_touch_motion.notify = handle_touch_motion; + wl_signal_add(&wlr_cursor->events.touch_motion, &seat->cursor->touch_motion); + seat->cursor->touch_motion.notify = handle_touch_motion; - wl_signal_add(&cursor->events.tablet_tool_axis, &seat->cursor_tool_axis); - seat->cursor_tool_axis.notify = handle_tool_axis; + wl_signal_add(&wlr_cursor->events.tablet_tool_axis, &seat->cursor->tool_axis); + seat->cursor->tool_axis.notify = handle_tool_axis; - wl_signal_add(&cursor->events.tablet_tool_tip, &seat->cursor_tool_tip); - seat->cursor_tool_tip.notify = handle_tool_tip; + wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip); + seat->cursor->tool_tip.notify = handle_tool_tip; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { @@ -172,6 +196,8 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { return NULL; } + seat->input = input; + roots_seat_init_cursor(seat); if (!seat->cursor) { free(seat); @@ -181,7 +207,7 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->seat = wlr_seat_create(input->server->wl_display, name); if (!seat->seat) { free(seat); - wlr_cursor_destroy(seat->cursor); + roots_cursor_destroy(seat->cursor); return NULL; } @@ -190,10 +216,12 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - seat->input = input; - wl_list_insert(&input->seats, &seat->link); + wl_list_init(&seat->keyboards); + wl_list_init(&seat->pointers); + wl_list_init(&seat->touch); + wl_list_init(&seat->tablet_tools); return seat; } @@ -228,7 +256,7 @@ static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *d pointer->device = device; pointer->seat = seat; wl_list_insert(&seat->pointers, &pointer->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } @@ -243,7 +271,7 @@ static void seat_add_touch(struct roots_seat *seat, struct wlr_input_device *dev touch->device = device; touch->seat = seat; wl_list_insert(&seat->touch, &touch->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } @@ -262,7 +290,7 @@ static void seat_add_tablet_tool(struct roots_seat *seat, struct wlr_input_devic tablet_tool->device = device; tablet_tool->seat = seat; wl_list_insert(&seat->tablet_tools, &tablet_tool->link); - wlr_cursor_attach_input_device(seat->cursor, device); + wlr_cursor_attach_input_device(seat->cursor->cursor, device); roots_seat_configure_cursor(seat); } -- cgit v1.2.3 From 03d3fdc15879c6fbdd24d5fe1d60f9a77402220d Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 5 Nov 2017 16:29:43 +0100 Subject: Basic maximization implementation for xdg-shell --- include/rootston/view.h | 12 ++++++++++++ rootston/cursor.c | 9 ++++++++- rootston/desktop.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ rootston/xdg_shell_v6.c | 24 +++++++++++++++++++++++- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 0913b42e..67643b94 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -48,8 +48,17 @@ enum roots_view_type { struct roots_view { struct roots_desktop *desktop; + double x, y; float rotation; + + bool maximized; + struct { + double x, y; + uint32_t width, height; + float rotation; + } saved; + // TODO: Something for roots-enforced width/height enum roots_view_type type; union { @@ -67,6 +76,7 @@ struct roots_view { #endif }; struct wlr_surface *wlr_surface; + // TODO: This would probably be better as a field that's updated on a // configure event from the xdg_shell // If not then this should follow the typical type/impl pattern we use @@ -77,6 +87,7 @@ struct roots_view { void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); void (*move_resize)(struct roots_view *view, double x, double y, uint32_t width, uint32_t height); + void (*maximize)(struct roots_view *view, bool maximized); void (*close)(struct roots_view *view); }; @@ -86,6 +97,7 @@ void view_move(struct roots_view *view, double x, double y); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height); +void view_maximize(struct roots_view *view, bool maximized); void view_close(struct roots_view *view); bool view_center(struct roots_view *view); void view_setup(struct roots_view *view); diff --git a/rootston/cursor.c b/rootston/cursor.c index b153e8c8..d97d518e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -39,6 +39,8 @@ static void cursor_set_xcursor_image(struct roots_input *input, void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view) { + view_maximize(view, false); + input->mode = ROOTS_CURSOR_MOVE; input->offs_x = cursor->x; input->offs_y = cursor->y; @@ -54,6 +56,8 @@ void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view, uint32_t edges) { + view_maximize(view, false); + input->mode = ROOTS_CURSOR_RESIZE; input->offs_x = cursor->x; input->offs_y = cursor->y; @@ -74,6 +78,8 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, void view_begin_rotate(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view) { + view_maximize(view, false); + input->mode = ROOTS_CURSOR_ROTATE; input->offs_x = cursor->x; input->offs_y = cursor->y; @@ -102,7 +108,8 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { set_compositor_cursor = view_client != input->cursor_client; } if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); + struct wlr_xcursor *xcursor = + get_default_xcursor(input->xcursor_theme); cursor_set_xcursor_image(input, xcursor->images[0]); input->cursor_client = NULL; } diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..f5d5925b 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -78,6 +78,50 @@ void view_move_resize(struct roots_view *view, double x, double y, view_resize(view, width, height); } +void view_maximize(struct roots_view *view, bool maximized) { + if (view->maximized == maximized) { + return; + } + + if (view->maximize) { + view->maximize(view, maximized); + } + + if (!view->maximized && maximized) { + struct wlr_box view_box; + view_get_size(view, &view_box); + + view->maximized = true; + view->saved.x = view->x; + view->saved.y = view->y; + view->saved.rotation = view->rotation; + view->saved.width = view_box.width; + view->saved.height = view_box.height; + + double output_x, output_y; + wlr_output_layout_closest_point(view->desktop->layout, NULL, + view->x + (double)view_box.width/2, + view->y + (double)view_box.height/2, + &output_x, &output_y); + struct wlr_output *output = wlr_output_layout_output_at( + view->desktop->layout, output_x, output_y); + struct wlr_box *output_box = + wlr_output_layout_get_box(view->desktop->layout, output); + + view_move_resize(view, output_box->x, output_box->y, output_box->width, + output_box->height); + view->rotation = 0; + } + + if (view->maximized && !maximized) { + view->maximized = false; + + view_move_resize(view, view->saved.x, view->saved.y, view->saved.width, + view->saved.height); + view->rotation = view->saved.rotation; + } +} + void view_close(struct roots_view *view) { if (view->close) { view->close(view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca33c582..45691d16 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -84,6 +84,16 @@ static void move_resize(struct roots_view *view, double x, double y, wlr_xdg_toplevel_v6_set_size(surf, contrained_width, contrained_height); } +static void maximize(struct roots_view *view, bool maximized) { + assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + return; + } + + wlr_xdg_toplevel_v6_set_maximized(surface, maximized); +} + static void close(struct roots_view *view) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; @@ -119,7 +129,18 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { } static void handle_commit(struct wl_listener *listener, void *data) { - // TODO is there anything we need to do here? + struct roots_xdg_surface_v6 *roots_xdg_surface = + wl_container_of(listener, roots_xdg_surface, commit); + struct roots_view *view = roots_xdg_surface->view; + struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + + if (surface->role != WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { + return; + } + + if (view->maximized != surface->toplevel_state->current.maximized) { + view_maximize(view, surface->toplevel_state->current.maximized); + } } static void handle_destroy(struct wl_listener *listener, void *data) { @@ -178,6 +199,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { view->activate = activate; view->resize = resize; view->move_resize = move_resize; + view->maximize = maximize; view->close = close; view->desktop = desktop; roots_surface->view = view; -- cgit v1.2.3 From c88990d2c2c66835f9098dc642b6d679529a84a8 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Tue, 7 Nov 2017 12:32:55 +0100 Subject: fix the keybind handling in rootston. As mentioned in https://github.com/swaywm/wlroots/issues/393 keybinds did't trigger / were checked with "odd" keys and modifiers. This commit sends the keycode through two paths, one to get the keycode and modifiers *after* xkb handles them, a secondary path to get a "raw" keysym without modifiers and then add the modifiers rootston knows about. This will result in the `[Alt]+[Shift]+2` combination I mention earlier going through the keybind detection twice. 1) `[Alt]+[at]` 2) `[Alt]+[Shift]+2` When either combination is found, the appropriate keybind is executed. The xkb handled version will be prefered over the "raw" version. --- rootston/keyboard.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index e174b731..6b1fde86 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -60,7 +60,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, * should be propagated to clients. */ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, - xkb_keysym_t keysym) { + xkb_keysym_t keysym, uint32_t modifiers) { ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); if (i < 0) { i = keyboard_pressed_keysym_index(keyboard, XKB_KEY_NoSymbol); @@ -88,7 +88,6 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, wlr_seat_keyboard_end_grab(keyboard->input->wl_seat); } - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); struct wl_list *bindings = &keyboard->input->server->config->bindings; struct binding_config *bc; wl_list_for_each(bc, bindings, link) { @@ -122,25 +121,70 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -static void keyboard_key_notify(struct wl_listener *listener, void *data) { - struct wlr_event_keyboard_key *event = data; - struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); +static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, + uint32_t keycode, enum wlr_key_state state) +{ + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + const xkb_keysym_t *syms; + xkb_layout_index_t layout_index = xkb_state_key_get_layout( + keyboard->device->keyboard->xkb_state, + keycode); + int syms_len = xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, + keycode, layout_index, 0, &syms); - uint32_t keycode = event->keycode + 8; + bool handled = false; + for (int i = 0; i < syms_len; i++) { + if (state) { + bool keysym_handled = keyboard_keysym_press(keyboard, + syms[i], modifiers); + handled = handled || keysym_handled; + } else { // WLR_KEY_RELEASED + keyboard_keysym_release(keyboard, syms[i]); + } + } + + return handled; +} + +static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, + uint32_t keycode, enum wlr_key_state state) +{ + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, keycode, &syms); + uint32_t consumed = xkb_state_key_get_consumed_mods2( + keyboard->device->keyboard->xkb_state, + keycode, + XKB_CONSUMED_MODE_XKB); + + modifiers = modifiers & ~consumed; bool handled = false; for (int i = 0; i < syms_len; i++) { - if (event->state == WLR_KEY_PRESSED) { - bool keysym_handled = keyboard_keysym_press(keyboard, syms[i]); + if (state) { + bool keysym_handled = keyboard_keysym_press(keyboard, + syms[i], modifiers); handled = handled || keysym_handled; } else { // WLR_KEY_RELEASED keyboard_keysym_release(keyboard, syms[i]); } } + return handled; +} + +static void keyboard_key_notify(struct wl_listener *listener, void *data) { + struct wlr_event_keyboard_key *event = data; + struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, key); + + uint32_t keycode = event->keycode + 8; + + bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); + + if (!handled) + handled |= keyboard_keysyms_simple(keyboard, keycode, event->state); + if (!handled) { wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); wlr_seat_keyboard_notify_key(keyboard->input->wl_seat, event->time_msec, -- cgit v1.2.3 From 8ca76ff7f27175e275cbebcc788a1e09ce831293 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Tue, 7 Nov 2017 12:55:19 +0100 Subject: explains 2 way keybind trying. --- rootston/keyboard.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6b1fde86..86f10374 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -121,14 +121,21 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } +/** + * Process keypresses from the keyboard as if modifiers didn't change keysyms. + * + * This avoids the xkb keysym translation based on modifiers considered pressed + * in the state and uses the list of modifiers saved on the rootston side. + * + * This will trigger the keybind: [Alt]+[Shift]+2 + */ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, uint32_t keycode, enum wlr_key_state state) { uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; xkb_layout_index_t layout_index = xkb_state_key_get_layout( - keyboard->device->keyboard->xkb_state, - keycode); + keyboard->device->keyboard->xkb_state, keycode); int syms_len = xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); @@ -146,6 +153,15 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, return handled; } +/** + * Process keypresses from the keyboard as xkb sees them. + * + * This uses the xkb keysyms translation based on pressed modifiers and clears + * the consumed modifiers from the list of modifiers passed to keybind + * detection. + * + * (On US layout) this will trigger: [Alt]+[at] + */ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, uint32_t keycode, enum wlr_key_state state) { @@ -154,9 +170,7 @@ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, keycode, &syms); uint32_t consumed = xkb_state_key_get_consumed_mods2( - keyboard->device->keyboard->xkb_state, - keycode, - XKB_CONSUMED_MODE_XKB); + keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); modifiers = modifiers & ~consumed; -- cgit v1.2.3 From 23991861a461acabafde3c8d63c4355320e67db3 Mon Sep 17 00:00:00 2001 From: Markus Ongyerth Date: Tue, 7 Nov 2017 16:50:34 +0100 Subject: works in review comments --- rootston/keyboard.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 86f10374..6c419df8 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -121,7 +121,7 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, } } -/** +/* * Process keypresses from the keyboard as if modifiers didn't change keysyms. * * This avoids the xkb keysym translation based on modifiers considered pressed @@ -130,8 +130,7 @@ static void keyboard_keysym_release(struct roots_keyboard *keyboard, * This will trigger the keybind: [Alt]+[Shift]+2 */ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) -{ + uint32_t keycode, enum wlr_key_state state) { uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; xkb_layout_index_t layout_index = xkb_state_key_get_layout( @@ -153,7 +152,7 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, return handled; } -/** +/* * Process keypresses from the keyboard as xkb sees them. * * This uses the xkb keysyms translation based on pressed modifiers and clears @@ -163,8 +162,7 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, * (On US layout) this will trigger: [Alt]+[at] */ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) -{ + uint32_t keycode, enum wlr_key_state state) { uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); const xkb_keysym_t *syms; int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, @@ -196,8 +194,10 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); - if (!handled) - handled |= keyboard_keysyms_simple(keyboard, keycode, event->state); + if (!handled) { + bool key_handled = keyboard_keysyms_simple(keyboard, keycode, event->state); + handled = handled || key_handled; + } if (!handled) { wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); -- cgit v1.2.3 From 09c60924235805d07b7915ba879685545a3442aa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 15:56:11 -0500 Subject: multiseat: somewhat working --- include/rootston/cursor.h | 35 +++++ include/rootston/input.h | 54 +------- include/rootston/keyboard.h | 1 + include/rootston/seat.h | 30 +++++ include/wlr/types/wlr_wl_shell.h | 4 +- include/wlr/types/wlr_xdg_shell_v6.h | 6 +- rootston/desktop.c | 36 +++--- rootston/input.c | 62 ++------- rootston/keyboard.c | 26 ++-- rootston/meson.build | 2 +- rootston/output.c | 32 ++--- rootston/roots_cursor.c | 239 +++++++++++++++++++++++++++++++++-- rootston/seat.c | 134 +++++++++++++++++++- rootston/wl_shell.c | 13 +- rootston/xdg_shell_v6.c | 14 +- rootston/xwayland.c | 32 ++--- types/wlr_wl_shell.c | 8 +- types/wlr_xdg_shell_v6.c | 12 +- 18 files changed, 521 insertions(+), 219 deletions(-) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 8a8d33f2..18d5f720 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -3,10 +3,45 @@ #include "rootston/seat.h" +enum roots_cursor_mode { + ROOTS_CURSOR_PASSTHROUGH = 0, + ROOTS_CURSOR_MOVE = 1, + ROOTS_CURSOR_RESIZE = 2, + ROOTS_CURSOR_ROTATE = 3, +}; + +enum roots_cursor_resize_edge { + ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, + ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, + ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, + ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, +}; + +struct roots_input_event { + uint32_t serial; + struct wlr_cursor *cursor; + struct wlr_input_device *device; +}; + struct roots_cursor { struct roots_seat *seat; struct wlr_cursor *cursor; + enum roots_cursor_mode mode; + + // state from input (review if this is necessary) + struct wlr_xcursor_theme *xcursor_theme; + struct wlr_seat *wl_seat; + struct wl_client *cursor_client; + int offs_x, offs_y; + int view_x, view_y, view_width, view_height; + float view_rotation; + uint32_t resize_edges; + // Ring buffer of input events that could trigger move/resize/rotate + int input_events_idx; + struct wl_list touch_points; + struct roots_input_event input_events[16]; + struct wl_listener motion; struct wl_listener motion_absolute; struct wl_listener button; diff --git a/include/rootston/input.h b/include/rootston/input.h index 7b1358f8..7463ba3a 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -5,64 +5,15 @@ #include #include #include +#include "rootston/cursor.h" #include "rootston/config.h" #include "rootston/view.h" #include "rootston/server.h" -enum roots_cursor_mode { - ROOTS_CURSOR_PASSTHROUGH = 0, - ROOTS_CURSOR_MOVE = 1, - ROOTS_CURSOR_RESIZE = 2, - ROOTS_CURSOR_ROTATE = 3, -}; - -enum roots_cursor_resize_edge { - ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, - ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, - ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, - ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, -}; - -struct roots_input_event { - uint32_t serial; - struct wlr_cursor *cursor; - struct wlr_input_device *device; -}; - -struct roots_drag_icon { - struct wlr_surface *surface; - struct wl_list link; // roots_input::drag_icons - bool mapped; - - int32_t sx; - int32_t sy; - - struct wl_listener surface_destroy; - struct wl_listener surface_commit; -}; - struct roots_input { struct roots_config *config; struct roots_server *server; - // TODO: multiseat, multicursor - struct wlr_cursor *cursor; - struct wlr_xcursor_theme *xcursor_theme; - struct wlr_seat *wl_seat; - struct wl_list drag_icons; - struct wl_client *cursor_client; - - enum roots_cursor_mode mode; - struct roots_view *active_view; - int offs_x, offs_y; - int view_x, view_y, view_width, view_height; - float view_rotation; - uint32_t resize_edges; - - // Ring buffer of input events that could trigger move/resize/rotate - int input_events_idx; - struct roots_input_event input_events[16]; - struct wl_list keyboards; struct wl_list pointers; struct wl_list touch; @@ -117,4 +68,7 @@ struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, struct roots_view *view); +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *seat); + #endif diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index cb639ba1..e3caf8fb 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -10,6 +10,7 @@ struct roots_keyboard { struct roots_input *input; struct roots_seat *seat; struct wlr_input_device *device; + struct keyboard_config *config; struct wl_list seat_link; // XXX temporary struct wl_list link; diff --git a/include/rootston/seat.h b/include/rootston/seat.h index b7c8b477..b5593651 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -6,11 +6,26 @@ #include "rootston/input.h" #include "rootston/keyboard.h" +struct roots_drag_icon { + struct wlr_surface *surface; + struct wl_list link; // roots_seat::drag_icons + bool mapped; + + int32_t sx; + int32_t sy; + + struct wl_listener surface_destroy; + struct wl_listener surface_commit; +}; + struct roots_seat { struct roots_input *input; struct wlr_seat *seat; struct roots_cursor *cursor; struct wl_list link; + struct wl_list drag_icons; + + struct roots_view *focus; struct wl_list keyboards; struct wl_list pointers; @@ -57,4 +72,19 @@ void roots_seat_add_device(struct roots_seat *seat, void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device); +void roots_seat_configure_cursor(struct roots_seat *seat); + +void roots_seat_configure_xcursor(struct roots_seat *seat); + +bool roots_seat_has_meta_pressed(struct roots_seat *seat); + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view); + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges); + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view); + #endif diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 4e814817..ab3b4b10 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -93,14 +93,14 @@ struct wlr_wl_shell_surface { struct wlr_wl_shell_surface_move_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_wl_shell_surface_resize_event { struct wl_client *client; struct wlr_wl_shell_surface *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; enum wl_shell_surface_resize edges; }; diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index b0de41e2..e17393f6 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -138,14 +138,14 @@ struct wlr_xdg_surface_v6 { struct wlr_xdg_toplevel_v6_move_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; }; struct wlr_xdg_toplevel_v6_resize_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t edges; }; @@ -153,7 +153,7 @@ struct wlr_xdg_toplevel_v6_resize_event { struct wlr_xdg_toplevel_v6_show_window_menu_event { struct wl_client *client; struct wlr_xdg_surface_v6 *surface; - struct wlr_seat_handle *seat_handle; + struct wlr_seat_client *seat; uint32_t serial; uint32_t x; uint32_t y; diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..e752e639 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -14,15 +14,19 @@ #include #include #include "rootston/server.h" -#include "rootston/server.h" +#include "rootston/seat.h" +// TODO replace me with a signal void view_destroy(struct roots_view *view) { struct roots_desktop *desktop = view->desktop; struct roots_input *input = desktop->server->input; - if (input->active_view == view) { - input->active_view = NULL; - input->mode = ROOTS_CURSOR_PASSTHROUGH; + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->focus == view) { + seat->focus = NULL; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + } } for (size_t i = 0; i < desktop->views->length; ++i) { @@ -89,15 +93,9 @@ bool view_center(struct roots_view *view) { view_get_size(view, &size); struct roots_desktop *desktop = view->desktop; - struct wlr_cursor *cursor = desktop->server->input->cursor; struct wlr_output *output = - wlr_output_layout_output_at(desktop->layout, cursor->x, cursor->y); - - if (!output) { - output = wlr_output_layout_get_center_output(desktop->layout); - } - + wlr_output_layout_get_center_output(desktop->layout); if (!output) { // empty layout return false; @@ -121,19 +119,15 @@ void view_setup(struct roots_view *view) { view_center(view); struct roots_input *input = view->desktop->server->input; - set_view_focus(input, view->desktop, view); + // TODO what seat gets focus? the one with the last input event? + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_focus_view(seat, view); + } } void view_teardown(struct roots_view *view) { - struct wlr_list *views = view->desktop->views; - if (views->length < 2 || views->items[views->length-1] != view) { - return; - } - - struct roots_view *prev_view = views->items[views->length-2]; - struct roots_input *input = prev_view->desktop->server->input; - set_view_focus(input, prev_view->desktop, prev_view); - wlr_seat_keyboard_notify_enter(input->wl_seat, prev_view->wlr_surface); + // TODO replace me with a signal } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/input.c b/rootston/input.c index 4a567763..8e45d6d3 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -84,43 +84,6 @@ struct roots_input *input_create(struct roots_server *server, input->config = config; input->server = server; - input->xcursor_theme = wlr_xcursor_theme_load("default", 16); - if (input->xcursor_theme == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor theme"); - free(input); - return NULL; - } - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - if (xcursor == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor from theme"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - - if (server->desktop->xwayland != NULL) { - struct wlr_xcursor_image *xcursor_image = xcursor->images[0]; - wlr_xwayland_set_cursor(server->desktop->xwayland, - xcursor_image->buffer, xcursor_image->width, xcursor_image->width, - xcursor_image->height, xcursor_image->hotspot_x, - xcursor_image->hotspot_y); - } - - input->wl_seat = wlr_seat_create(server->wl_display, "seat0"); - if (input->wl_seat == NULL) { - wlr_log(L_ERROR, "Cannot create seat"); - wlr_xcursor_theme_destroy(input->xcursor_theme); - free(input); - return NULL; - } - wlr_seat_set_capabilities(input->wl_seat, WL_SEAT_CAPABILITY_KEYBOARD - | WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_TOUCH); - - wl_list_init(&input->keyboards); - wl_list_init(&input->pointers); - wl_list_init(&input->touch); - wl_list_init(&input->tablet_tools); wl_list_init(&input->seats); input->input_add.notify = input_add_notify; @@ -128,23 +91,20 @@ struct roots_input *input_create(struct roots_server *server, input->input_remove.notify = input_remove_notify; wl_signal_add(&server->backend->events.input_remove, &input->input_remove); - input->cursor = wlr_cursor_create(); - cursor_initialize(input); - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_attach_output_layout(input->cursor, server->desktop->layout); - wlr_cursor_map_to_region(input->cursor, config->cursor.mapped_box); - cursor_load_config(config, input->cursor, - input, server->desktop); - - wl_list_init(&input->drag_icons); - return input; } void input_destroy(struct roots_input *input) { // TODO } + +struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, + struct wlr_seat *wlr_seat) { + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &input->seats, link) { + if (seat->seat == wlr_seat) { + return seat; + } + } + return seat; +} diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 0865f551..ef5eb8ab 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -39,7 +39,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } else if (strcmp(command, "next_window") == 0) { if (server->desktop->views->length > 0) { struct roots_view *view = server->desktop->views->items[0]; - set_view_focus(keyboard->input, server->desktop, view); + roots_seat_focus_view(keyboard->seat, view); } } else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { const char *shell_cmd = command + strlen(exec_prefix); @@ -192,13 +192,9 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->device = device; keyboard->input = input; - // XXX temporary - wl_list_insert(&input->keyboards, &keyboard->link); - - struct keyboard_config config; - memset(&config, 0, sizeof(config)); - keyboard_config_merge(&config, config_get_keyboard(input->config, device)); - keyboard_config_merge(&config, config_get_keyboard(input->config, NULL)); + struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + keyboard_config_merge(config, config_get_keyboard(input->config, device)); + keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); struct keyboard_config env_config = { .rules = getenv("XKB_DEFAULT_RULES"), @@ -207,15 +203,16 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, .variant = getenv("XKB_DEFAULT_VARIANT"), .options = getenv("XKB_DEFAULT_OPTIONS"), }; - keyboard_config_merge(&config, &env_config); + keyboard_config_merge(config, &env_config); + keyboard->config = config; struct xkb_rule_names rules; memset(&rules, 0, sizeof(rules)); - rules.rules = config.rules; - rules.model = config.model; - rules.layout = config.layout; - rules.variant = config.variant; - rules.options = config.options; + rules.rules = config->rules; + rules.model = config->model; + rules.layout = config->layout; + rules.variant = config->variant; + rules.options = config->options; struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (context == NULL) { wlr_log(L_ERROR, "Cannot create XKB context"); @@ -231,5 +228,6 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { struct roots_keyboard *keyboard = device->data; wl_list_remove(&keyboard->link); + free(keyboard->config); free(keyboard); } diff --git a/rootston/meson.build b/rootston/meson.build index baed5330..062f56fc 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,6 +1,6 @@ sources = [ 'config.c', - 'cursor.c', + #'cursor.c', 'roots_cursor.c', 'desktop.c', 'ini.c', diff --git a/rootston/output.c b/rootston/output.c index baa7b6cc..329c29be 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -151,15 +151,18 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { } struct roots_drag_icon *drag_icon = NULL; - wl_list_for_each(drag_icon, &server->input->drag_icons, link) { - if (!drag_icon->mapped) { - continue; + struct roots_seat *seat = NULL; + wl_list_for_each(seat, &server->input->seats, link) { + wl_list_for_each(drag_icon, &seat->drag_icons, link) { + if (!drag_icon->mapped) { + continue; + } + struct wlr_surface *icon = drag_icon->surface; + struct wlr_cursor *cursor = seat->cursor->cursor; + double icon_x = cursor->x + drag_icon->sx; + double icon_y = cursor->y + drag_icon->sy; + render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } - struct wlr_surface *icon = drag_icon->surface; - struct wlr_cursor *cursor = server->input->cursor; - double icon_x = cursor->x + drag_icon->sx; - double icon_y = cursor->y + drag_icon->sy; - render_surface(icon, desktop, wlr_output, &now, icon_x, icon_y, 0); } wlr_renderer_end(server->renderer); @@ -224,14 +227,11 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } - cursor_load_config(config, input->cursor, input, desktop); - - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); - - wlr_cursor_warp(input->cursor, NULL, input->cursor->x, input->cursor->y); + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + roots_seat_configure_cursor(seat); + roots_seat_configure_xcursor(seat); + } } void output_remove_notify(struct wl_listener *listener, void *data) { diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 72eff996..92c0cc9e 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -1,4 +1,11 @@ +#define _XOPEN_SOURCE 700 #include +#include +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include "rootston/cursor.h" @@ -19,47 +26,261 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { // TODO } +static void cursor_set_xcursor_image(struct roots_cursor *cursor, + struct wlr_xcursor_image *image) { + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); +} + +static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { + struct roots_desktop *desktop = cursor->seat->input->server->desktop; + struct roots_seat *seat = cursor->seat; + struct roots_view *view; + struct wlr_surface *surface; + double sx, sy; + switch (cursor->mode) { + case ROOTS_CURSOR_PASSTHROUGH: + view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, + &surface, &sx, &sy); + bool set_compositor_cursor = !view && cursor->cursor_client; + if (view) { + struct wl_client *view_client = + wl_resource_get_client(view->wlr_surface->resource); + set_compositor_cursor = view_client != cursor->cursor_client; + } + if (set_compositor_cursor) { + struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); + cursor_set_xcursor_image(cursor, xcursor->images[0]); + cursor->cursor_client = NULL; + } + if (view) { + wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); + } else { + wlr_seat_pointer_clear_focus(seat->seat); + } + break; + case ROOTS_CURSOR_MOVE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + view_move(seat->focus, cursor->view_x + dx, + cursor->view_y + dy); + } + break; + case ROOTS_CURSOR_RESIZE: + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + double active_x = seat->focus->x; + double active_y = seat->focus->y; + int width = cursor->view_width; + int height = cursor->view_height; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { + active_y = cursor->view_y + dy; + height -= dy; + if (height < 0) { + active_y += height; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { + height += dy; + } + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { + active_x = cursor->view_x + dx; + width -= dx; + if (width < 0) { + active_x += width; + } + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { + width += dx; + } + + if (width < 0) { + width = 0; + } + if (height < 0) { + height = 0; + } + + if (active_x != seat->focus->x || + active_y != seat->focus->y) { + view_move_resize(seat->focus, active_x, active_y, + width, height); + } else { + view_resize(seat->focus, width, height); + } + } + break; + case ROOTS_CURSOR_ROTATE: + if (seat->focus) { + struct roots_view *view = seat->focus; + int ox = view->x + view->wlr_surface->current->width/2, + oy = view->y + view->wlr_surface->current->height/2; + int ux = cursor->offs_x - ox, + uy = cursor->offs_y - oy; + int vx = cursor->cursor->x - ox, + vy = cursor->cursor->y - oy; + float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); + int steps = 12; + angle = round(angle/M_PI*steps) / (steps/M_PI); + view->rotation = cursor->view_rotation + angle; + } + break; + } + +} + +static void roots_cursor_press_button(struct roots_cursor *cursor, + struct wlr_input_device *device, uint32_t time, uint32_t button, + uint32_t state) { + struct roots_seat *seat = cursor->seat; + struct roots_desktop *desktop = seat->input->server->desktop; + struct wlr_surface *surface; + double sx, sy; + struct roots_view *view = view_at(desktop, + cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); + + if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { + // TODO + roots_seat_focus_view(seat, view); + + uint32_t edges; + switch (button) { + case BTN_LEFT: + // TODO + roots_seat_begin_move(seat, view); + break; + case BTN_RIGHT: + edges = 0; + if (sx < view->wlr_surface->current->width/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_LEFT; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_RIGHT; + } + if (sy < view->wlr_surface->current->height/2) { + edges |= ROOTS_CURSOR_RESIZE_EDGE_TOP; + } else { + edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; + } + roots_seat_begin_resize(seat, view, edges); + break; + case BTN_MIDDLE: + roots_seat_begin_rotate(seat, view); + break; + } + return; + } + + // TODO + uint32_t serial = + wlr_seat_pointer_notify_button(seat->seat, time, button, state); + + int i; + switch (state) { + case WLR_BUTTON_RELEASED: + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_position(cursor, time); + break; + case WLR_BUTTON_PRESSED: + // TODO + i = cursor->input_events_idx; + cursor->input_events[i].serial = serial; + cursor->input_events[i].cursor = cursor->cursor; + cursor->input_events[i].device = device; + cursor->input_events_idx = (i + 1) + % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); + roots_seat_focus_view(seat, view); + break; + } +} + void roots_cursor_handle_motion(struct roots_cursor *cursor, struct wlr_event_pointer_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion"); + wlr_cursor_move(cursor->cursor, event->device, + event->delta_x, event->delta_y); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_motion_absolute(struct roots_cursor *cursor, struct wlr_event_pointer_motion_absolute *event) { - wlr_log(L_DEBUG, "TODO: cursor handle motion absolute"); + wlr_cursor_warp_absolute(cursor->cursor, event->device, + event->x_mm / event->width_mm, event->y_mm / event->height_mm); + roots_cursor_update_position(cursor, event->time_msec); } void roots_cursor_handle_button(struct roots_cursor *cursor, struct wlr_event_pointer_button *event) { - wlr_log(L_DEBUG, "TODO: cursor handle button"); + roots_cursor_press_button(cursor, event->device, event->time_msec, + event->button, event->state); } void roots_cursor_handle_axis(struct roots_cursor *cursor, struct wlr_event_pointer_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle axis"); + wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, + event->orientation, event->delta); } void roots_cursor_handle_touch_down(struct roots_cursor *cursor, struct wlr_event_touch_down *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch down"); + struct roots_touch_point *point = + calloc(1, sizeof(struct roots_touch_point)); + if (!point) { + wlr_log(L_ERROR, "could not allocate memory for touch point"); + return; + } + + point->device = event->device->data; + point->slot = event->slot; + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + wl_list_insert(&cursor->touch_points, &point->link); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 1); } void roots_cursor_handle_touch_up(struct roots_cursor *cursor, struct wlr_event_touch_up *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch up"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + wl_list_remove(&point->link); + free(point); + break; + } + } + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, 0); } void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, struct wlr_event_touch_motion *event) { - wlr_log(L_DEBUG, "TODO: cursor handle touch motion"); + struct roots_touch_point *point; + wl_list_for_each(point, &cursor->touch_points, link) { + if (point->slot == event->slot) { + point->x = event->x_mm / event->width_mm; + point->y = event->y_mm / event->height_mm; + wlr_cursor_warp_absolute(cursor->cursor, event->device, + point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + break; + } + } } void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, struct wlr_event_tablet_tool_axis *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool axis"); + 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); + roots_cursor_update_position(cursor, event->time_msec); + } } void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, struct wlr_event_tablet_tool_tip *event) { - wlr_log(L_DEBUG, "TODO: cursor handle tool tip"); + roots_cursor_press_button(cursor, event->device, + event->time_msec, BTN_LEFT, event->state); } diff --git a/rootston/seat.c b/rootston/seat.c index 957843ec..ec7709fa 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -110,7 +111,7 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, } } -static void roots_seat_configure_cursor(struct roots_seat *seat) { +void roots_seat_configure_cursor(struct roots_seat *seat) { struct roots_config *config = seat->input->config; struct roots_desktop *desktop = seat->input->server->desktop; struct wlr_cursor *cursor = seat->cursor->cursor; @@ -156,10 +157,44 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { if (!seat->cursor) { return; } + seat->cursor->seat = seat; struct wlr_cursor *wlr_cursor = seat->cursor->cursor; struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); + seat->cursor->xcursor_theme = wlr_xcursor_theme_load("default", 16); + if (seat->cursor->xcursor_theme == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor theme"); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + if (xcursor == NULL) { + wlr_log(L_ERROR, "Cannot load xcursor from theme"); + wlr_xcursor_theme_destroy(seat->cursor->xcursor_theme); + roots_cursor_destroy(seat->cursor); + seat->cursor = NULL; + return; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + // XXX: xwayland will always have the theme of the last created seat + if (seat->input->server->desktop->xwayland != NULL) { + wlr_xwayland_set_cursor(seat->input->server->desktop->xwayland, + image->buffer, image->width, image->width, + image->height, image->hotspot_x, + image->hotspot_y); + } + + wl_list_init(&seat->cursor->touch_points); + + roots_seat_configure_cursor(seat); + // add input signals wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); seat->cursor->motion.notify = handle_cursor_motion; @@ -196,6 +231,12 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { return NULL; } + wl_list_init(&seat->keyboards); + wl_list_init(&seat->pointers); + wl_list_init(&seat->touch); + wl_list_init(&seat->tablet_tools); + wl_list_init(&seat->drag_icons); + seat->input = input; roots_seat_init_cursor(seat); @@ -218,11 +259,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { wl_list_insert(&input->seats, &seat->link); - wl_list_init(&seat->keyboards); - wl_list_init(&seat->pointers); - wl_list_init(&seat->touch); - wl_list_init(&seat->tablet_tools); - return seat; } @@ -231,6 +267,7 @@ void roots_seat_destroy(struct roots_seat *seat) { } static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { + assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; @@ -319,3 +356,88 @@ void roots_seat_remove_device(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } + +void roots_seat_configure_xcursor(struct roots_seat *seat) { + struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + + wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, + seat->cursor->cursor->y); +} + +bool roots_seat_has_meta_pressed(struct roots_seat *seat) { + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + if (!keyboard->config->meta_key) { + continue; + } + + uint32_t modifiers = + wlr_keyboard_get_modifiers(keyboard->device->keyboard); + if ((modifiers ^ keyboard->config->meta_key) == 0) { + return true; + } + } + + return false; +} + +void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { + struct roots_desktop *desktop = seat->input->server->desktop; + if (seat->focus == view) { + return; + } + seat->focus = view; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + if (!view) { + return; + } + + if (view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { + return; + } + + size_t index = 0; + for (size_t i = 0; i < desktop->views->length; ++i) { + struct roots_view *_view = desktop->views->items[i]; + if (_view != view) { + view_activate(_view, false); + } else { + index = i; + } + } + view_activate(view, true); + // TODO: list_swap + wlr_list_del(desktop->views, index); + wlr_list_add(desktop->views, view); + wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); +} + +void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_MOVE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_x = view->x; + cursor->view_y = view->y; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); + if (xcursor != NULL) { + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); + } +} + +void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, + uint32_t edges) { + // TODO +} + +void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { + // TODO +} diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index e38eb697..81b9e640 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -29,11 +29,11 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -42,11 +42,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_wl_shell_surface_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify input event + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_surface_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ca33c582..4a694349 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -98,11 +98,12 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_move_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + // TODO verify event serial + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, event->cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -111,11 +112,12 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_view *view = roots_xdg_surface->view; struct roots_input *input = view->desktop->server->input; struct wlr_xdg_toplevel_v6_resize_event *e = data; - const struct roots_input_event *event = get_input_event(input, e->serial); - if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + // TODO verify event serial + struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, event->cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_commit(struct wl_listener *listener, void *data) { diff --git a/rootston/xwayland.c b/rootston/xwayland.c index e3fc1c84..b53b98a9 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -114,22 +114,8 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { // seat based on seat pointer focus, but interactive moving and resizing is not // yet seat aware. Even then, we can only guess because X11 events don't give us // enough wayland info to know for sure. -static struct wlr_cursor *guess_cursor_for_view(struct roots_view *view) { - struct roots_input *input = view->desktop->server->input; - size_t len = sizeof(input->input_events) / sizeof(*input->input_events); - for (size_t i = 0; i < len; i++) { - struct wlr_cursor *cursor = input->input_events[i].cursor; - if (cursor) { - int width = view->xwayland_surface->surface->current->width; - int height = view->xwayland_surface->surface->current->height; - if (cursor->x > view->x && cursor->y > view->y && - cursor->x < view->x + width && - cursor->y < view->y + height) { - return cursor; - } - } - } - +static struct roots_seat *guess_seat_for_view(struct roots_view *view) { + // TODO return NULL; } @@ -137,28 +123,26 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_move); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_move(input, cursor, view); + roots_seat_begin_move(seat, view); } static void handle_request_resize(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, request_resize); struct roots_view *view = roots_surface->view; - struct roots_input *input = view->desktop->server->input; - struct wlr_cursor *cursor = guess_cursor_for_view(view); + struct roots_seat *seat = guess_seat_for_view(view); struct wlr_xwayland_resize_event *e = data; - if (!cursor || input->mode != ROOTS_CURSOR_PASSTHROUGH) { + if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } - view_begin_resize(input, cursor, view, e->edges); + roots_seat_begin_resize(seat, view, e->edges); } static void handle_map_notify(struct wl_listener *listener, void *data) { diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index fe61075e..ce32d186 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -110,7 +110,7 @@ static void shell_surface_protocol_move(struct wl_client *client, uint32_t serial) { wlr_log(L_DEBUG, "got shell surface move"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_move_event *event = @@ -121,7 +121,7 @@ static void shell_surface_protocol_move(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -177,7 +177,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, uint32_t serial, enum wl_shell_surface_resize edges) { wlr_log(L_DEBUG, "got shell surface resize"); struct wlr_wl_shell_surface *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); struct wlr_wl_shell_surface_resize_event *event = @@ -188,7 +188,7 @@ static void shell_surface_protocol_resize(struct wl_client *client, } event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..0c41b66f 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -557,7 +557,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -576,7 +576,7 @@ static void xdg_toplevel_protocol_show_window_menu(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->x = x; event->y = y; @@ -590,7 +590,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -609,7 +609,7 @@ static void xdg_toplevel_protocol_move(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; wl_signal_emit(&surface->events.request_move, event); @@ -621,7 +621,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, uint32_t edges) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); - struct wlr_seat_handle *seat_handle = + struct wlr_seat_client *seat = wl_resource_get_user_data(seat_resource); if (!surface->configured) { @@ -640,7 +640,7 @@ static void xdg_toplevel_protocol_resize(struct wl_client *client, event->client = client; event->surface = surface; - event->seat_handle = seat_handle; + event->seat = seat; event->serial = serial; event->edges = edges; -- cgit v1.2.3 From 5ac05b0c475aae86e0a9356dc68d59a5f4004d5e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 16:24:21 -0500 Subject: rootston: input remove stubs --- rootston/input.c | 2 +- rootston/seat.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/rootston/input.c b/rootston/input.c index 8e45d6d3..08cde4a1 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -63,7 +63,7 @@ static void input_add_notify(struct wl_listener *listener, void *data) { static void input_remove_notify(struct wl_listener *listener, void *data) { struct wlr_input_device *device = data; - struct roots_input *input = wl_container_of(listener, input, input_add); + struct roots_input *input = wl_container_of(listener, input, input_remove); struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { diff --git a/rootston/seat.c b/rootston/seat.c index ec7709fa..3a009a51 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -352,11 +352,52 @@ void roots_seat_add_device(struct roots_seat *seat, } } -void roots_seat_remove_device(struct roots_seat *seat, +static void seat_remove_keyboard(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_pointer(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_touch(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_tablet_pad(struct roots_seat *seat, + struct wlr_input_device *device) { + // TODO +} + +static void seat_remove_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { // TODO } +void roots_seat_remove_device(struct roots_seat *seat, + struct wlr_input_device *device) { + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + seat_remove_keyboard(seat, device); + break; + case WLR_INPUT_DEVICE_POINTER: + seat_remove_pointer(seat, device); + break; + case WLR_INPUT_DEVICE_TOUCH: + seat_remove_touch(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_PAD: + seat_remove_tablet_pad(seat, device); + break; + case WLR_INPUT_DEVICE_TABLET_TOOL: + seat_remove_tablet_tool(seat, device); + break; + } +} + void roots_seat_configure_xcursor(struct roots_seat *seat) { struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); struct wlr_xcursor_image *image = xcursor->images[0]; -- cgit v1.2.3 From fc6c3310e812afdc7c9754894e9e09c2fca20046 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 16:32:14 -0500 Subject: rootston: log seat name --- rootston/input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rootston/input.c b/rootston/input.c index 08cde4a1..92148b65 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -55,8 +55,8 @@ static void input_add_notify(struct wl_listener *listener, void *data) { return; } - wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s", device->name, - device->vendor, device->product, device_type(device->type)); + wlr_log(L_DEBUG, "New input device: %s (%d:%d) %s seat:%s", device->name, + device->vendor, device->product, device_type(device->type), seat_name); roots_seat_add_device(seat, device); } -- cgit v1.2.3 From 86b86f07143132a399f28c13c6e86db027bb0486 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 7 Nov 2017 16:42:04 -0500 Subject: rootston: multiple activated views --- rootston/seat.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/rootston/seat.c b/rootston/seat.c index 3a009a51..9a725dfa 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -430,12 +430,35 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { if (seat->focus == view) { return; } - seat->focus = view; - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + + // unfocus the old view if it is not focused by some other seat + // TODO probably should be an input function + if (seat->focus) { + bool has_other_focus = false; + struct roots_seat *iter_seat; + wl_list_for_each(iter_seat, &seat->input->seats, link) { + if (iter_seat == seat) { + continue; + } + if (iter_seat->focus == seat->focus) { + has_other_focus = true; + break; + } + } + + if (!has_other_focus) { + view_activate(seat->focus, false); + } + } + if (!view) { + seat->focus = NULL; + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; return; } + seat->focus = view; + if (view->type == ROOTS_XWAYLAND_VIEW && view->xwayland_surface->override_redirect) { return; @@ -444,12 +467,12 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { size_t index = 0; for (size_t i = 0; i < desktop->views->length; ++i) { struct roots_view *_view = desktop->views->items[i]; - if (_view != view) { - view_activate(_view, false); - } else { + if (_view == view) { index = i; + break; } } + view_activate(view, true); // TODO: list_swap wlr_list_del(desktop->views, index); -- cgit v1.2.3 From 84d5e6bbb445c601d85653264f91d4faf333145d Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 5 Nov 2017 17:09:00 +0100 Subject: Send current keyboard state when entering a surface --- include/wlr/types/wlr_keyboard.h | 3 +++ types/wlr_keyboard.c | 25 +++++++++++++++++++++++++ types/wlr_seat.c | 17 +++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index af837ff5..e2d50b03 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -28,6 +28,8 @@ enum wlr_keyboard_modifier { WLR_MODIFIER_MOD5 = 128, }; +#define WLR_KEYBOARD_KEYS_CAP 32 + struct wlr_keyboard_impl; struct wlr_keyboard { @@ -41,6 +43,7 @@ struct wlr_keyboard { xkb_led_index_t led_indexes[WLR_LED_COUNT]; xkb_mod_index_t mod_indexes[WLR_MODIFIER_COUNT]; + uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP]; struct { xkb_mod_mask_t depressed; xkb_mod_mask_t latched; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c27264ef..98ebeed5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -45,6 +45,30 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { wl_signal_emit(&keyboard->events.modifiers, keyboard); } +static void keyboard_key_update(struct wlr_keyboard *keyboard, + struct wlr_event_keyboard_key *event) { + bool found = false; + size_t i = 0; + for (; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] == event->keycode) { + found = true; + break; + } + } + + if (event->state == WLR_KEY_PRESSED && !found) { + for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] == 0) { + keyboard->keycodes[i] = event->keycode; + break; + } + } + } + if (event->state == WLR_KEY_RELEASED && found) { + keyboard->keycodes[i] = 0; + } +} + void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { @@ -68,6 +92,7 @@ void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, } keyboard_led_update(keyboard); keyboard_modifier_update(keyboard); + keyboard_key_update(keyboard, event); wl_signal_emit(&keyboard->events.key, event); } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 76b34d31..ae991383 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -751,13 +751,26 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, // enter the current surface if (client && client->keyboard) { - // TODO: read the currently pressed keys out of the active keyboard and - // put them in this array + struct wlr_keyboard *keyboard = wlr_seat->keyboard_state.keyboard; + struct wl_array keys; wl_array_init(&keys); + size_t n = 0; + for (size_t i = 0; i < WLR_KEYBOARD_KEYS_CAP; ++i) { + if (keyboard->keycodes[i] != 0) { + wl_array_add(&keys, sizeof(uint32_t)); + ((uint32_t *)keys.data)[n] = keyboard->keycodes[i]; + n++; + } + } uint32_t serial = wl_display_next_serial(wlr_seat->display); wl_keyboard_send_enter(client->keyboard, serial, surface->resource, &keys); + wl_array_release(&keys); + + wlr_seat_keyboard_send_modifiers(wlr_seat, + keyboard->modifiers.depressed, keyboard->modifiers.latched, + keyboard->modifiers.locked, keyboard->modifiers.group); wlr_seat_client_send_selection(client); } -- cgit v1.2.3 From fc09f904624a8f3a4fc7577ba19137a3700c7a45 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 08:19:23 -0500 Subject: rootston: guess seat for xwayland moveresize --- rootston/xwayland.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/rootston/xwayland.c b/rootston/xwayland.c index b53b98a9..92ba5e60 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -110,12 +110,16 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { xwayland_surface, event->x, event->y, event->width, event->height); } -// XXX Needs deep refactoring to get this better. We need to select the correct -// seat based on seat pointer focus, but interactive moving and resizing is not -// yet seat aware. Even then, we can only guess because X11 events don't give us -// enough wayland info to know for sure. static struct roots_seat *guess_seat_for_view(struct roots_view *view) { - // TODO + // the best we can do is to pick the first seat that has the surface focused + // for the pointer + struct roots_input *input = view->desktop->server->input; + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->seat->pointer_state.focused_surface == view->wlr_surface) { + return seat; + } + } return NULL; } -- cgit v1.2.3 From eb3c367c63adbef67bfe76bfc57f3eba25d0c149 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 08:35:27 -0500 Subject: rootston: seat resize and rotate --- rootston/seat.c | 40 ++++++++++++++++++++++++++++++++++++---- rootston/xdg_shell_v6.c | 1 + 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/rootston/seat.c b/rootston/seat.c index 9a725dfa..7fcffc29 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -480,6 +480,12 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); } +static void seat_set_xcursor_image(struct roots_seat *seat, struct + wlr_xcursor_image *image) { + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); +} + void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { struct roots_cursor *cursor = seat->cursor; cursor->mode = ROOTS_CURSOR_MOVE; @@ -492,16 +498,42 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); if (xcursor != NULL) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + seat_set_xcursor_image(seat, image); } } void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, uint32_t edges) { - // TODO + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_RESIZE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_x = view->x; + cursor->view_y = view->y; + struct wlr_box size; + view_get_size(view, &size); + cursor->view_width = size.width; + cursor->view_height = size.height; + cursor->resize_edges = edges; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_resize_xcursor(cursor->xcursor_theme, edges); + if (xcursor != NULL) { + seat_set_xcursor_image(seat, xcursor->images[0]); + } + } void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { - // TODO + struct roots_cursor *cursor = seat->cursor; + cursor->mode = ROOTS_CURSOR_ROTATE; + cursor->offs_x = cursor->cursor->x; + cursor->offs_y = cursor->cursor->y; + cursor->view_rotation = view->rotation; + wlr_seat_pointer_clear_focus(seat->seat); + + struct wlr_xcursor *xcursor = get_rotate_xcursor(cursor->xcursor_theme); + if (xcursor != NULL) { + seat_set_xcursor_image(seat, xcursor->images[0]); + } } diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 4a694349..ed952e18 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -114,6 +114,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct wlr_xdg_toplevel_v6_resize_event *e = data; // TODO verify event serial struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); + assert(seat); if (!seat || seat->cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { return; } -- cgit v1.2.3 From a00b7f1e9bb992734f2498e597a86f1ca29b1d59 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 09:04:33 -0500 Subject: rootston: remove devices from seat --- include/rootston/keyboard.h | 5 +---- rootston/keyboard.c | 3 +-- rootston/seat.c | 42 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index e3caf8fb..4dd70a65 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -11,8 +11,6 @@ struct roots_keyboard { struct roots_seat *seat; struct wlr_input_device *device; struct keyboard_config *config; - struct wl_list seat_link; - // XXX temporary struct wl_list link; struct wl_listener keyboard_key; @@ -24,8 +22,7 @@ struct roots_keyboard { struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, struct roots_input *input); -void roots_keyboard_destroy(struct wlr_input_device *device, - struct roots_input *input); +void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ef5eb8ab..a770f00f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -225,8 +225,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, return keyboard; } -void roots_keyboard_destroy(struct wlr_input_device *device, struct roots_input *input) { - struct roots_keyboard *keyboard = device->data; +void roots_keyboard_destroy(struct roots_keyboard *keyboard) { wl_list_remove(&keyboard->link); free(keyboard->config); free(keyboard); diff --git a/rootston/seat.c b/rootston/seat.c index 7fcffc29..e860c093 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -271,7 +271,7 @@ static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device * struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); keyboard->seat = seat; - wl_list_insert(&seat->keyboards, &keyboard->seat_link); + wl_list_insert(&seat->keyboards, &keyboard->link); keyboard->keyboard_key.notify = handle_keyboard_key; wl_signal_add(&keyboard->device->keyboard->events.key, @@ -354,17 +354,39 @@ void roots_seat_add_device(struct roots_seat *seat, static void seat_remove_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &seat->keyboards, link) { + if (keyboard->device == device) { + roots_keyboard_destroy(keyboard); + return; + } + } } static void seat_remove_pointer(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_pointer *pointer; + wl_list_for_each(pointer, &seat->pointers, link) { + if (pointer->device == device) { + wl_list_remove(&pointer->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(pointer); + return; + } + } } static void seat_remove_touch(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_touch *touch; + wl_list_for_each(touch, &seat->touch, link) { + if (touch->device == device) { + wl_list_remove(&touch->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(touch); + return; + } + } } static void seat_remove_tablet_pad(struct roots_seat *seat, @@ -374,7 +396,15 @@ static void seat_remove_tablet_pad(struct roots_seat *seat, static void seat_remove_tablet_tool(struct roots_seat *seat, struct wlr_input_device *device) { - // TODO + struct roots_tablet_tool *tablet_tool; + wl_list_for_each(tablet_tool, &seat->tablet_tools, link) { + if (tablet_tool->device == device) { + wl_list_remove(&tablet_tool->link); + wlr_cursor_detach_input_device(seat->cursor->cursor, device); + free(tablet_tool); + return; + } + } } void roots_seat_remove_device(struct roots_seat *seat, @@ -410,7 +440,7 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { bool roots_seat_has_meta_pressed(struct roots_seat *seat) { struct roots_keyboard *keyboard; - wl_list_for_each(keyboard, &seat->keyboards, seat_link) { + wl_list_for_each(keyboard, &seat->keyboards, link) { if (!keyboard->config->meta_key) { continue; } -- cgit v1.2.3 From 882e6206393f1931fea3de8fd2b87b91314ed6d0 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 8 Nov 2017 19:02:56 +0100 Subject: Always read state from wlr_keyboard in the seat --- include/wlr/types/wlr_seat.h | 12 ++----- rootston/desktop.c | 1 - rootston/keyboard.c | 23 +++++-------- types/wlr_data_device.c | 5 ++- types/wlr_seat.c | 78 ++++++++++++++++++++------------------------ types/wlr_xdg_shell_v6.c | 7 ++-- 6 files changed, 52 insertions(+), 74 deletions(-) diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index b8b467d2..09d3e282 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -45,9 +45,7 @@ struct wlr_keyboard_grab_interface { struct wlr_surface *surface); void (*key)(struct wlr_seat_keyboard_grab *grab, uint32_t time, uint32_t key, uint32_t state); - void (*modifiers)(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group); + void (*modifiers)(struct wlr_seat_keyboard_grab *grab); void (*cancel)(struct wlr_seat_keyboard_grab *grab); }; @@ -296,17 +294,13 @@ void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, * Send the modifier state to focused keyboard resources. Compositors should use * `wlr_seat_keyboard_notify_modifiers()` to respect any keyboard grabs. */ -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat); /** * Notify the seat that the modifiers for the keyboard have changed. Defers to * any keyboard grabs. */ -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat); /** * Notify the seat that the keyboard focus has changed and request it to be the diff --git a/rootston/desktop.c b/rootston/desktop.c index 29f78ac7..b36a6932 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -133,7 +133,6 @@ void view_teardown(struct roots_view *view) { struct roots_view *prev_view = views->items[views->length-2]; struct roots_input *input = prev_view->desktop->server->input; set_view_focus(input, prev_view->desktop, prev_view); - wlr_seat_keyboard_notify_enter(input->wl_seat, prev_view->wlr_surface); } struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6c419df8..bde912aa 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -135,8 +135,8 @@ static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, const xkb_keysym_t *syms; xkb_layout_index_t layout_index = xkb_state_key_get_layout( keyboard->device->keyboard->xkb_state, keycode); - int syms_len = xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, - keycode, layout_index, 0, &syms); + int syms_len = xkb_keymap_key_get_syms_by_level( + keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); bool handled = false; for (int i = 0; i < syms_len; i++) { @@ -195,7 +195,8 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); if (!handled) { - bool key_handled = keyboard_keysyms_simple(keyboard, keycode, event->state); + bool key_handled = keyboard_keysyms_simple(keyboard, keycode, + event->state); handled = handled || key_handled; } @@ -207,17 +208,11 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) { } static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { - struct roots_keyboard *r_keyboard = - wl_container_of(listener, r_keyboard, modifiers); - struct wlr_seat *seat = r_keyboard->input->wl_seat; - struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; - wlr_seat_set_keyboard(seat, r_keyboard->device); - wlr_seat_keyboard_notify_modifiers(seat, - keyboard->modifiers.depressed, - keyboard->modifiers.latched, - keyboard->modifiers.locked, - keyboard->modifiers.group); - + struct roots_keyboard *keyboard = + wl_container_of(listener, keyboard, modifiers); + struct wlr_seat *seat = keyboard->input->wl_seat; + wlr_seat_set_keyboard(seat, keyboard->device); + wlr_seat_keyboard_notify_modifiers(seat); } static void keyboard_config_merge(struct keyboard_config *config, diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index ee83260e..ea28ef50 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -531,9 +531,8 @@ static void keyboard_drag_key(struct wlr_seat_keyboard_grab *grab, // no keyboard input during drags } -static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { +static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab) { + //struct wlr_keyboard *keyboard = grab->seat->keyboard_state.keyboard; // TODO change the dnd action based on what modifier is pressed on the // keyboard } diff --git a/types/wlr_seat.c b/types/wlr_seat.c index ae991383..9de1b3a0 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -284,11 +284,8 @@ static void default_keyboard_key(struct wlr_seat_keyboard_grab *grab, wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - wlr_seat_keyboard_send_modifiers(grab->seat, mods_depressed, - mods_latched, mods_locked, group); +static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab) { + wlr_seat_keyboard_send_modifiers(grab->seat); } static void default_keyboard_cancel(struct wlr_seat_keyboard_grab *grab) { @@ -708,24 +705,26 @@ static void keyboard_resource_destroy_notify(struct wl_listener *listener, wlr_seat_keyboard_clear_focus(state->seat); } -void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { +void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat) { struct wlr_seat_client *client = seat->keyboard_state.focused_client; if (!client || !client->keyboard) { return; } - uint32_t serial = wl_display_next_serial(seat->display); + struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; + if (!keyboard) { + return; + } + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_modifiers(client->keyboard, serial, - mods_depressed, mods_latched, - mods_locked, group); + keyboard->modifiers.depressed, keyboard->modifiers.latched, + keyboard->modifiers.locked, keyboard->modifiers.group); } -void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, +void wlr_seat_keyboard_enter(struct wlr_seat *seat, struct wlr_surface *surface) { - if (wlr_seat->keyboard_state.focused_surface == surface) { + if (seat->keyboard_state.focused_surface == surface) { // this surface already got an enter notify return; } @@ -734,24 +733,24 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, if (surface) { struct wl_client *wl_client = wl_resource_get_client(surface->resource); - client = wlr_seat_client_for_wl_client(wlr_seat, wl_client); + client = wlr_seat_client_for_wl_client(seat, wl_client); } struct wlr_seat_client *focused_client = - wlr_seat->keyboard_state.focused_client; + seat->keyboard_state.focused_client; struct wlr_surface *focused_surface = - wlr_seat->keyboard_state.focused_surface; + seat->keyboard_state.focused_surface; // leave the previously entered surface if (focused_client && focused_client->keyboard && focused_surface) { - uint32_t serial = wl_display_next_serial(wlr_seat->display); + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_leave(focused_client->keyboard, serial, focused_surface->resource); } // enter the current surface - if (client && client->keyboard) { - struct wlr_keyboard *keyboard = wlr_seat->keyboard_state.keyboard; + if (client && client->keyboard && seat->keyboard_state.keyboard) { + struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard; struct wl_array keys; wl_array_init(&keys); @@ -763,55 +762,50 @@ void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, n++; } } - uint32_t serial = wl_display_next_serial(wlr_seat->display); + uint32_t serial = wl_display_next_serial(seat->display); wl_keyboard_send_enter(client->keyboard, serial, surface->resource, &keys); wl_array_release(&keys); - wlr_seat_keyboard_send_modifiers(wlr_seat, - keyboard->modifiers.depressed, keyboard->modifiers.latched, - keyboard->modifiers.locked, keyboard->modifiers.group); + wlr_seat_keyboard_send_modifiers(seat); wlr_seat_client_send_selection(client); } // reinitialize the focus destroy events - wl_list_remove(&wlr_seat->keyboard_state.surface_destroy.link); - wl_list_init(&wlr_seat->keyboard_state.surface_destroy.link); - wl_list_remove(&wlr_seat->keyboard_state.resource_destroy.link); - wl_list_init(&wlr_seat->keyboard_state.resource_destroy.link); + wl_list_remove(&seat->keyboard_state.surface_destroy.link); + wl_list_init(&seat->keyboard_state.surface_destroy.link); + wl_list_remove(&seat->keyboard_state.resource_destroy.link); + wl_list_init(&seat->keyboard_state.resource_destroy.link); if (surface) { wl_signal_add(&surface->events.destroy, - &wlr_seat->keyboard_state.surface_destroy); + &seat->keyboard_state.surface_destroy); wl_resource_add_destroy_listener(surface->resource, - &wlr_seat->keyboard_state.resource_destroy); - wlr_seat->keyboard_state.resource_destroy.notify = + &seat->keyboard_state.resource_destroy); + seat->keyboard_state.resource_destroy.notify = keyboard_resource_destroy_notify; - wlr_seat->keyboard_state.surface_destroy.notify = + seat->keyboard_state.surface_destroy.notify = keyboard_surface_destroy_notify; } - wlr_seat->keyboard_state.focused_client = client; - wlr_seat->keyboard_state.focused_surface = surface; + seat->keyboard_state.focused_client = client; + seat->keyboard_state.focused_surface = surface; } -void wlr_seat_keyboard_notify_enter(struct wlr_seat *wlr_seat, struct +void wlr_seat_keyboard_notify_enter(struct wlr_seat *seat, struct wlr_surface *surface) { - struct wlr_seat_keyboard_grab *grab = wlr_seat->keyboard_state.grab; + struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; grab->interface->enter(grab, surface); } -void wlr_seat_keyboard_clear_focus(struct wlr_seat *wlr_seat) { +void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) { struct wl_array keys; wl_array_init(&keys); - wlr_seat_keyboard_enter(wlr_seat, NULL); + wlr_seat_keyboard_enter(seat, NULL); } -void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) { +void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; - grab->interface->modifiers(grab, - mods_depressed, mods_latched, mods_locked, group); + grab->interface->modifiers(grab); } void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..ef4ae42e 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -111,11 +111,8 @@ static void xdg_keyboard_grab_key(struct wlr_seat_keyboard_grab *grab, uint32_t wlr_seat_keyboard_send_key(grab->seat, time, key, state); } -static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { - wlr_seat_keyboard_send_modifiers(grab->seat, mods_depressed, mods_latched, - mods_locked, group); +static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab) { + wlr_seat_keyboard_send_modifiers(grab->seat); } static void xdg_keyboard_grab_cancel(struct wlr_seat_keyboard_grab *grab) { -- cgit v1.2.3 From 992f931ae9319999f338298d8e0538f13ee388d7 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 14:53:08 -0500 Subject: rootston: cleanup for multiseat --- include/rootston/input.h | 42 +----------------------------------------- include/rootston/xcursor.h | 15 +++++++++++++++ rootston/roots_cursor.c | 5 +---- rootston/seat.c | 1 + rootston/xcursor.c | 16 ++++++++-------- 5 files changed, 26 insertions(+), 53 deletions(-) create mode 100644 include/rootston/xcursor.h diff --git a/include/rootston/input.h b/include/rootston/input.h index 7463ba3a..e073a59d 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -4,7 +4,6 @@ #include #include #include -#include #include "rootston/cursor.h" #include "rootston/config.h" #include "rootston/view.h" @@ -14,30 +13,12 @@ struct roots_input { struct roots_config *config; struct roots_server *server; - struct wl_list keyboards; - struct wl_list pointers; - struct wl_list touch; - struct wl_list tablet_tools; - struct wl_list seats; - struct wl_listener input_add; struct wl_listener input_remove; - struct wl_listener cursor_motion; - struct wl_listener cursor_motion_absolute; - struct wl_listener cursor_button; - struct wl_listener cursor_axis; - - struct wl_listener cursor_touch_down; - struct wl_listener cursor_touch_up; - struct wl_listener cursor_touch_motion; - - struct wl_listener cursor_tool_axis; - struct wl_listener cursor_tool_tip; + struct wl_list seats; struct wl_listener pointer_grab_begin; - struct wl_list touch_points; - struct wl_listener pointer_grab_end; struct wl_listener request_set_cursor; @@ -47,27 +28,6 @@ struct roots_input *input_create(struct roots_server *server, struct roots_config *config); void input_destroy(struct roots_input *input); -void cursor_initialize(struct roots_input *input); -void cursor_load_config(struct roots_config *config, - struct wlr_cursor *cursor, - struct roots_input *input, - struct roots_desktop *desktop); -const struct roots_input_event *get_input_event(struct roots_input *input, - uint32_t serial); -void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view); -void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view, uint32_t edges); - -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); -struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, - uint32_t edges); -struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); - -void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, - struct roots_view *view); - struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, struct wlr_seat *seat); diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h new file mode 100644 index 00000000..c96e50ef --- /dev/null +++ b/include/rootston/xcursor.h @@ -0,0 +1,15 @@ +#ifndef _ROOTSTON_XCURSOR_H +#define _ROOTSTON_XCURSOR_H + +#include + +struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); + +struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); + +struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, + uint32_t edges); + +struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); + +#endif diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 92c0cc9e..833551d1 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -7,6 +7,7 @@ #include #endif #include +#include "rootston/xcursor.h" #include "rootston/cursor.h" struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { @@ -141,13 +142,11 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { - // TODO roots_seat_focus_view(seat, view); uint32_t edges; switch (button) { case BTN_LEFT: - // TODO roots_seat_begin_move(seat, view); break; case BTN_RIGHT: @@ -171,7 +170,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, return; } - // TODO uint32_t serial = wlr_seat_pointer_notify_button(seat->seat, time, button, state); @@ -182,7 +180,6 @@ static void roots_cursor_press_button(struct roots_cursor *cursor, roots_cursor_update_position(cursor, time); break; case WLR_BUTTON_PRESSED: - // TODO i = cursor->input_events_idx; cursor->input_events[i].serial = serial; cursor->input_events[i].cursor = cursor->cursor; diff --git a/rootston/seat.c b/rootston/seat.c index e860c093..b4d7887e 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -5,6 +5,7 @@ #include +#include "rootston/xcursor.h" #include "rootston/input.h" #include "rootston/seat.h" #include "rootston/keyboard.h" diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 43cbfc51..8697cdc3 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -1,14 +1,6 @@ #include #include "rootston/input.h" -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); -} - -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); -} - static const char *get_resize_xcursor_name(uint32_t edges) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { @@ -32,6 +24,14 @@ static const char *get_resize_xcursor_name(uint32_t edges) { return "se-resize"; // fallback } +struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { + return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); +} + +struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { + return wlr_xcursor_theme_get_cursor(theme, "grabbing"); +} + struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, uint32_t edges) { return wlr_xcursor_theme_get_cursor(theme, get_resize_xcursor_name(edges)); -- cgit v1.2.3 From 428bf18ec70a29d6e3d778ab3baf175a3cead0af Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 15:23:56 -0500 Subject: rootston: request set cursor --- include/rootston/cursor.h | 8 ++++++++ include/rootston/input.h | 5 ----- rootston/roots_cursor.c | 21 +++++++++++++++++++++ rootston/seat.c | 23 ++++++++++++++++++----- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 18d5f720..3bc8c08b 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -53,6 +53,11 @@ struct roots_cursor { struct wl_listener tool_axis; struct wl_listener tool_tip; + + struct wl_listener pointer_grab_begin; + struct wl_listener pointer_grab_end; + + struct wl_listener request_set_cursor; }; struct roots_cursor *roots_cursor_create(struct roots_seat *seat); @@ -86,4 +91,7 @@ void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, struct wlr_event_tablet_tool_tip *event); +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event); + #endif diff --git a/include/rootston/input.h b/include/rootston/input.h index e073a59d..ea0bbeb6 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -17,11 +17,6 @@ struct roots_input { struct wl_listener input_remove; struct wl_list seats; - - struct wl_listener pointer_grab_begin; - struct wl_listener pointer_grab_end; - - struct wl_listener request_set_cursor; }; struct roots_input *input_create(struct roots_server *server, diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index 833551d1..c44b0e7f 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -281,3 +281,24 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, event->state); } + +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event) { + struct wlr_surface *focused_surface = + event->seat_client->seat->pointer_state.focused_surface; + bool has_focused = focused_surface != NULL && focused_surface->resource != NULL; + struct wl_client *focused_client = NULL; + if (has_focused) { + focused_client = wl_resource_get_client(focused_surface->resource); + } + if (event->seat_client->client != focused_client || + cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { + wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); + return; + } + + wlr_log(L_DEBUG, "Setting client cursor"); + wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, + event->hotspot_y); + cursor->cursor_client = event->seat_client->client; +} diff --git a/rootston/seat.c b/rootston/seat.c index b4d7887e..12f12a69 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -89,6 +89,14 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { roots_cursor_handle_tool_tip(cursor, event); } +static void handle_request_set_cursor(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, request_set_cursor); + struct wlr_seat_pointer_request_set_cursor_event *event = data; + roots_cursor_handle_request_set_cursor(cursor, event); +} + static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; @@ -224,6 +232,10 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&wlr_cursor->events.tablet_tool_tip, &seat->cursor->tool_tip); seat->cursor->tool_tip.notify = handle_tool_tip; + + wl_signal_add(&seat->seat->events.request_set_cursor, + &seat->cursor->request_set_cursor); + seat->cursor->request_set_cursor.notify = handle_request_set_cursor; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { @@ -240,16 +252,17 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->input = input; - roots_seat_init_cursor(seat); - if (!seat->cursor) { + seat->seat = wlr_seat_create(input->server->wl_display, name); + if (!seat->seat) { free(seat); + roots_cursor_destroy(seat->cursor); return NULL; } - seat->seat = wlr_seat_create(input->server->wl_display, name); - if (!seat->seat) { + roots_seat_init_cursor(seat); + if (!seat->cursor) { + wlr_seat_destroy(seat->seat); free(seat); - roots_cursor_destroy(seat->cursor); return NULL; } -- cgit v1.2.3 From 06642859f1d6c1e88056a606dac7376fb59e9205 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 15:35:47 -0500 Subject: rootston: drag icons --- include/rootston/cursor.h | 6 +++++ rootston/roots_cursor.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ rootston/seat.c | 24 ++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 3bc8c08b..c0dbc010 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -94,4 +94,10 @@ void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, struct wlr_seat_pointer_request_set_cursor_event *event); +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab); + +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab); + #endif diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c index c44b0e7f..c8abe098 100644 --- a/rootston/roots_cursor.c +++ b/rootston/roots_cursor.c @@ -302,3 +302,65 @@ void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, event->hotspot_y); cursor->cursor_client = event->seat_client->client; } + +static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_commit); + drag_icon->sx += drag_icon->surface->current->sx; + drag_icon->sy += drag_icon->surface->current->sy; +} + +static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_destroy); + wl_list_remove(&drag_icon->link); + wl_list_remove(&drag_icon->surface_destroy.link); + wl_list_remove(&drag_icon->surface_commit.link); + free(drag_icon); +} + +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + struct roots_seat *seat = cursor->seat; + if (grab->interface == &wlr_data_device_pointer_drag_interface) { + struct wlr_drag *drag = grab->data; + if (drag->icon) { + struct roots_drag_icon *iter_icon; + wl_list_for_each(iter_icon, &seat->drag_icons, link) { + if (iter_icon->surface == drag->icon) { + // already in the list + return; + } + } + + struct roots_drag_icon *drag_icon = + calloc(1, sizeof(struct roots_drag_icon)); + drag_icon->mapped = true; + drag_icon->surface = drag->icon; + wl_list_insert(&seat->drag_icons, &drag_icon->link); + + wl_signal_add(&drag->icon->events.destroy, + &drag_icon->surface_destroy); + drag_icon->surface_destroy.notify = handle_drag_icon_destroy; + + wl_signal_add(&drag->icon->events.commit, + &drag_icon->surface_commit); + drag_icon->surface_commit.notify = handle_drag_icon_commit; + } + } +} + +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + if (grab->interface == &wlr_data_device_pointer_drag_interface) { + struct wlr_drag *drag = grab->data; + struct roots_drag_icon *icon; + wl_list_for_each(icon, &cursor->seat->drag_icons, link) { + if (icon->surface == drag->icon) { + icon->mapped = false; + } + } + } + + roots_cursor_update_position(cursor, 0); +} diff --git a/rootston/seat.c b/rootston/seat.c index 12f12a69..ce8ad10b 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -97,6 +97,22 @@ static void handle_request_set_cursor(struct wl_listener *listener, roots_cursor_handle_request_set_cursor(cursor, event); } +static void handle_pointer_grab_begin(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, pointer_grab_begin); + struct wlr_seat_pointer_grab *grab = data; + roots_cursor_handle_pointer_grab_begin(cursor, grab); +} + +static void handle_pointer_grab_end(struct wl_listener *listener, + void *data) { + struct roots_cursor *cursor = + wl_container_of(listener, cursor, pointer_grab_end); + struct wlr_seat_pointer_grab *grab = data; + roots_cursor_handle_pointer_grab_end(cursor, grab); +} + static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input_device *device) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; @@ -236,6 +252,14 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wl_signal_add(&seat->seat->events.request_set_cursor, &seat->cursor->request_set_cursor); seat->cursor->request_set_cursor.notify = handle_request_set_cursor; + + wl_signal_add(&seat->seat->events.pointer_grab_begin, + &seat->cursor->pointer_grab_begin); + seat->cursor->pointer_grab_begin.notify = handle_pointer_grab_begin; + + wl_signal_add(&seat->seat->events.pointer_grab_end, + &seat->cursor->pointer_grab_end); + seat->cursor->pointer_grab_end.notify = handle_pointer_grab_end; } struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { -- cgit v1.2.3 From 4df8be1a8f32ea59f88a179104885c0452a89d6e Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 8 Nov 2017 22:25:06 +0100 Subject: Better UX when moving/resizing/rotating maximized views --- rootston/cursor.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/rootston/cursor.c b/rootston/cursor.c index d97d518e..80836ccd 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -39,13 +39,18 @@ static void cursor_set_xcursor_image(struct roots_input *input, void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view) { - view_maximize(view, false); - input->mode = ROOTS_CURSOR_MOVE; input->offs_x = cursor->x; input->offs_y = cursor->y; - input->view_x = view->x; - input->view_y = view->y; + if (view->maximized) { + input->view_x = view->saved.x; + input->view_y = view->saved.y; + } else { + input->view_x = view->x; + input->view_y = view->y; + } + + view_maximize(view, false); wlr_seat_pointer_clear_focus(input->wl_seat); struct wlr_xcursor *xcursor = get_move_xcursor(input->xcursor_theme); @@ -56,18 +61,25 @@ void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view, uint32_t edges) { - view_maximize(view, false); - input->mode = ROOTS_CURSOR_RESIZE; input->offs_x = cursor->x; input->offs_y = cursor->y; - input->view_x = view->x; - input->view_y = view->y; - struct wlr_box size; - view_get_size(view, &size); - input->view_width = size.width; - input->view_height = size.height; + if (view->maximized) { + input->view_x = view->saved.x; + input->view_y = view->saved.y; + input->view_width = view->saved.width; + input->view_height = view->saved.height; + } else { + input->view_x = view->x; + input->view_y = view->y; + struct wlr_box size; + view_get_size(view, &size); + input->view_width = size.width; + input->view_height = size.height; + } input->resize_edges = edges; + + view_maximize(view, false); wlr_seat_pointer_clear_focus(input->wl_seat); struct wlr_xcursor *xcursor = get_resize_xcursor(input->xcursor_theme, edges); @@ -78,12 +90,12 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, void view_begin_rotate(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view) { - view_maximize(view, false); - input->mode = ROOTS_CURSOR_ROTATE; input->offs_x = cursor->x; input->offs_y = cursor->y; input->view_rotation = view->rotation; + + view_maximize(view, false); wlr_seat_pointer_clear_focus(input->wl_seat); struct wlr_xcursor *xcursor = get_rotate_xcursor(input->xcursor_theme); -- cgit v1.2.3 From 2118c691b13c20d7100abfa02f9e274667501aef Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 8 Nov 2017 23:03:07 +0100 Subject: Add maximize support for xwayland in rootston --- include/rootston/view.h | 1 + rootston/xwayland.c | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 67643b94..f6ac0d23 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -36,6 +36,7 @@ struct roots_xwayland_surface { struct wl_listener request_configure; struct wl_listener request_move; struct wl_listener request_resize; + struct wl_listener request_maximize; struct wl_listener map_notify; struct wl_listener unmap_notify; }; diff --git a/rootston/xwayland.c b/rootston/xwayland.c index e3fc1c84..431586ba 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -85,6 +85,13 @@ static void close(struct roots_view *view) { wlr_xwayland_surface_close(view->desktop->xwayland, view->xwayland_surface); } +static void maximize(struct roots_view *view, bool maximized) { + assert(view->type == ROOTS_XWAYLAND_VIEW); + + wlr_xwayland_surface_set_maximized(view->desktop->xwayland, + view->xwayland_surface, maximized); +} + static void handle_destroy(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, destroy); @@ -161,6 +168,17 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, cursor, view, e->edges); } +static void handle_request_maximize(struct wl_listener *listener, void *data) { + struct roots_xwayland_surface *roots_surface = + wl_container_of(listener, roots_surface, request_resize); + struct roots_view *view = roots_surface->view; + struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; + + bool maximized = xwayland_surface->maximized_vert && + xwayland_surface->maximized_horz; + view_maximize(view, maximized); +} + static void handle_map_notify(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, map_notify); @@ -202,24 +220,24 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { if (roots_surface == NULL) { return; } + roots_surface->destroy.notify = handle_destroy; wl_signal_add(&surface->events.destroy, &roots_surface->destroy); - roots_surface->request_configure.notify = handle_request_configure; wl_signal_add(&surface->events.request_configure, &roots_surface->request_configure); - roots_surface->map_notify.notify = handle_map_notify; wl_signal_add(&surface->events.map_notify, &roots_surface->map_notify); - roots_surface->unmap_notify.notify = handle_unmap_notify; wl_signal_add(&surface->events.unmap_notify, &roots_surface->unmap_notify); - roots_surface->request_move.notify = handle_request_move; wl_signal_add(&surface->events.request_move, &roots_surface->request_move); - roots_surface->request_resize.notify = handle_request_resize; - wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); + wl_signal_add(&surface->events.request_resize, + &roots_surface->request_resize); + roots_surface->request_maximize.notify = handle_request_maximize; + wl_signal_add(&surface->events.request_maximize, + &roots_surface->request_maximize); struct roots_view *view = calloc(1, sizeof(struct roots_view)); if (view == NULL) { @@ -237,6 +255,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->resize = resize; view->move = move; view->move_resize = move_resize; + view->maximize = maximize; view->close = close; roots_surface->view = view; wlr_list_add(desktop->views, view); -- cgit v1.2.3 From c680ace5e8209d573e7ce2d676bbf5fe1b4ff894 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 8 Nov 2017 20:25:02 -0500 Subject: rootston: remove old cursor implementation --- rootston/cursor.c | 578 ++++++++++++++---------------------------------- rootston/meson.build | 3 +- rootston/roots_cursor.c | 366 ------------------------------ 3 files changed, 171 insertions(+), 776 deletions(-) delete mode 100644 rootston/roots_cursor.c diff --git a/rootston/cursor.c b/rootston/cursor.c index 64277464..c8abe098 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -1,152 +1,98 @@ #define _XOPEN_SOURCE 700 #include -#include -#include -#include #include -#include #ifdef __linux__ #include #elif __FreeBSD__ #include #endif -#include -#include #include -#include -#include "rootston/config.h" -#include "rootston/input.h" -#include "rootston/desktop.h" -#include "rootston/view.h" -#include "rootston/keyboard.h" -#include "rootston/seat.h" - -const struct roots_input_event *get_input_event(struct roots_input *input, - uint32_t serial) { - size_t len = sizeof(input->input_events) / sizeof(*input->input_events); - for (size_t i = 0; i < len; ++i) { - if (input->input_events[i].cursor - && input->input_events[i].serial == serial) { - return &input->input_events[i]; - } - } - return NULL; -} - -static void cursor_set_xcursor_image(struct roots_input *input, - struct wlr_xcursor_image *image) { - wlr_cursor_set_image(input->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); -} +#include "rootston/xcursor.h" +#include "rootston/cursor.h" -void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view) { - input->mode = ROOTS_CURSOR_MOVE; - input->offs_x = cursor->x; - input->offs_y = cursor->y; - input->view_x = view->x; - input->view_y = view->y; - wlr_seat_pointer_clear_focus(input->wl_seat); - - struct wlr_xcursor *xcursor = get_move_xcursor(input->xcursor_theme); - if (xcursor != NULL) { - cursor_set_xcursor_image(input, xcursor->images[0]); +struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { + struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); + if (!cursor) { + return NULL; + } + cursor->cursor = wlr_cursor_create(); + if (!cursor->cursor) { + return NULL; } + + return cursor; } -void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view, uint32_t edges) { - input->mode = ROOTS_CURSOR_RESIZE; - input->offs_x = cursor->x; - input->offs_y = cursor->y; - input->view_x = view->x; - input->view_y = view->y; - struct wlr_box size; - view_get_size(view, &size); - input->view_width = size.width; - input->view_height = size.height; - input->resize_edges = edges; - wlr_seat_pointer_clear_focus(input->wl_seat); - - struct wlr_xcursor *xcursor = get_resize_xcursor(input->xcursor_theme, edges); - if (xcursor != NULL) { - cursor_set_xcursor_image(input, xcursor->images[0]); - } +void roots_cursor_destroy(struct roots_cursor *cursor) { + // TODO } -void view_begin_rotate(struct roots_input *input, struct wlr_cursor *cursor, - struct roots_view *view) { - input->mode = ROOTS_CURSOR_ROTATE; - input->offs_x = cursor->x; - input->offs_y = cursor->y; - input->view_rotation = view->rotation; - wlr_seat_pointer_clear_focus(input->wl_seat); - - struct wlr_xcursor *xcursor = get_rotate_xcursor(input->xcursor_theme); - if (xcursor != NULL) { - cursor_set_xcursor_image(input, xcursor->images[0]); - } +static void cursor_set_xcursor_image(struct roots_cursor *cursor, + struct wlr_xcursor_image *image) { + wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y); } -void cursor_update_position(struct roots_input *input, uint32_t time) { - struct roots_desktop *desktop = input->server->desktop; +static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { + struct roots_desktop *desktop = cursor->seat->input->server->desktop; + struct roots_seat *seat = cursor->seat; struct roots_view *view; struct wlr_surface *surface; double sx, sy; - switch (input->mode) { + switch (cursor->mode) { case ROOTS_CURSOR_PASSTHROUGH: - view = view_at(desktop, input->cursor->x, input->cursor->y, + view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); - bool set_compositor_cursor = !view && input->cursor_client; + bool set_compositor_cursor = !view && cursor->cursor_client; if (view) { struct wl_client *view_client = wl_resource_get_client(view->wlr_surface->resource); - set_compositor_cursor = view_client != input->cursor_client; + set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(input->xcursor_theme); - cursor_set_xcursor_image(input, xcursor->images[0]); - input->cursor_client = NULL; + struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); + cursor_set_xcursor_image(cursor, xcursor->images[0]); + cursor->cursor_client = NULL; } if (view) { - wlr_seat_pointer_notify_enter(input->wl_seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(input->wl_seat, time, sx, sy); + wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); } else { - wlr_seat_pointer_clear_focus(input->wl_seat); + wlr_seat_pointer_clear_focus(seat->seat); } break; case ROOTS_CURSOR_MOVE: - if (input->active_view) { - double dx = input->cursor->x - input->offs_x; - double dy = input->cursor->y - input->offs_y; - view_move(input->active_view, input->view_x + dx, - input->view_y + dy); + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + view_move(seat->focus, cursor->view_x + dx, + cursor->view_y + dy); } break; case ROOTS_CURSOR_RESIZE: - if (input->active_view) { - double dx = input->cursor->x - input->offs_x; - double dy = input->cursor->y - input->offs_y; - double active_x = input->active_view->x; - double active_y = input->active_view->y; - int width = input->view_width; - int height = input->view_height; - if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { - active_y = input->view_y + dy; + if (seat->focus) { + double dx = cursor->cursor->x - cursor->offs_x; + double dy = cursor->cursor->y - cursor->offs_y; + double active_x = seat->focus->x; + double active_y = seat->focus->y; + int width = cursor->view_width; + int height = cursor->view_height; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { + active_y = cursor->view_y + dy; height -= dy; if (height < 0) { active_y += height; } - } else if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { height += dy; } - if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { - active_x = input->view_x + dx; + if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { + active_x = cursor->view_x + dx; width -= dx; if (width < 0) { active_x += width; } - } else if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { + } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { width += dx; } @@ -157,132 +103,51 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { height = 0; } - if (active_x != input->active_view->x || - active_y != input->active_view->y) { - view_move_resize(input->active_view, active_x, active_y, + if (active_x != seat->focus->x || + active_y != seat->focus->y) { + view_move_resize(seat->focus, active_x, active_y, width, height); } else { - view_resize(input->active_view, width, height); + view_resize(seat->focus, width, height); } } break; case ROOTS_CURSOR_ROTATE: - if (input->active_view) { - struct roots_view *view = input->active_view; + if (seat->focus) { + struct roots_view *view = seat->focus; int ox = view->x + view->wlr_surface->current->width/2, oy = view->y + view->wlr_surface->current->height/2; - int ux = input->offs_x - ox, - uy = input->offs_y - oy; - int vx = input->cursor->x - ox, - vy = input->cursor->y - oy; + int ux = cursor->offs_x - ox, + uy = cursor->offs_y - oy; + int vx = cursor->cursor->x - ox, + vy = cursor->cursor->y - oy; float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); int steps = 12; angle = round(angle/M_PI*steps) / (steps/M_PI); - view->rotation = input->view_rotation + angle; + view->rotation = cursor->view_rotation + angle; } break; } -} - -void set_view_focus(struct roots_input *input, struct roots_desktop *desktop, - struct roots_view *view) { - if (input->active_view == view) { - return; - } - input->active_view = view; - input->mode = ROOTS_CURSOR_PASSTHROUGH; - if (!view) { - return; - } - - if (view->type == ROOTS_XWAYLAND_VIEW && - view->xwayland_surface->override_redirect) { - return; - } - - size_t index = 0; - for (size_t i = 0; i < desktop->views->length; ++i) { - struct roots_view *_view = desktop->views->items[i]; - if (_view != view) { - view_activate(_view, false); - } else { - index = i; - } - } - view_activate(view, true); - // TODO: list_swap - wlr_list_del(desktop->views, index); - wlr_list_add(desktop->views, view); - wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); -} - -static void handle_cursor_motion(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_motion); - struct wlr_event_pointer_motion *event = data; - wlr_cursor_move(input->cursor, event->device, - event->delta_x, event->delta_y); - cursor_update_position(input, event->time_msec); -} - -static void handle_cursor_motion_absolute(struct wl_listener *listener, - void *data) { - struct roots_input *input = wl_container_of(listener, - input, cursor_motion_absolute); - struct wlr_event_pointer_motion_absolute *event = data; - wlr_cursor_warp_absolute(input->cursor, event->device, - event->x_mm / event->width_mm, event->y_mm / event->height_mm); - cursor_update_position(input, event->time_msec); -} - -static void handle_cursor_axis(struct wl_listener *listener, void *data) { - struct roots_input *input = - wl_container_of(listener, input, cursor_axis); - struct wlr_event_pointer_axis *event = data; - wlr_seat_pointer_notify_axis(input->wl_seat, event->time_msec, - event->orientation, event->delta); -} - -static bool is_meta_pressed(struct roots_input *input, - struct wlr_input_device *device) { - uint32_t meta_key = 0; - struct keyboard_config *config; - if ((config = config_get_keyboard(input->server->config, device))) { - meta_key = config->meta_key; - } else if (!meta_key && (config = config_get_keyboard(input->server->config, - NULL))) { - meta_key = config->meta_key; - } - if (meta_key == 0) { - return false; - } - struct roots_keyboard *keyboard; - wl_list_for_each(keyboard, &input->keyboards, link) { - uint32_t modifiers = - wlr_keyboard_get_modifiers(keyboard->device->keyboard); - if ((modifiers ^ meta_key) == 0) { - return true; - } - } - return false; } -static void do_cursor_button_press(struct roots_input *input, - struct wlr_cursor *cursor, struct wlr_input_device *device, - uint32_t time, uint32_t button, uint32_t state) { - struct roots_desktop *desktop = input->server->desktop; +static void roots_cursor_press_button(struct roots_cursor *cursor, + struct wlr_input_device *device, uint32_t time, uint32_t button, + uint32_t state) { + struct roots_seat *seat = cursor->seat; + struct roots_desktop *desktop = seat->input->server->desktop; struct wlr_surface *surface; double sx, sy; struct roots_view *view = view_at(desktop, - input->cursor->x, input->cursor->y, &surface, &sx, &sy); + cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); - if (state == WLR_BUTTON_PRESSED && view && is_meta_pressed(input, device)) { - set_view_focus(input, desktop, view); + if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { + roots_seat_focus_view(seat, view); uint32_t edges; switch (button) { case BTN_LEFT: - view_begin_move(input, cursor, view); + roots_seat_begin_move(seat, view); break; case BTN_RIGHT: edges = 0; @@ -296,117 +161,146 @@ static void do_cursor_button_press(struct roots_input *input, } else { edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; } - view_begin_resize(input, cursor, view, edges); + roots_seat_begin_resize(seat, view, edges); break; case BTN_MIDDLE: - view_begin_rotate(input, cursor, view); + roots_seat_begin_rotate(seat, view); break; } return; } - uint32_t serial = wlr_seat_pointer_notify_button(input->wl_seat, time, button, - state); + uint32_t serial = + wlr_seat_pointer_notify_button(seat->seat, time, button, state); int i; switch (state) { case WLR_BUTTON_RELEASED: - set_view_focus(input, desktop, NULL); - cursor_update_position(input, time); + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_position(cursor, time); break; case WLR_BUTTON_PRESSED: - i = input->input_events_idx; - input->input_events[i].serial = serial; - input->input_events[i].cursor = cursor; - input->input_events[i].device = device; - input->input_events_idx = (i + 1) - % (sizeof(input->input_events) / sizeof(input->input_events[0])); - set_view_focus(input, desktop, view); + i = cursor->input_events_idx; + cursor->input_events[i].serial = serial; + cursor->input_events[i].cursor = cursor->cursor; + cursor->input_events[i].device = device; + cursor->input_events_idx = (i + 1) + % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); + roots_seat_focus_view(seat, view); break; } } -static void handle_cursor_button(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_button); - struct wlr_event_pointer_button *event = data; - do_cursor_button_press(input, input->cursor, event->device, - event->time_msec, event->button, event->state); +void roots_cursor_handle_motion(struct roots_cursor *cursor, + struct wlr_event_pointer_motion *event) { + wlr_cursor_move(cursor->cursor, event->device, + event->delta_x, event->delta_y); + roots_cursor_update_position(cursor, event->time_msec); +} + +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); + roots_cursor_update_position(cursor, event->time_msec); +} + +void roots_cursor_handle_button(struct roots_cursor *cursor, + struct wlr_event_pointer_button *event) { + roots_cursor_press_button(cursor, event->device, event->time_msec, + event->button, event->state); } -static void handle_touch_down(struct wl_listener *listener, void *data) { - struct wlr_event_touch_down *event = data; - struct roots_input *input = - wl_container_of(listener, input, cursor_touch_down); +void roots_cursor_handle_axis(struct roots_cursor *cursor, + struct wlr_event_pointer_axis *event) { + wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, + event->orientation, event->delta); +} + +void roots_cursor_handle_touch_down(struct roots_cursor *cursor, + struct wlr_event_touch_down *event) { struct roots_touch_point *point = calloc(1, sizeof(struct roots_touch_point)); + if (!point) { + wlr_log(L_ERROR, "could not allocate memory for touch point"); + return; + } + point->device = event->device->data; point->slot = event->slot; point->x = event->x_mm / event->width_mm; point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(input->cursor, event->device, point->x, point->y); - cursor_update_position(input, event->time_msec); - wl_list_insert(&input->touch_points, &point->link); - do_cursor_button_press(input, input->cursor, event->device, + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); + roots_cursor_update_position(cursor, event->time_msec); + wl_list_insert(&cursor->touch_points, &point->link); + roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, 1); } -static void handle_touch_up(struct wl_listener *listener, void *data) { - struct wlr_event_touch_up *event = data; - struct roots_input *input = - wl_container_of(listener, input, cursor_touch_up); +void roots_cursor_handle_touch_up(struct roots_cursor *cursor, + struct wlr_event_touch_up *event) { struct roots_touch_point *point; - wl_list_for_each(point, &input->touch_points, link) { + wl_list_for_each(point, &cursor->touch_points, link) { if (point->slot == event->slot) { wl_list_remove(&point->link); + free(point); break; } } - do_cursor_button_press(input, input->cursor, event->device, + roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, 0); } -static void handle_touch_motion(struct wl_listener *listener, void *data) { - struct wlr_event_touch_motion *event = data; - struct roots_input *input = - wl_container_of(listener, input, cursor_touch_motion); +void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, + struct wlr_event_touch_motion *event) { struct roots_touch_point *point; - wl_list_for_each(point, &input->touch_points, link) { + wl_list_for_each(point, &cursor->touch_points, link) { if (point->slot == event->slot) { point->x = event->x_mm / event->width_mm; point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(input->cursor, event->device, + wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); - cursor_update_position(input, event->time_msec); + roots_cursor_update_position(cursor, event->time_msec); break; } } } -static void handle_tool_axis(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_tool_axis); - struct wlr_event_tablet_tool_axis *event = data; +void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_axis *event) { if ((event->updated_axes & WLR_TABLET_TOOL_AXIS_X) && (event->updated_axes & WLR_TABLET_TOOL_AXIS_Y)) { - wlr_cursor_warp_absolute(input->cursor, event->device, + wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x_mm / event->width_mm, event->y_mm / event->height_mm); - cursor_update_position(input, event->time_msec); + roots_cursor_update_position(cursor, event->time_msec); } } -static void handle_tool_tip(struct wl_listener *listener, void *data) { - struct roots_input *input = wl_container_of(listener, input, cursor_tool_tip); - struct wlr_event_tablet_tool_tip *event = data; - do_cursor_button_press(input, input->cursor, event->device, +void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, + struct wlr_event_tablet_tool_tip *event) { + roots_cursor_press_button(cursor, event->device, event->time_msec, BTN_LEFT, event->state); } -static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_destroy); - wl_list_remove(&drag_icon->link); - wl_list_remove(&drag_icon->surface_destroy.link); - wl_list_remove(&drag_icon->surface_commit.link); - free(drag_icon); +void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, + struct wlr_seat_pointer_request_set_cursor_event *event) { + struct wlr_surface *focused_surface = + event->seat_client->seat->pointer_state.focused_surface; + bool has_focused = focused_surface != NULL && focused_surface->resource != NULL; + struct wl_client *focused_client = NULL; + if (has_focused) { + focused_client = wl_resource_get_client(focused_surface->resource); + } + if (event->seat_client->client != focused_client || + cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { + wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); + return; + } + + wlr_log(L_DEBUG, "Setting client cursor"); + wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, + event->hotspot_y); + cursor->cursor_client = event->seat_client->client; } static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { @@ -416,17 +310,23 @@ static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { drag_icon->sy += drag_icon->surface->current->sy; } -static void handle_pointer_grab_begin(struct wl_listener *listener, - void *data) { - struct roots_input *input = - wl_container_of(listener, input, pointer_grab_begin); - struct wlr_seat_pointer_grab *grab = data; +static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { + struct roots_drag_icon *drag_icon = + wl_container_of(listener, drag_icon, surface_destroy); + wl_list_remove(&drag_icon->link); + wl_list_remove(&drag_icon->surface_destroy.link); + wl_list_remove(&drag_icon->surface_commit.link); + free(drag_icon); +} +void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { + struct roots_seat *seat = cursor->seat; if (grab->interface == &wlr_data_device_pointer_drag_interface) { struct wlr_drag *drag = grab->data; if (drag->icon) { struct roots_drag_icon *iter_icon; - wl_list_for_each(iter_icon, &input->drag_icons, link) { + wl_list_for_each(iter_icon, &seat->drag_icons, link) { if (iter_icon->surface == drag->icon) { // already in the list return; @@ -437,7 +337,7 @@ static void handle_pointer_grab_begin(struct wl_listener *listener, calloc(1, sizeof(struct roots_drag_icon)); drag_icon->mapped = true; drag_icon->surface = drag->icon; - wl_list_insert(&input->drag_icons, &drag_icon->link); + wl_list_insert(&seat->drag_icons, &drag_icon->link); wl_signal_add(&drag->icon->events.destroy, &drag_icon->surface_destroy); @@ -450,155 +350,17 @@ static void handle_pointer_grab_begin(struct wl_listener *listener, } } -static void handle_pointer_grab_end(struct wl_listener *listener, void *data) { - struct roots_input *input = - wl_container_of(listener, input, pointer_grab_end); - struct wlr_seat_pointer_grab *grab = data; - +void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, + struct wlr_seat_pointer_grab *grab) { if (grab->interface == &wlr_data_device_pointer_drag_interface) { struct wlr_drag *drag = grab->data; struct roots_drag_icon *icon; - wl_list_for_each(icon, &input->drag_icons, link) { + wl_list_for_each(icon, &cursor->seat->drag_icons, link) { if (icon->surface == drag->icon) { icon->mapped = false; } } } - cursor_update_position(input, 0); -} - -static void handle_request_set_cursor(struct wl_listener *listener, - void *data) { - struct roots_input *input = wl_container_of(listener, input, - request_set_cursor); - struct wlr_seat_pointer_request_set_cursor_event *event = data; - - struct wlr_surface *focused_surface = - event->seat_client->seat->pointer_state.focused_surface; - bool ok = focused_surface != NULL && focused_surface->resource != NULL; - if (ok) { - struct wl_client *focused_client = - wl_resource_get_client(focused_surface->resource); - ok = event->seat_client->client == focused_client; - } - if (!ok || input->mode != ROOTS_CURSOR_PASSTHROUGH) { - wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); - return; - } - - wlr_log(L_DEBUG, "Setting client cursor"); - wlr_cursor_set_surface(input->cursor, event->surface, event->hotspot_x, - event->hotspot_y); - input->cursor_client = event->seat_client->client; -} - -void cursor_initialize(struct roots_input *input) { - struct wlr_cursor *cursor = input->cursor; - - // TODO: Does this belong here - wl_list_init(&input->touch_points); - - wl_signal_add(&cursor->events.motion, &input->cursor_motion); - input->cursor_motion.notify = handle_cursor_motion; - - wl_signal_add(&cursor->events.motion_absolute, - &input->cursor_motion_absolute); - input->cursor_motion_absolute.notify = handle_cursor_motion_absolute; - - wl_signal_add(&cursor->events.button, &input->cursor_button); - input->cursor_button.notify = handle_cursor_button; - - wl_signal_add(&cursor->events.axis, &input->cursor_axis); - input->cursor_axis.notify = handle_cursor_axis; - - wl_signal_add(&cursor->events.touch_down, &input->cursor_touch_down); - input->cursor_touch_down.notify = handle_touch_down; - - wl_signal_add(&cursor->events.touch_up, &input->cursor_touch_up); - input->cursor_touch_up.notify = handle_touch_up; - - wl_signal_add(&cursor->events.touch_motion, &input->cursor_touch_motion); - input->cursor_touch_motion.notify = handle_touch_motion; - - wl_signal_add(&cursor->events.tablet_tool_axis, &input->cursor_tool_axis); - input->cursor_tool_axis.notify = handle_tool_axis; - - wl_signal_add(&cursor->events.tablet_tool_tip, &input->cursor_tool_tip); - input->cursor_tool_tip.notify = handle_tool_tip; - - wl_signal_add(&input->wl_seat->events.pointer_grab_end, &input->pointer_grab_end); - input->pointer_grab_end.notify = handle_pointer_grab_end; - - wl_signal_add(&input->wl_seat->events.pointer_grab_begin, &input->pointer_grab_begin); - input->pointer_grab_begin.notify = handle_pointer_grab_begin; - - wl_list_init(&input->request_set_cursor.link); - - wl_signal_add(&input->wl_seat->events.request_set_cursor, - &input->request_set_cursor); - input->request_set_cursor.notify = handle_request_set_cursor; -} - -static void reset_device_mappings(struct roots_config *config, - struct wlr_cursor *cursor, struct wlr_input_device *device) { - wlr_cursor_map_input_to_output(cursor, device, NULL); - struct device_config *dconfig; - if ((dconfig = config_get_device(config, device))) { - wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); - } -} - -static void set_device_output_mappings(struct roots_config *config, - struct wlr_cursor *cursor, struct wlr_output *output, - struct wlr_input_device *device) { - struct device_config *dconfig; - dconfig = config_get_device(config, device); - if (dconfig && dconfig->mapped_output && - strcmp(dconfig->mapped_output, output->name) == 0) { - wlr_cursor_map_input_to_output(cursor, device, output); - } -} - -void cursor_load_config(struct roots_config *config, - struct wlr_cursor *cursor, - struct roots_input *input, - struct roots_desktop *desktop) { - struct roots_pointer *pointer; - struct roots_touch *touch; - struct roots_tablet_tool *tablet_tool; - struct roots_output *output; - - // reset mappings - wlr_cursor_map_to_output(cursor, NULL); - wl_list_for_each(pointer, &input->pointers, link) { - reset_device_mappings(config, cursor, pointer->device); - } - wl_list_for_each(touch, &input->touch, link) { - reset_device_mappings(config, cursor, touch->device); - } - wl_list_for_each(tablet_tool, &input->tablet_tools, link) { - reset_device_mappings(config, cursor, tablet_tool->device); - } - - // configure device to output mappings - const char *mapped_output = config->cursor.mapped_output; - wl_list_for_each(output, &desktop->outputs, link) { - if (mapped_output && strcmp(mapped_output, output->wlr_output->name) == 0) { - wlr_cursor_map_to_output(cursor, output->wlr_output); - } - - wl_list_for_each(pointer, &input->pointers, link) { - set_device_output_mappings(config, cursor, output->wlr_output, - pointer->device); - } - wl_list_for_each(tablet_tool, &input->tablet_tools, link) { - set_device_output_mappings(config, cursor, output->wlr_output, - tablet_tool->device); - } - wl_list_for_each(touch, &input->touch, link) { - set_device_output_mappings(config, cursor, output->wlr_output, - touch->device); - } - } + roots_cursor_update_position(cursor, 0); } diff --git a/rootston/meson.build b/rootston/meson.build index 062f56fc..9c543c4f 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,7 +1,6 @@ sources = [ 'config.c', - #'cursor.c', - 'roots_cursor.c', + 'cursor.c', 'desktop.c', 'ini.c', 'input.c', diff --git a/rootston/roots_cursor.c b/rootston/roots_cursor.c deleted file mode 100644 index c8abe098..00000000 --- a/rootston/roots_cursor.c +++ /dev/null @@ -1,366 +0,0 @@ -#define _XOPEN_SOURCE 700 -#include -#include -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#endif -#include -#include "rootston/xcursor.h" -#include "rootston/cursor.h" - -struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { - struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); - if (!cursor) { - return NULL; - } - cursor->cursor = wlr_cursor_create(); - if (!cursor->cursor) { - return NULL; - } - - return cursor; -} - -void roots_cursor_destroy(struct roots_cursor *cursor) { - // TODO -} - -static void cursor_set_xcursor_image(struct roots_cursor *cursor, - struct wlr_xcursor_image *image) { - wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); -} - -static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { - struct roots_desktop *desktop = cursor->seat->input->server->desktop; - struct roots_seat *seat = cursor->seat; - struct roots_view *view; - struct wlr_surface *surface; - double sx, sy; - switch (cursor->mode) { - case ROOTS_CURSOR_PASSTHROUGH: - view = view_at(desktop, cursor->cursor->x, cursor->cursor->y, - &surface, &sx, &sy); - bool set_compositor_cursor = !view && cursor->cursor_client; - if (view) { - struct wl_client *view_client = - wl_resource_get_client(view->wlr_surface->resource); - set_compositor_cursor = view_client != cursor->cursor_client; - } - if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); - cursor_set_xcursor_image(cursor, xcursor->images[0]); - cursor->cursor_client = NULL; - } - if (view) { - wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(seat->seat, time, sx, sy); - } else { - wlr_seat_pointer_clear_focus(seat->seat); - } - break; - case ROOTS_CURSOR_MOVE: - if (seat->focus) { - double dx = cursor->cursor->x - cursor->offs_x; - double dy = cursor->cursor->y - cursor->offs_y; - view_move(seat->focus, cursor->view_x + dx, - cursor->view_y + dy); - } - break; - case ROOTS_CURSOR_RESIZE: - if (seat->focus) { - double dx = cursor->cursor->x - cursor->offs_x; - double dy = cursor->cursor->y - cursor->offs_y; - double active_x = seat->focus->x; - double active_y = seat->focus->y; - int width = cursor->view_width; - int height = cursor->view_height; - if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { - active_y = cursor->view_y + dy; - height -= dy; - if (height < 0) { - active_y += height; - } - } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { - height += dy; - } - if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { - active_x = cursor->view_x + dx; - width -= dx; - if (width < 0) { - active_x += width; - } - } else if (cursor->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { - width += dx; - } - - if (width < 0) { - width = 0; - } - if (height < 0) { - height = 0; - } - - if (active_x != seat->focus->x || - active_y != seat->focus->y) { - view_move_resize(seat->focus, active_x, active_y, - width, height); - } else { - view_resize(seat->focus, width, height); - } - } - break; - case ROOTS_CURSOR_ROTATE: - if (seat->focus) { - struct roots_view *view = seat->focus; - int ox = view->x + view->wlr_surface->current->width/2, - oy = view->y + view->wlr_surface->current->height/2; - int ux = cursor->offs_x - ox, - uy = cursor->offs_y - oy; - int vx = cursor->cursor->x - ox, - vy = cursor->cursor->y - oy; - float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); - int steps = 12; - angle = round(angle/M_PI*steps) / (steps/M_PI); - view->rotation = cursor->view_rotation + angle; - } - break; - } - -} - -static void roots_cursor_press_button(struct roots_cursor *cursor, - struct wlr_input_device *device, uint32_t time, uint32_t button, - uint32_t state) { - struct roots_seat *seat = cursor->seat; - struct roots_desktop *desktop = seat->input->server->desktop; - struct wlr_surface *surface; - double sx, sy; - struct roots_view *view = view_at(desktop, - cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); - - if (state == WLR_BUTTON_PRESSED && view && roots_seat_has_meta_pressed(seat)) { - roots_seat_focus_view(seat, view); - - uint32_t edges; - switch (button) { - case BTN_LEFT: - roots_seat_begin_move(seat, view); - break; - case BTN_RIGHT: - edges = 0; - if (sx < view->wlr_surface->current->width/2) { - edges |= ROOTS_CURSOR_RESIZE_EDGE_LEFT; - } else { - edges |= ROOTS_CURSOR_RESIZE_EDGE_RIGHT; - } - if (sy < view->wlr_surface->current->height/2) { - edges |= ROOTS_CURSOR_RESIZE_EDGE_TOP; - } else { - edges |= ROOTS_CURSOR_RESIZE_EDGE_BOTTOM; - } - roots_seat_begin_resize(seat, view, edges); - break; - case BTN_MIDDLE: - roots_seat_begin_rotate(seat, view); - break; - } - return; - } - - uint32_t serial = - wlr_seat_pointer_notify_button(seat->seat, time, button, state); - - int i; - switch (state) { - case WLR_BUTTON_RELEASED: - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; - roots_cursor_update_position(cursor, time); - break; - case WLR_BUTTON_PRESSED: - i = cursor->input_events_idx; - cursor->input_events[i].serial = serial; - cursor->input_events[i].cursor = cursor->cursor; - cursor->input_events[i].device = device; - cursor->input_events_idx = (i + 1) - % (sizeof(cursor->input_events) / sizeof(cursor->input_events[0])); - roots_seat_focus_view(seat, view); - break; - } -} - -void roots_cursor_handle_motion(struct roots_cursor *cursor, - struct wlr_event_pointer_motion *event) { - wlr_cursor_move(cursor->cursor, event->device, - event->delta_x, event->delta_y); - roots_cursor_update_position(cursor, event->time_msec); -} - -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); - roots_cursor_update_position(cursor, event->time_msec); -} - -void roots_cursor_handle_button(struct roots_cursor *cursor, - struct wlr_event_pointer_button *event) { - roots_cursor_press_button(cursor, event->device, event->time_msec, - event->button, event->state); -} - -void roots_cursor_handle_axis(struct roots_cursor *cursor, - struct wlr_event_pointer_axis *event) { - wlr_seat_pointer_notify_axis(cursor->seat->seat, event->time_msec, - event->orientation, event->delta); -} - -void roots_cursor_handle_touch_down(struct roots_cursor *cursor, - struct wlr_event_touch_down *event) { - struct roots_touch_point *point = - calloc(1, sizeof(struct roots_touch_point)); - if (!point) { - wlr_log(L_ERROR, "could not allocate memory for touch point"); - return; - } - - point->device = event->device->data; - point->slot = event->slot; - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(cursor->cursor, event->device, point->x, point->y); - roots_cursor_update_position(cursor, event->time_msec); - wl_list_insert(&cursor->touch_points, &point->link); - roots_cursor_press_button(cursor, event->device, - event->time_msec, BTN_LEFT, 1); -} - -void roots_cursor_handle_touch_up(struct roots_cursor *cursor, - struct wlr_event_touch_up *event) { - struct roots_touch_point *point; - wl_list_for_each(point, &cursor->touch_points, link) { - if (point->slot == event->slot) { - wl_list_remove(&point->link); - free(point); - break; - } - } - roots_cursor_press_button(cursor, event->device, - event->time_msec, BTN_LEFT, 0); -} - -void roots_cursor_handle_touch_motion(struct roots_cursor *cursor, - struct wlr_event_touch_motion *event) { - struct roots_touch_point *point; - wl_list_for_each(point, &cursor->touch_points, link) { - if (point->slot == event->slot) { - point->x = event->x_mm / event->width_mm; - point->y = event->y_mm / event->height_mm; - wlr_cursor_warp_absolute(cursor->cursor, event->device, - point->x, point->y); - roots_cursor_update_position(cursor, event->time_msec); - break; - } - } -} - -void roots_cursor_handle_tool_axis(struct roots_cursor *cursor, - struct wlr_event_tablet_tool_axis *event) { - 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); - roots_cursor_update_position(cursor, event->time_msec); - } -} - -void roots_cursor_handle_tool_tip(struct roots_cursor *cursor, - struct wlr_event_tablet_tool_tip *event) { - roots_cursor_press_button(cursor, event->device, - event->time_msec, BTN_LEFT, event->state); -} - -void roots_cursor_handle_request_set_cursor(struct roots_cursor *cursor, - struct wlr_seat_pointer_request_set_cursor_event *event) { - struct wlr_surface *focused_surface = - event->seat_client->seat->pointer_state.focused_surface; - bool has_focused = focused_surface != NULL && focused_surface->resource != NULL; - struct wl_client *focused_client = NULL; - if (has_focused) { - focused_client = wl_resource_get_client(focused_surface->resource); - } - if (event->seat_client->client != focused_client || - cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { - wlr_log(L_DEBUG, "Denying request to set cursor from unfocused client"); - return; - } - - wlr_log(L_DEBUG, "Setting client cursor"); - wlr_cursor_set_surface(cursor->cursor, event->surface, event->hotspot_x, - event->hotspot_y); - cursor->cursor_client = event->seat_client->client; -} - -static void handle_drag_icon_commit(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_commit); - drag_icon->sx += drag_icon->surface->current->sx; - drag_icon->sy += drag_icon->surface->current->sy; -} - -static void handle_drag_icon_destroy(struct wl_listener *listener, void *data) { - struct roots_drag_icon *drag_icon = - wl_container_of(listener, drag_icon, surface_destroy); - wl_list_remove(&drag_icon->link); - wl_list_remove(&drag_icon->surface_destroy.link); - wl_list_remove(&drag_icon->surface_commit.link); - free(drag_icon); -} - -void roots_cursor_handle_pointer_grab_begin(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab) { - struct roots_seat *seat = cursor->seat; - if (grab->interface == &wlr_data_device_pointer_drag_interface) { - struct wlr_drag *drag = grab->data; - if (drag->icon) { - struct roots_drag_icon *iter_icon; - wl_list_for_each(iter_icon, &seat->drag_icons, link) { - if (iter_icon->surface == drag->icon) { - // already in the list - return; - } - } - - struct roots_drag_icon *drag_icon = - calloc(1, sizeof(struct roots_drag_icon)); - drag_icon->mapped = true; - drag_icon->surface = drag->icon; - wl_list_insert(&seat->drag_icons, &drag_icon->link); - - wl_signal_add(&drag->icon->events.destroy, - &drag_icon->surface_destroy); - drag_icon->surface_destroy.notify = handle_drag_icon_destroy; - - wl_signal_add(&drag->icon->events.commit, - &drag_icon->surface_commit); - drag_icon->surface_commit.notify = handle_drag_icon_commit; - } - } -} - -void roots_cursor_handle_pointer_grab_end(struct roots_cursor *cursor, - struct wlr_seat_pointer_grab *grab) { - if (grab->interface == &wlr_data_device_pointer_drag_interface) { - struct wlr_drag *drag = grab->data; - struct roots_drag_icon *icon; - wl_list_for_each(icon, &cursor->seat->drag_icons, link) { - if (icon->surface == drag->icon) { - icon->mapped = false; - } - } - } - - roots_cursor_update_position(cursor, 0); -} -- cgit v1.2.3 From 758514fe5d67d226290694208a34f90d1a857d8e Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 9 Nov 2017 11:21:55 +0100 Subject: Fix xwayland _NET_WM_STATE handling --- rootston/xwayland.c | 2 +- xwayland/xwm.c | 52 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 431586ba..1da61ec3 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -170,7 +170,7 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { static void handle_request_maximize(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = - wl_container_of(listener, roots_surface, request_resize); + wl_container_of(listener, roots_surface, request_maximize); struct roots_view *view = roots_surface->view; struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index f011587e..e5806d5b 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -823,41 +823,49 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm, if (!xsurface) { return; } + if (client_message->format != 32) { + return; + } - int maximized = xsurface_is_maximized(xsurface); + bool fullscreen = xsurface->fullscreen; + bool maximized = xsurface_is_maximized(xsurface); uint32_t action = client_message->data.data32[0]; - uint32_t property = client_message->data.data32[1]; + for (size_t i = 0; i < 2; ++i) { + uint32_t property = client_message->data.data32[1 + i]; - if (property == xwm->atoms[_NET_WM_STATE_FULLSCREEN] && - update_state(action, &xsurface->fullscreen)) { - xsurface_set_net_wm_state(xsurface); + if (property == xwm->atoms[_NET_WM_STATE_FULLSCREEN] && + update_state(action, &xsurface->fullscreen)) { + xsurface_set_net_wm_state(xsurface); + } else if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT] && + update_state(action, &xsurface->maximized_vert)) { + wlr_log(L_DEBUG, "cc sava"); + xsurface_set_net_wm_state(xsurface); + } else if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ] && + update_state(action, &xsurface->maximized_horz)) { + wlr_log(L_DEBUG, "mwa sava"); + xsurface_set_net_wm_state(xsurface); + } + } + // client_message->data.data32[3] is the source indication + // all other values are set to 0 + if (fullscreen != xsurface->fullscreen) { if (xsurface->fullscreen) { xsurface->saved_width = xsurface->width; xsurface->saved_height = xsurface->height; } wl_signal_emit(&xsurface->events.request_fullscreen, xsurface); - } else { - if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT] && - update_state(action, &xsurface->maximized_vert)) { - xsurface_set_net_wm_state(xsurface); - } + } - if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ] && - update_state(action, &xsurface->maximized_horz)) { - xsurface_set_net_wm_state(xsurface); + if (maximized != xsurface_is_maximized(xsurface)) { + if (xsurface_is_maximized(xsurface)) { + xsurface->saved_width = xsurface->width; + xsurface->saved_height = xsurface->height; } - if (maximized != xsurface_is_maximized(xsurface)) { - if (xsurface_is_maximized(xsurface)) { - xsurface->saved_width = xsurface->width; - xsurface->saved_height = xsurface->height; - } - - wl_signal_emit(&xsurface->events.request_maximize, xsurface); - } + wl_signal_emit(&xsurface->events.request_maximize, xsurface); } } @@ -1310,8 +1318,8 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xwm->atoms[_NET_ACTIVE_WINDOW], xwm->atoms[_NET_WM_MOVERESIZE], xwm->atoms[_NET_WM_STATE_FULLSCREEN], - xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ], xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT], + xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ], }; xcb_change_property(xwm->xcb_conn, XCB_PROP_MODE_REPLACE, -- cgit v1.2.3 From 75fd9b8426953d98c57fc0f598bf3a3ace602c0c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 9 Nov 2017 08:40:15 -0500 Subject: Remove extraneous keyboard send_enter --- rootston/desktop.c | 1 - 1 file changed, 1 deletion(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index df8a79f2..2448ffac 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -150,7 +150,6 @@ void view_setup(struct roots_view *view) { struct roots_input *input = view->desktop->server->input; view_center(view); set_view_focus(input, view->desktop, view); - wlr_seat_keyboard_notify_enter(input->wl_seat, view->wlr_surface); struct wlr_box before; view_get_size(view, &before); view_update_output(view, &before); -- cgit v1.2.3 From 26dadacb7199d28af672cca3f91713e173a41258 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 9 Nov 2017 20:06:05 +0100 Subject: Add wl_shell support for maximized views --- include/rootston/view.h | 3 ++- include/wlr/types/wlr_wl_shell.h | 2 ++ rootston/wl_shell.c | 28 ++++++++++++++++++++++++++++ types/wlr_wl_shell.c | 11 ++++------- xwayland/xwm.c | 2 -- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index f6ac0d23..1b0fb831 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -11,9 +11,10 @@ struct roots_wl_shell_surface { // TODO: Maybe destroy listener should go in roots_view struct wl_listener destroy; - struct wl_listener ping_timeout; struct wl_listener request_move; struct wl_listener request_resize; + struct wl_listener request_set_maximized; + struct wl_listener set_state; struct wl_listener surface_commit; }; diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 4e814817..1f0630f2 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -42,6 +42,8 @@ struct wlr_wl_shell_popup_grab { enum wlr_wl_shell_surface_state { WLR_WL_SHELL_SURFACE_STATE_NONE, WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL, + WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED, + WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN, WLR_WL_SHELL_SURFACE_STATE_TRANSIENT, WLR_WL_SHELL_SURFACE_STATE_POPUP, }; diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index e38eb697..3ac8fe61 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -49,6 +49,26 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, event->cursor, view, e->edges); } +static void handle_request_set_maximized(struct wl_listener *listener, + void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, request_set_maximized); + struct roots_view *view = roots_surface->view; + //struct wlr_wl_shell_surface_set_maximized_event *e = data; + view_maximize(view, true); +} + +static void handle_set_state(struct wl_listener *listener, void *data) { + struct roots_wl_shell_surface *roots_surface = + wl_container_of(listener, roots_surface, set_state); + struct roots_view *view = roots_surface->view; + struct wlr_wl_shell_surface *surface = view->wl_shell_surface; + if (view->maximized && + surface->state != WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED) { + view_maximize(view, false); + } +} + static void handle_surface_commit(struct wl_listener *listener, void *data) { // TODO do we need to do anything here? } @@ -60,6 +80,9 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&roots_surface->destroy.link); wl_list_remove(&roots_surface->request_move.link); wl_list_remove(&roots_surface->request_resize.link); + wl_list_remove(&roots_surface->request_set_maximized.link); + wl_list_remove(&roots_surface->set_state.link); + wl_list_remove(&roots_surface->surface_commit.link); view_destroy(roots_surface->view); free(roots_surface); } @@ -93,6 +116,11 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { roots_surface->request_resize.notify = handle_request_resize; wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); + roots_surface->request_set_maximized.notify = handle_request_set_maximized; + wl_signal_add(&surface->events.request_set_maximized, + &roots_surface->request_set_maximized); + roots_surface->set_state.notify = handle_set_state; + wl_signal_add(&surface->events.set_state, &roots_surface->set_state); roots_surface->surface_commit.notify = handle_surface_commit; wl_signal_add(&surface->surface->events.commit, &roots_surface->surface_commit); diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index fe61075e..f0287ba9 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -171,7 +171,6 @@ static void shell_surface_destroy_popup_state( } } - static void shell_surface_protocol_resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, enum wl_shell_surface_resize edges) { @@ -287,9 +286,8 @@ static void shell_surface_protocol_set_fullscreen(struct wl_client *client, output = wl_resource_get_user_data(output_resource); } - if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL) { - return; - } + shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN, + NULL, NULL); struct wlr_wl_shell_surface_set_fullscreen_event *event = calloc(1, sizeof(struct wlr_wl_shell_surface_set_fullscreen_event)); @@ -377,9 +375,8 @@ static void shell_surface_protocol_set_maximized(struct wl_client *client, output = wl_resource_get_user_data(output_resource); } - if (surface->state == WLR_WL_SHELL_SURFACE_STATE_TOPLEVEL) { - return; - } + shell_surface_set_state(surface, WLR_WL_SHELL_SURFACE_STATE_MAXIMIZED, + NULL, NULL); struct wlr_wl_shell_surface_set_maximized_event *event = calloc(1, sizeof(struct wlr_wl_shell_surface_set_maximized_event)); diff --git a/xwayland/xwm.c b/xwayland/xwm.c index e5806d5b..dff9fac2 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -839,11 +839,9 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm, xsurface_set_net_wm_state(xsurface); } else if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT] && update_state(action, &xsurface->maximized_vert)) { - wlr_log(L_DEBUG, "cc sava"); xsurface_set_net_wm_state(xsurface); } else if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ] && update_state(action, &xsurface->maximized_horz)) { - wlr_log(L_DEBUG, "mwa sava"); xsurface_set_net_wm_state(xsurface); } } -- cgit v1.2.3 From 0204f811b44a0a999666bc7601c9b38f7c5c1adb Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 9 Nov 2017 20:08:43 +0100 Subject: Remove xwayland view listeners on destroy --- rootston/xwayland.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 1da61ec3..b608b143 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -97,6 +97,10 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_container_of(listener, roots_surface, destroy); view_teardown(roots_surface->view); wl_list_remove(&roots_surface->destroy.link); + wl_list_remove(&roots_surface->request_configure.link); + wl_list_remove(&roots_surface->request_move.link); + wl_list_remove(&roots_surface->request_resize.link); + wl_list_remove(&roots_surface->request_maximize.link); wl_list_remove(&roots_surface->map_notify.link); wl_list_remove(&roots_surface->unmap_notify.link); view_destroy(roots_surface->view); -- cgit v1.2.3 From bf1b12a72500fb8cb41cbc60d29e602c25c97fc2 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 9 Nov 2017 21:41:11 +0100 Subject: Fix maximize delay in xdg-shell --- include/rootston/view.h | 1 + include/wlr/types/wlr_xdg_shell_v6.h | 2 ++ rootston/xdg_shell_v6.c | 19 ++++++++++++++----- types/wlr_xdg_shell_v6.c | 6 ++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index 1b0fb831..956ba1d3 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -27,6 +27,7 @@ struct roots_xdg_surface_v6 { struct wl_listener destroy; struct wl_listener request_move; struct wl_listener request_resize; + struct wl_listener request_maximize; }; struct roots_xwayland_surface { diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index b0de41e2..bc78428b 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -126,6 +126,8 @@ struct wlr_xdg_surface_v6 { struct wl_signal ack_configure; struct wl_signal ping_timeout; + struct wl_signal request_maximize; + struct wl_signal request_fullscreen; struct wl_signal request_minimize; struct wl_signal request_move; struct wl_signal request_resize; diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 45691d16..a86899be 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -128,9 +128,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { view_begin_resize(input, event->cursor, view, e->edges); } -static void handle_commit(struct wl_listener *listener, void *data) { +static void handle_request_maximize(struct wl_listener *listener, void *data) { struct roots_xdg_surface_v6 *roots_xdg_surface = - wl_container_of(listener, roots_xdg_surface, commit); + wl_container_of(listener, roots_xdg_surface, request_maximize); struct roots_view *view = roots_xdg_surface->view; struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; @@ -138,9 +138,15 @@ static void handle_commit(struct wl_listener *listener, void *data) { return; } - if (view->maximized != surface->toplevel_state->current.maximized) { - view_maximize(view, surface->toplevel_state->current.maximized); - } + view_maximize(view, surface->toplevel_state->next.maximized); +} + +static void handle_commit(struct wl_listener *listener, void *data) { + //struct roots_xdg_surface_v6 *roots_xdg_surface = + // wl_container_of(listener, roots_xdg_surface, commit); + //struct roots_view *view = roots_xdg_surface->view; + //struct wlr_xdg_surface_v6 *surface = view->xdg_surface_v6; + // TODO } static void handle_destroy(struct wl_listener *listener, void *data) { @@ -185,6 +191,9 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { roots_surface->request_resize.notify = handle_request_resize; wl_signal_add(&surface->events.request_resize, &roots_surface->request_resize); + roots_surface->request_maximize.notify = handle_request_maximize; + wl_signal_add(&surface->events.request_maximize, + &roots_surface->request_maximize); struct roots_view *view = calloc(1, sizeof(struct roots_view)); if (!view) { diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fc45bc17..c260fd5e 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -667,24 +667,28 @@ static void xdg_toplevel_protocol_set_maximized(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.maximized = true; + wl_signal_emit(&surface->events.request_maximize, surface); } static void xdg_toplevel_protocol_unset_maximized(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.maximized = false; + wl_signal_emit(&surface->events.request_maximize, surface); } static void xdg_toplevel_protocol_set_fullscreen(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.fullscreen = true; + wl_signal_emit(&surface->events.request_fullscreen, surface); } static void xdg_toplevel_protocol_unset_fullscreen(struct wl_client *client, struct wl_resource *resource) { struct wlr_xdg_surface_v6 *surface = wl_resource_get_user_data(resource); surface->toplevel_state->next.fullscreen = false; + wl_signal_emit(&surface->events.request_fullscreen, surface); } static void xdg_toplevel_protocol_set_minimized(struct wl_client *client, @@ -1146,6 +1150,8 @@ static void xdg_shell_get_xdg_surface(struct wl_client *wl_client, wl_list_init(&surface->configure_list); wl_list_init(&surface->popups); + wl_signal_init(&surface->events.request_maximize); + wl_signal_init(&surface->events.request_fullscreen); wl_signal_init(&surface->events.request_minimize); wl_signal_init(&surface->events.request_move); wl_signal_init(&surface->events.request_resize); -- cgit v1.2.3 From 739361aa70d61cbc9e062d6a90df09f258a1bbcb Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 17:29:28 -0500 Subject: wlr-keyboard: take out modifiers event struct (for now) --- backend/libinput/keyboard.c | 1 - backend/wayland/wl_seat.c | 12 ++---------- backend/x11/backend.c | 1 - include/rootston/keyboard.h | 3 +-- include/wlr/interfaces/wlr_keyboard.h | 3 ++- include/wlr/types/wlr_keyboard.h | 11 ----------- rootston/keyboard.c | 3 +-- rootston/seat.c | 3 +-- types/wlr_keyboard.c | 11 ++++++----- 9 files changed, 13 insertions(+), 35 deletions(-) diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 9a24c791..065d8ead 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -54,7 +54,6 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; - wlr_event.device = wlr_dev; wlr_event.time_msec = usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 74eaf9bd..a2da8df5 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -151,7 +151,6 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, assert(dev && dev->keyboard); struct wlr_event_keyboard_key wlr_event; - wlr_event.device = dev; wlr_event.keycode = key; wlr_event.state = state; wlr_event.time_msec = time; @@ -163,15 +162,8 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_locked, uint32_t group) { struct wlr_input_device *dev = data; assert(dev && dev->keyboard); - struct wlr_event_keyboard_modifiers wlr_event; - wlr_event.device = dev; - wlr_event.keyboard = dev->keyboard; - wlr_event.mods_depressed = mods_depressed; - wlr_event.mods_latched = mods_latched; - wlr_event.mods_locked = mods_locked; - wlr_event.group = group; - - wlr_keyboard_notify_modifiers(dev->keyboard, &wlr_event); + wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, + mods_locked, group); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index f76b314e..97b0dd8c 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -50,7 +50,6 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_KEY_RELEASE: { xcb_key_press_event_t *ev = (xcb_key_press_event_t *)event; struct wlr_event_keyboard_key key = { - .device = &x11->keyboard_dev, .time_msec = ev->time, .keycode = ev->detail - 8, .state = event->response_type == XCB_KEY_PRESS ? diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 4dd70a65..51977f08 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -27,7 +27,6 @@ void roots_keyboard_destroy(struct roots_keyboard *keyboard); void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event); -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event); +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard); #endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 5848416d..570f5721 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -14,6 +14,7 @@ void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, struct wlr_event_keyboard_key *event); void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event); + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group); #endif diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 4bd5b9b6..e2d50b03 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -66,23 +66,12 @@ enum wlr_key_state { }; struct wlr_event_keyboard_key { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; uint32_t time_msec; uint32_t keycode; bool update_state; enum wlr_key_state state; }; -struct wlr_event_keyboard_modifiers { - struct wlr_input_device *device; - struct wlr_keyboard *keyboard; - uint32_t mods_depressed; - uint32_t mods_latched; - uint32_t mods_locked; - uint32_t group; -}; - void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 9692ea7d..da75b44f 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -204,8 +204,7 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, } } -void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard, - struct wlr_event_keyboard_modifiers *event) { +void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { struct wlr_seat *seat = r_keyboard->seat->seat; wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_keyboard_notify_modifiers(seat); diff --git a/rootston/seat.c b/rootston/seat.c index ce8ad10b..97d5c7e4 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -22,8 +22,7 @@ static void handle_keyboard_modifiers(struct wl_listener *listener, void *data) { struct roots_keyboard *keyboard = wl_container_of(listener, keyboard, keyboard_modifiers); - struct wlr_event_keyboard_modifiers *event = data; - roots_keyboard_handle_modifiers(keyboard, event); + roots_keyboard_handle_modifiers(keyboard); } static void handle_cursor_motion(struct wl_listener *listener, void *data) { diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index a301c6e0..98ebeed5 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -41,6 +41,8 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { keyboard->modifiers.latched = latched; keyboard->modifiers.locked = locked; keyboard->modifiers.group = group; + + wl_signal_emit(&keyboard->events.modifiers, keyboard); } static void keyboard_key_update(struct wlr_keyboard *keyboard, @@ -68,15 +70,14 @@ static void keyboard_key_update(struct wlr_keyboard *keyboard, } void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, - struct wlr_event_keyboard_modifiers *event) { + uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) { if (!keyboard->xkb_state) { return; } - xkb_state_update_mask(keyboard->xkb_state, event->mods_depressed, - event->mods_latched, event->mods_locked, 0, 0, event->group); + xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, + mods_locked, 0, 0, group); keyboard_modifier_update(keyboard); - - wl_signal_emit(&keyboard->events.modifiers, event); } void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, -- cgit v1.2.3 From d6513cef5dc3f2c20e1bf11ff6a468b60ce35aca Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 17:47:59 -0500 Subject: rootston: add missing properties to kb config merge --- rootston/keyboard.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index da75b44f..72567eef 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -230,6 +230,12 @@ static void keyboard_config_merge(struct keyboard_config *config, if (config->options == NULL) { config->options = fallback->options; } + if (config->meta_key == 0) { + config->meta_key = fallback->meta_key; + } + if (config->name == NULL) { + config->name = fallback->name; + } } struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, -- cgit v1.2.3 From 1472dbda74dea5387a4d0e531b641734131dc705 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 9 Nov 2017 18:32:54 -0500 Subject: rootston: roots_keyboard null check --- rootston/keyboard.c | 4 ++++ rootston/seat.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 72567eef..bb748550 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -249,6 +249,10 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->input = input; struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + if (config == NULL) { + free(keyboard); + return NULL; + } keyboard_config_merge(config, config_get_keyboard(input->config, device)); keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); diff --git a/rootston/seat.c b/rootston/seat.c index 97d5c7e4..72e94aec 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -306,6 +306,11 @@ void roots_seat_destroy(struct roots_seat *seat) { static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device *device) { assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); struct roots_keyboard *keyboard = roots_keyboard_create(device, seat->input); + if (keyboard == NULL) { + wlr_log(L_ERROR, "could not allocate keyboard for seat"); + return; + } + keyboard->seat = seat; wl_list_insert(&seat->keyboards, &keyboard->link); -- cgit v1.2.3 From 80bf3cfff05d3ddabf75b2e53ed040aff0bbae62 Mon Sep 17 00:00:00 2001 From: Timidger Date: Thu, 9 Nov 2017 18:38:13 -0800 Subject: Fixes #399 Adds wlr_data_device_manager destructor Fixed issues --- include/wlr/types/wlr_data_device.h | 5 +++++ types/wlr_data_device.c | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index 691e2df8..f45c15a2 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -74,6 +74,11 @@ struct wlr_drag { struct wlr_data_device_manager *wlr_data_device_manager_create( struct wl_display *display); +/** + * Destroys a wlr_data_device_manager and removes its wl_data_device_manager global. + */ +void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager); + /** * Creates a new wl_data_offer if there is a wl_data_source currently set as * the seat selection and sends it to the seat client, followed by the diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index ea28ef50..df18317b 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -815,3 +815,11 @@ struct wlr_data_device_manager *wlr_data_device_manager_create( return manager; } + +void wlr_data_device_manager_destroy(struct wlr_data_device_manager *manager) { + if (!manager) { + return; + } + wl_global_destroy(manager->global); + free(manager); +} -- cgit v1.2.3 From aafb00a15fd84b6d40f2efa52333eea5633b14e5 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 10 Nov 2017 08:21:23 -0500 Subject: Fix centering views on scaled outputs --- rootston/desktop.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index 2448ffac..78bd271a 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -136,8 +136,6 @@ bool view_center(struct roots_view *view) { int width, height; wlr_output_effective_resolution(output, &width, &height); - width /= output->scale; - height /= output->scale; double view_x = (double)(width - box.width) / 2 + l_output->x; double view_y = (double)(height - box.height) / 2 + l_output->y; -- cgit v1.2.3 From 27a3a810ab372ca699bb9da1ce506816432b39f6 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Fri, 10 Nov 2017 08:27:45 -0500 Subject: rootston: fix multiseat focus --- include/rootston/input.h | 2 ++ rootston/input.c | 14 ++++++++++++++ rootston/seat.c | 35 ++++++++++------------------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/include/rootston/input.h b/include/rootston/input.h index ea0bbeb6..0af48577 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -26,4 +26,6 @@ void input_destroy(struct roots_input *input); struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, struct wlr_seat *seat); +bool input_view_has_focus(struct roots_input *input, struct roots_view *view); + #endif diff --git a/rootston/input.c b/rootston/input.c index 92148b65..e96565e0 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -108,3 +108,17 @@ struct roots_seat *input_seat_from_wlr_seat(struct roots_input *input, } return seat; } + +bool input_view_has_focus(struct roots_input *input, struct roots_view *view) { + if (!view) { + return false; + } + struct roots_seat *seat; + wl_list_for_each(seat, &input->seats, link) { + if (seat->focus == view) { + return true; + } + } + + return false; +} diff --git a/rootston/seat.c b/rootston/seat.c index 72e94aec..3dcd7f2f 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -503,36 +503,21 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { return; } - // unfocus the old view if it is not focused by some other seat - // TODO probably should be an input function - if (seat->focus) { - bool has_other_focus = false; - struct roots_seat *iter_seat; - wl_list_for_each(iter_seat, &seat->input->seats, link) { - if (iter_seat == seat) { - continue; - } - if (iter_seat->focus == seat->focus) { - has_other_focus = true; - break; - } - } - - if (!has_other_focus) { - view_activate(seat->focus, false); - } - } - - if (!view) { - seat->focus = NULL; - seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + if (view && view->type == ROOTS_XWAYLAND_VIEW && + view->xwayland_surface->override_redirect) { return; } + struct roots_view *prev_focus = seat->focus; seat->focus = view; - if (view->type == ROOTS_XWAYLAND_VIEW && - view->xwayland_surface->override_redirect) { + // unfocus the old view if it is not focused by some other seat + if (prev_focus && !input_view_has_focus(seat->input, prev_focus)) { + view_activate(prev_focus, false); + } + + if (!seat->focus) { + seat->cursor->mode = ROOTS_CURSOR_PASSTHROUGH; return; } -- cgit v1.2.3 From 5be11a5c95457c6d4f6cd9720162f962286c2258 Mon Sep 17 00:00:00 2001 From: Eric Molitor Date: Fri, 10 Nov 2017 15:12:00 +0000 Subject: Remove VLA from session.h VLAs are optional C11 features and not supported by C++. --- backend/session/session.c | 2 +- include/wlr/backend/session.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/session/session.c b/backend/session/session.c index b14ca4d0..760830c3 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -257,7 +257,7 @@ static size_t explicit_find_gpus(struct wlr_session *session, * If it's not found, it returns the first valid GPU it finds. */ size_t wlr_session_find_gpus(struct wlr_session *session, - size_t ret_len, int ret[static ret_len]) { + size_t ret_len, int *ret) { const char *explicit = getenv("WLR_DRM_DEVICES"); if (explicit) { return explicit_find_gpus(session, ret_len, ret, explicit); diff --git a/include/wlr/backend/session.h b/include/wlr/backend/session.h index 94002bc5..5c822ea9 100644 --- a/include/wlr/backend/session.h +++ b/include/wlr/backend/session.h @@ -79,6 +79,6 @@ void wlr_session_signal_add(struct wlr_session *session, int fd, bool wlr_session_change_vt(struct wlr_session *session, unsigned vt); size_t wlr_session_find_gpus(struct wlr_session *session, - size_t ret_len, int ret[static ret_len]); + size_t ret_len, int *ret); #endif -- cgit v1.2.3 From f092a379556ed3bbca2043445305eee28ab8c850 Mon Sep 17 00:00:00 2001 From: Stefano Ragni Date: Sat, 11 Nov 2017 00:45:52 +0100 Subject: Fix typos --- backend/session/logind.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/session/logind.c b/backend/session/logind.c index 42b48e94..daff75b6 100644 --- a/backend/session/logind.c +++ b/backend/session/logind.c @@ -123,7 +123,7 @@ static bool logind_change_vt(struct wlr_session *base, unsigned vt) { return ret >= 0; } -static bool find_sesion_path(struct logind_session *session) { +static bool find_session_path(struct logind_session *session) { int ret; sd_bus_message *msg = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; @@ -303,7 +303,7 @@ static bool add_signal_matches(struct logind_session *session) { "member='%s'," "path='%s'"; - snprintf(str, sizeof(str), fmt, "Manager", "SesssionRemoved", "/org/freedesktop/login1"); + snprintf(str, sizeof(str), fmt, "Manager", "SessionRemoved", "/org/freedesktop/login1"); ret = sd_bus_add_match(session->bus, NULL, str, session_removed, session); if (ret < 0) { wlr_log(L_ERROR, "Failed to add D-Bus match: %s", strerror(-ret)); @@ -368,7 +368,7 @@ static struct wlr_session *logind_session_create(struct wl_display *disp) { goto error; } - if (!find_sesion_path(session)) { + if (!find_session_path(session)) { sd_bus_unref(session->bus); goto error; } -- cgit v1.2.3 From eb89f1dcd2dd820bc86ae0350774aff4d81408e8 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 15:39:15 +0100 Subject: Fix resize issues with some xdg-shell apps. Also renames view_get_size to view_get_box to be more consistent with wlroots API and make it more obvious that x,y are set (while in roots_view.get_size this isn't the case). Fixes #407 --- include/rootston/view.h | 2 +- rootston/cursor.c | 8 ++++---- rootston/desktop.c | 18 +++++++++--------- rootston/xdg_shell_v6.c | 10 ++++++++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/include/rootston/view.h b/include/rootston/view.h index f0d102cd..99b4ed78 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -94,7 +94,7 @@ struct roots_view { void (*close)(struct roots_view *view); }; -void view_get_size(const struct roots_view *view, struct wlr_box *box); +void view_get_box(const struct roots_view *view, struct wlr_box *box); void view_activate(struct roots_view *view, bool active); void view_move(struct roots_view *view, double x, double y); void view_resize(struct roots_view *view, uint32_t width, uint32_t height); diff --git a/rootston/cursor.c b/rootston/cursor.c index cbd03af1..81841b6c 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -72,10 +72,10 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, } else { input->view_x = view->x; input->view_y = view->y; - struct wlr_box size; - view_get_size(view, &size); - input->view_width = size.width; - input->view_height = size.height; + struct wlr_box box; + view_get_box(view, &box); + input->view_width = box.width; + input->view_height = box.height; } input->resize_edges = edges; diff --git a/rootston/desktop.c b/rootston/desktop.c index 469a503b..0f5f5fdd 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -35,15 +35,15 @@ void view_destroy(struct roots_view *view) { free(view); } -void view_get_size(const struct roots_view *view, struct wlr_box *box) { +void view_get_box(const struct roots_view *view, struct wlr_box *box) { + box->x = view->x; + box->y = view->y; if (view->get_size) { view->get_size(view, box); } else { box->width = view->wlr_surface->current->width; box->height = view->wlr_surface->current->height; } - box->x = view->x; - box->y = view->y; } static void view_update_output(const struct roots_view *view, @@ -51,7 +51,7 @@ static void view_update_output(const struct roots_view *view, struct roots_desktop *desktop = view->desktop; struct roots_output *output; struct wlr_box box; - view_get_size(view, &box); + view_get_box(view, &box); wl_list_for_each(output, &desktop->outputs, link) { bool intersected = before->x != -1 && wlr_output_layout_intersects( desktop->layout, output->wlr_output, @@ -71,7 +71,7 @@ static void view_update_output(const struct roots_view *view, void view_move(struct roots_view *view, double x, double y) { struct wlr_box before; - view_get_size(view, &before); + view_get_box(view, &before); if (view->move) { view->move(view, x, y); } else { @@ -88,7 +88,7 @@ void view_activate(struct roots_view *view, bool activate) { void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { struct wlr_box before; - view_get_size(view, &before); + view_get_box(view, &before); if (view->resize) { view->resize(view, width, height); } @@ -117,7 +117,7 @@ void view_maximize(struct roots_view *view, bool maximized) { if (!view->maximized && maximized) { struct wlr_box view_box; - view_get_size(view, &view_box); + view_get_box(view, &view_box); view->maximized = true; view->saved.x = view->x; @@ -158,7 +158,7 @@ void view_close(struct roots_view *view) { bool view_center(struct roots_view *view) { struct wlr_box box; - view_get_size(view, &box); + view_get_box(view, &box); struct roots_desktop *desktop = view->desktop; struct wlr_cursor *cursor = desktop->server->input->cursor; @@ -193,7 +193,7 @@ void view_setup(struct roots_view *view) { view_center(view); set_view_focus(input, view->desktop, view); struct wlr_box before; - view_get_size(view, &before); + view_get_box(view, &before); view_update_output(view, &before); } diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 2a0660a6..5e76e5d4 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -13,8 +13,14 @@ static void get_size(const struct roots_view *view, struct wlr_box *box) { assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; - // TODO: surf->geometry can be NULL - memcpy(box, surf->geometry, sizeof(struct wlr_box)); + + if (surf->geometry->width > 0 && surf->geometry->height > 0) { + box->width = surf->geometry->width; + box->height = surf->geometry->height; + } else { + box->width = view->wlr_surface->current->width; + box->height = view->wlr_surface->current->height; + } } static void activate(struct roots_view *view, bool active) { -- cgit v1.2.3 From 4ccadf713b68a01540ec192981e167821d75294e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:40:56 -0500 Subject: rootston: fix formatting for xwayland config --- rootston/config.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rootston/config.c b/rootston/config.c index 54f10fcd..73bb6eb0 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -194,17 +194,17 @@ static int config_ini_handler(void *user, const char *section, const char *name, const char *value) { struct roots_config *config = user; if (strcmp(section, "core") == 0) { - if (strcmp(name, "xwayland") == 0) { - if (strcasecmp(value, "true") == 0) { - config->xwayland = true; - } else if (strcasecmp(value, "false") == 0) { - config->xwayland = false; - } else { - wlr_log(L_ERROR, "got unknown xwayland value: %s", value); - } - } else { - wlr_log(L_ERROR, "got unknown core config: %s", name); - } + if (strcmp(name, "xwayland") == 0) { + if (strcasecmp(value, "true") == 0) { + config->xwayland = true; + } else if (strcasecmp(value, "false") == 0) { + config->xwayland = false; + } else { + wlr_log(L_ERROR, "got unknown xwayland value: %s", value); + } + } else { + wlr_log(L_ERROR, "got unknown core config: %s", name); + } } else if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) { const char *output_name = section + strlen(output_prefix); struct output_config *oc; -- cgit v1.2.3 From 6e00140e8a0326ce1d78c1c3efd8b0a373298af0 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:41:18 -0500 Subject: rootston: remove unused import and old todo from config header --- include/rootston/config.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/rootston/config.h b/include/rootston/config.h index 872dc7b6..8ef58100 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -2,7 +2,6 @@ #define _ROOTSTON_CONFIG_H #include #include -#include struct output_config { char *name; @@ -45,7 +44,7 @@ struct keyboard_config { struct roots_config { bool xwayland; - // TODO: Multiple cursors, multiseat + struct { char *mapped_output; struct wlr_box *mapped_box; -- cgit v1.2.3 From 18079e234a9fb8ee3ee8686cf3e28d5920326a4a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:44:29 -0500 Subject: rootston: documentation for config.h functions --- include/rootston/config.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/rootston/config.h b/include/rootston/config.h index 8ef58100..d2a25b5b 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -58,8 +58,16 @@ struct roots_config { char *startup_cmd; }; +/** + * Create a roots config from the given command line arguments. Command line + * arguments can specify the location of the config file. If it is not + * specified, the default location will be used. + */ struct roots_config *parse_args(int argc, char *argv[]); +/** + * Destroy the config and free its resources. + */ void roots_config_destroy(struct roots_config *config); /** -- cgit v1.2.3 From 029f2c05bbe701d27dae7402902256955ca6eb8d Mon Sep 17 00:00:00 2001 From: Tancredi Orlando Date: Sat, 11 Nov 2017 16:47:54 +0100 Subject: Fix unused-result error --- examples/screenshot.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/screenshot.c b/examples/screenshot.c index 2a3b74aa..fc7f3cb3 100644 --- a/examples/screenshot.c +++ b/examples/screenshot.c @@ -187,7 +187,10 @@ static void write_image(const char *filename, int width, int height) { sprintf(size, "%dx%d+0", width, height); int fd[2]; - pipe(fd); + if (pipe(fd) != 0) { + fprintf(stderr, "cannot create pipe: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } pid_t child = fork(); if (child < 0) { @@ -195,7 +198,10 @@ static void write_image(const char *filename, int width, int height) { exit(EXIT_FAILURE); } else if (child != 0) { close(fd[0]); - write(fd[1], data, buffer_stride * height); + if (write(fd[1], data, buffer_stride * height) < 0) { + fprintf(stderr, "write() failed: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } close(fd[1]); free(data); waitpid(child, NULL, 0); -- cgit v1.2.3 From 1db3b5512821b1d6f936897f598e0f4d12233e8e Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:59:04 -0500 Subject: rootston: prefix config structs and functions --- include/rootston/config.h | 18 +++++++++--------- include/rootston/keyboard.h | 2 +- rootston/config.c | 42 ++++++++++++++++++++++-------------------- rootston/input.c | 3 ++- rootston/keyboard.c | 15 ++++++++------- rootston/main.c | 2 +- rootston/output.c | 6 ++++-- rootston/seat.c | 8 ++++---- 8 files changed, 51 insertions(+), 45 deletions(-) diff --git a/include/rootston/config.h b/include/rootston/config.h index d2a25b5b..71ee61c7 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -3,7 +3,7 @@ #include #include -struct output_config { +struct roots_output_config { char *name; enum wl_output_transform transform; int x, y; @@ -15,7 +15,7 @@ struct output_config { } mode; }; -struct device_config { +struct roots_device_config { char *name; char *mapped_output; struct wlr_box *mapped_box; @@ -23,7 +23,7 @@ struct device_config { struct wl_list link; }; -struct binding_config { +struct roots_binding_config { uint32_t modifiers; xkb_keysym_t *keysyms; size_t keysyms_len; @@ -31,7 +31,7 @@ struct binding_config { struct wl_list link; }; -struct keyboard_config { +struct roots_keyboard_config { char *name; uint32_t meta_key; char *rules; @@ -63,7 +63,7 @@ struct roots_config { * arguments can specify the location of the config file. If it is not * specified, the default location will be used. */ -struct roots_config *parse_args(int argc, char *argv[]); +struct roots_config *roots_config_create_from_args(int argc, char *argv[]); /** * Destroy the config and free its resources. @@ -74,21 +74,21 @@ void roots_config_destroy(struct roots_config *config); * Get configuration for the output. If the output is not configured, returns * NULL. */ -struct output_config *config_get_output(struct roots_config *config, +struct roots_output_config *roots_config_get_output(struct roots_config *config, struct wlr_output *output); /** * Get configuration for the device. If the device is not configured, returns * NULL. */ -struct device_config *config_get_device(struct roots_config *config, +struct roots_device_config *roots_config_get_device(struct roots_config *config, struct wlr_input_device *device); /** * Get configuration for the keyboard. If the keyboard is not configured, * returns NULL. A NULL device returns the default config for keyboards. */ -struct keyboard_config *config_get_keyboard(struct roots_config *config, - struct wlr_input_device *device); +struct roots_keyboard_config *roots_config_get_keyboard( + struct roots_config *config, struct wlr_input_device *device); #endif diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 51977f08..15e7c9c4 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -10,7 +10,7 @@ struct roots_keyboard { struct roots_input *input; struct roots_seat *seat; struct wlr_input_device *device; - struct keyboard_config *config; + struct roots_keyboard_config *config; struct wl_list link; struct wl_listener keyboard_key; diff --git a/rootston/config.c b/rootston/config.c index 73bb6eb0..9530ba37 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -115,7 +115,8 @@ static uint32_t parse_modifier(const char *symname) { void add_binding_config(struct wl_list *bindings, const char* combination, const char* command) { - struct binding_config *bc = calloc(1, sizeof(struct binding_config)); + struct roots_binding_config *bc = + calloc(1, sizeof(struct roots_binding_config)); xkb_keysym_t keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; char *symnames = strdup(combination); @@ -151,7 +152,7 @@ void add_binding_config(struct wl_list *bindings, const char* combination, static void config_handle_keyboard(struct roots_config *config, const char *device_name, const char *name, const char *value) { - struct keyboard_config *kc; + struct roots_keyboard_config *kc; bool found = false; wl_list_for_each(kc, &config->keyboards, link) { if (strcmp(kc->name, device_name) == 0) { @@ -161,7 +162,7 @@ static void config_handle_keyboard(struct roots_config *config, } if (!found) { - kc = calloc(1, sizeof(struct keyboard_config)); + kc = calloc(1, sizeof(struct roots_keyboard_config)); kc->name = strdup(device_name); wl_list_insert(&config->keyboards, &kc->link); } @@ -207,7 +208,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } } else if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) { const char *output_name = section + strlen(output_prefix); - struct output_config *oc; + struct roots_output_config *oc; bool found = false; wl_list_for_each(oc, &config->outputs, link) { @@ -218,7 +219,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } if (!found) { - oc = calloc(1, sizeof(struct output_config)); + oc = calloc(1, sizeof(struct roots_output_config)); oc->name = strdup(output_name); oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; oc->scale = 1; @@ -281,7 +282,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else if (strncmp(device_prefix, section, strlen(device_prefix)) == 0) { const char *device_name = section + strlen(device_prefix); - struct device_config *dc; + struct roots_device_config *dc; bool found = false; wl_list_for_each(dc, &config->devices, link) { if (strcmp(dc->name, device_name) == 0) { @@ -291,7 +292,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, } if (!found) { - dc = calloc(1, sizeof(struct device_config)); + dc = calloc(1, sizeof(struct roots_device_config)); dc->name = strdup(device_name); dc->seat = strdup("seat0"); wl_list_insert(&config->devices, &dc->link); @@ -323,7 +324,7 @@ static int config_ini_handler(void *user, const char *section, const char *name, return 1; } -struct roots_config *parse_args(int argc, char *argv[]) { +struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { struct roots_config *config = calloc(1, sizeof(struct roots_config)); if (config == NULL) { return NULL; @@ -370,7 +371,8 @@ struct roots_config *parse_args(int argc, char *argv[]) { add_binding_config(&config->bindings, "Logo+Shift+E", "exit"); add_binding_config(&config->bindings, "Ctrl+q", "close"); add_binding_config(&config->bindings, "Alt+Tab", "next_window"); - struct keyboard_config *kc = calloc(1, sizeof(struct keyboard_config)); + struct roots_keyboard_config *kc = + calloc(1, sizeof(struct roots_keyboard_config)); kc->meta_key = WLR_MODIFIER_LOGO; kc->name = strdup(""); wl_list_insert(&config->keyboards, &kc->link); @@ -386,13 +388,13 @@ struct roots_config *parse_args(int argc, char *argv[]) { } void roots_config_destroy(struct roots_config *config) { - struct output_config *oc, *otmp = NULL; + struct roots_output_config *oc, *otmp = NULL; wl_list_for_each_safe(oc, otmp, &config->outputs, link) { free(oc->name); free(oc); } - struct device_config *dc, *dtmp = NULL; + struct roots_device_config *dc, *dtmp = NULL; wl_list_for_each_safe(dc, dtmp, &config->devices, link) { free(dc->name); free(dc->seat); @@ -401,7 +403,7 @@ void roots_config_destroy(struct roots_config *config) { free(dc); } - struct keyboard_config *kc, *ktmp = NULL; + struct roots_keyboard_config *kc, *ktmp = NULL; wl_list_for_each_safe(kc, ktmp, &config->bindings, link) { free(kc->name); free(kc->rules); @@ -412,7 +414,7 @@ void roots_config_destroy(struct roots_config *config) { free(kc); } - struct binding_config *bc, *btmp = NULL; + struct roots_binding_config *bc, *btmp = NULL; wl_list_for_each_safe(bc, btmp, &config->bindings, link) { free(bc->keysyms); free(bc->command); @@ -425,9 +427,9 @@ void roots_config_destroy(struct roots_config *config) { free(config); } -struct output_config *config_get_output(struct roots_config *config, +struct roots_output_config *roots_config_get_output(struct roots_config *config, struct wlr_output *output) { - struct output_config *o_config; + struct roots_output_config *o_config; wl_list_for_each(o_config, &config->outputs, link) { if (strcmp(o_config->name, output->name) == 0) { return o_config; @@ -437,9 +439,9 @@ struct output_config *config_get_output(struct roots_config *config, return NULL; } -struct device_config *config_get_device(struct roots_config *config, +struct roots_device_config *roots_config_get_device(struct roots_config *config, struct wlr_input_device *device) { - struct device_config *d_config; + struct roots_device_config *d_config; wl_list_for_each(d_config, &config->devices, link) { if (strcmp(d_config->name, device->name) == 0) { return d_config; @@ -449,9 +451,9 @@ struct device_config *config_get_device(struct roots_config *config, return NULL; } -struct keyboard_config *config_get_keyboard(struct roots_config *config, - struct wlr_input_device *device) { - struct keyboard_config *kc; +struct roots_keyboard_config *roots_config_get_keyboard( + struct roots_config *config, struct wlr_input_device *device) { + struct roots_keyboard_config *kc; wl_list_for_each(kc, &config->keyboards, link) { if ((device != NULL && strcmp(kc->name, device->name) == 0) || (device == NULL && strcmp(kc->name, "") == 0)) { diff --git a/rootston/input.c b/rootston/input.c index e96565e0..35a5af97 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -44,7 +44,8 @@ static void input_add_notify(struct wl_listener *listener, void *data) { struct roots_input *input = wl_container_of(listener, input, input_add); char *seat_name = "seat0"; - struct device_config *dc = config_get_device(input->config, device); + struct roots_device_config *dc = + roots_config_get_device(input->config, device); if (dc) { seat_name = dc->seat; } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index bb748550..c118e55c 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -92,7 +92,7 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); struct wl_list *bindings = &keyboard->input->server->config->bindings; - struct binding_config *bc; + struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { if (modifiers ^ bc->modifiers) { continue; @@ -210,8 +210,8 @@ void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { wlr_seat_keyboard_notify_modifiers(seat); } -static void keyboard_config_merge(struct keyboard_config *config, - struct keyboard_config *fallback) { +static void keyboard_config_merge(struct roots_keyboard_config *config, + struct roots_keyboard_config *fallback) { if (fallback == NULL) { return; } @@ -248,15 +248,16 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard->device = device; keyboard->input = input; - struct keyboard_config *config = calloc(1, sizeof(struct keyboard_config)); + struct roots_keyboard_config *config = + calloc(1, sizeof(struct roots_keyboard_config)); if (config == NULL) { free(keyboard); return NULL; } - keyboard_config_merge(config, config_get_keyboard(input->config, device)); - keyboard_config_merge(config, config_get_keyboard(input->config, NULL)); + keyboard_config_merge(config, roots_config_get_keyboard(input->config, device)); + keyboard_config_merge(config, roots_config_get_keyboard(input->config, NULL)); - struct keyboard_config env_config = { + struct roots_keyboard_config env_config = { .rules = getenv("XKB_DEFAULT_RULES"), .model = getenv("XKB_DEFAULT_MODEL"), .layout = getenv("XKB_DEFAULT_LAYOUT"), diff --git a/rootston/main.c b/rootston/main.c index 2a054e6c..d55bc682 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -13,7 +13,7 @@ struct roots_server server = { 0 }; int main(int argc, char **argv) { - assert(server.config = parse_args(argc, argv)); + assert(server.config = roots_config_create_from_args(argc, argv)); assert(server.wl_display = wl_display_create()); assert(server.wl_event_loop = wl_display_get_event_loop(server.wl_display)); diff --git a/rootston/output.c b/rootston/output.c index f192cb48..d853c45f 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -181,7 +181,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { output->last_frame = desktop->last_frame = now; } -static void set_mode(struct wlr_output *output, struct output_config *oc) { +static void set_mode(struct wlr_output *output, + struct roots_output_config *oc) { struct wlr_output_mode *mode, *best = NULL; int mhz = (int)(oc->mode.refresh_rate * 1000); wl_list_for_each(mode, &output->modes, link) { @@ -225,7 +226,8 @@ void output_add_notify(struct wl_listener *listener, void *data) { wl_signal_add(&wlr_output->events.frame, &output->frame); wl_list_insert(&desktop->outputs, &output->link); - struct output_config *output_config = config_get_output(config, wlr_output); + struct roots_output_config *output_config = + roots_config_get_output(config, wlr_output); if (output_config) { if (output_config->mode.width) { set_mode(wlr_output, output_config); diff --git a/rootston/seat.c b/rootston/seat.c index 3530fb75..4602aad5 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -117,8 +117,8 @@ static void seat_reset_device_mappings(struct roots_seat *seat, struct wlr_input struct roots_config *config = seat->input->config; wlr_cursor_map_input_to_output(cursor, device, NULL); - struct device_config *dconfig; - if ((dconfig = config_get_device(config, device))) { + struct roots_device_config *dconfig; + if ((dconfig = roots_config_get_device(config, device))) { wlr_cursor_map_input_to_region(cursor, device, dconfig->mapped_box); } } @@ -127,8 +127,8 @@ static void seat_set_device_output_mappings(struct roots_seat *seat, struct wlr_input_device *device, struct wlr_output *output) { struct wlr_cursor *cursor = seat->cursor->cursor; struct roots_config *config = seat->input->config; - struct device_config *dconfig; - dconfig = config_get_device(config, device); + struct roots_device_config *dconfig; + dconfig = roots_config_get_device(config, device); if (dconfig && dconfig->mapped_output && strcmp(dconfig->mapped_output, output->name) == 0) { wlr_cursor_map_input_to_output(cursor, device, output); -- cgit v1.2.3 From 7072ac87fd1f92cfe6e88a075ff0e8ac2901e870 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sat, 11 Nov 2017 10:59:50 -0500 Subject: rootston: config.c 80 col --- rootston/config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rootston/config.c b/rootston/config.c index 9530ba37..7ffbb786 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -312,7 +312,8 @@ static int config_ini_handler(void *user, const char *section, const char *name, } } else if (strcmp(section, "keyboard") == 0) { config_handle_keyboard(config, "", name, value); - } else if (strncmp(keyboard_prefix, section, strlen(keyboard_prefix)) == 0) { + } else if (strncmp(keyboard_prefix, + section, strlen(keyboard_prefix)) == 0) { const char *device_name = section + strlen(keyboard_prefix); config_handle_keyboard(config, device_name, name, value); } else if (strcmp(section, "bindings") == 0) { -- cgit v1.2.3 From ac1573b0e7b0b08413e115bb88682ebedbfbf39a Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 17:27:44 +0100 Subject: Add scale parameter to wlr_cursor_set_image --- examples/multi-pointer.c | 4 ++-- examples/pointer.c | 4 ++-- include/wlr/types/wlr_cursor.h | 15 ++++++++++++++- rootston/cursor.c | 2 +- rootston/seat.c | 21 ++++++++++----------- types/wlr_cursor.c | 7 ++++++- 6 files changed, 35 insertions(+), 18 deletions(-) diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index e29a69db..f1bcebc7 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -86,7 +86,7 @@ static void handle_output_add(struct output_state *ostate) { struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wlr_cursor_warp(cursor->cursor, NULL, cursor->cursor->x, cursor->cursor->y); @@ -150,7 +150,7 @@ static void handle_input_add(struct compositor_state *state, struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wl_list_insert(&sample->cursors, &cursor->link); } diff --git a/examples/pointer.c b/examples/pointer.c index 1bcd7349..476cc617 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -110,7 +110,7 @@ static void handle_output_add(struct output_state *ostate) { struct wlr_xcursor_image *image = sample->xcursor->images[0]; wlr_cursor_set_image(sample->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); wlr_cursor_warp(sample->cursor, NULL, sample->cursor->x, sample->cursor->y); } @@ -321,7 +321,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, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); compositor_init(&compositor); if (!wlr_backend_start(compositor.backend)) { diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 1aac2b94..3df74d28 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -60,9 +60,22 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur, void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, double delta_x, double delta_y); +/** + * Set the cursor image. stride is given in bytes. If pixels is NULL, hides the + * cursor. + * + * If scale isn't zero, the image is only set on outputs having the provided + * scale. + */ void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, - int32_t hotspot_y); + int32_t hotspot_y, uint32_t scale); + +/** + * Set the cursor surface. The surface can be committed to update the cursor + * image. The surface position is substracted from the hotspot. A NULL surface + * commit hides the cursor. + */ void wlr_cursor_set_surface(struct wlr_cursor *cur, struct wlr_surface *surface, int32_t hotspot_x, int32_t hotspot_y); diff --git a/rootston/cursor.c b/rootston/cursor.c index cba9e782..c3982e0e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -30,7 +30,7 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { static void cursor_set_xcursor_image(struct roots_cursor *cursor, struct wlr_xcursor_image *image) { wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); } static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { diff --git a/rootston/seat.c b/rootston/seat.c index 4602aad5..280443ac 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -176,6 +176,12 @@ void roots_seat_configure_cursor(struct roots_seat *seat) { } } +static void seat_set_xcursor_image(struct roots_seat *seat, struct + wlr_xcursor_image *image) { + wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y, 0); +} + static void roots_seat_init_cursor(struct roots_seat *seat) { seat->cursor = roots_cursor_create(seat); if (!seat->cursor) { @@ -204,8 +210,7 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { } struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + seat_set_xcursor_image(seat, image); // XXX: xwayland will always have the theme of the last created seat if (seat->input->server->desktop->xwayland != NULL) { @@ -471,10 +476,10 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); + struct wlr_xcursor *xcursor = + get_default_xcursor(seat->cursor->xcursor_theme); struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); + seat_set_xcursor_image(seat, image); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); @@ -537,12 +542,6 @@ void roots_seat_focus_view(struct roots_seat *seat, struct roots_view *view) { wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface); } -static void seat_set_xcursor_image(struct roots_seat *seat, struct - wlr_xcursor_image *image) { - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y); -} - void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { struct roots_cursor *cursor = seat->cursor; cursor->mode = ROOTS_CURSOR_MOVE; diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index dfaccb53..e8965b68 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -299,9 +299,14 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev, void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels, int32_t stride, uint32_t width, uint32_t height, int32_t hotspot_x, - int32_t hotspot_y) { + int32_t hotspot_y, uint32_t scale) { struct wlr_cursor_output_cursor *output_cursor; wl_list_for_each(output_cursor, &cur->state->output_cursors, link) { + if (scale != 0 && + output_cursor->output_cursor->output->scale != scale) { + continue; + } + wlr_output_cursor_set_image(output_cursor->output_cursor, pixels, stride, width, height, hotspot_x, hotspot_y); } -- cgit v1.2.3 From aaf069188319f42bc214f4317c37d533aea64518 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 18:42:14 +0100 Subject: rootston: add roots_xcursor_theme roots_xcursor_theme loads multiple wlr_xcursor_theme at different scales. --- include/rootston/cursor.h | 1 - include/rootston/desktop.h | 2 + include/rootston/xcursor.h | 39 ++++++++++++++-- rootston/cursor.c | 10 +--- rootston/desktop.c | 14 ++++++ rootston/output.c | 6 +++ rootston/seat.c | 61 ++++-------------------- rootston/xcursor.c | 114 ++++++++++++++++++++++++++++++++++++++++----- 8 files changed, 170 insertions(+), 77 deletions(-) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index c0dbc010..fc71e31d 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -30,7 +30,6 @@ struct roots_cursor { enum roots_cursor_mode mode; // state from input (review if this is necessary) - struct wlr_xcursor_theme *xcursor_theme; struct wlr_seat *wl_seat; struct wl_client *cursor_client; int offs_x, offs_y; diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 376412fb..b12fff70 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -12,6 +12,7 @@ #include #include "rootston/view.h" #include "rootston/config.h" +#include "rootston/xcursor.h" struct roots_output { struct roots_desktop *desktop; @@ -29,6 +30,7 @@ struct roots_desktop { struct roots_server *server; struct roots_config *config; + struct roots_xcursor_theme *xcursor_theme; struct wlr_output_layout *layout; diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h index c96e50ef..45fac481 100644 --- a/include/rootston/xcursor.h +++ b/include/rootston/xcursor.h @@ -1,15 +1,44 @@ #ifndef _ROOTSTON_XCURSOR_H #define _ROOTSTON_XCURSOR_H +#include #include +#include +#include -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme); +#define ROOTS_XCURSOR_SIZE 16 -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme); +struct roots_xcursor_scaled_theme { + uint32_t scale; + struct wlr_xcursor_theme *theme; + struct wl_list link; +}; -struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, - uint32_t edges); +struct roots_xcursor_theme { + char *name; + struct wl_list scaled_themes; // roots_xcursor_scaled_theme::link +}; -struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme); +struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name); + +void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme); + +int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, + uint32_t scale); + +void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor); + +void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor); + +void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor, uint32_t edges); + +void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor); + +void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, + struct wlr_xwayland *xwayland); #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index c3982e0e..46f4caea 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -27,12 +27,6 @@ void roots_cursor_destroy(struct roots_cursor *cursor) { // TODO } -static void cursor_set_xcursor_image(struct roots_cursor *cursor, - struct wlr_xcursor_image *image) { - wlr_cursor_set_image(cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y, 0); -} - static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { struct roots_desktop *desktop = cursor->seat->input->server->desktop; struct roots_seat *seat = cursor->seat; @@ -50,8 +44,8 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - struct wlr_xcursor *xcursor = get_default_xcursor(cursor->xcursor_theme); - cursor_set_xcursor_image(cursor, xcursor->images[0]); + roots_xcursor_theme_set_default(desktop->xcursor_theme, + cursor->cursor); cursor->cursor_client = NULL; } if (view) { diff --git a/rootston/desktop.c b/rootston/desktop.c index 448171ec..e20fceab 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -323,6 +323,14 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->server = server; desktop->config = config; + + desktop->xcursor_theme = roots_xcursor_theme_create("default"); + if (desktop->xcursor_theme == NULL) { + wlr_list_free(desktop->views); + free(desktop); + return NULL; + } + desktop->layout = wlr_output_layout_create(); desktop->compositor = wlr_compositor_create(server->wl_display, server->renderer); @@ -344,6 +352,12 @@ struct roots_desktop *desktop_create(struct roots_server *server, wl_signal_add(&desktop->xwayland->events.new_surface, &desktop->xwayland_surface); desktop->xwayland_surface.notify = handle_xwayland_surface; + + if (roots_xcursor_theme_load(desktop->xcursor_theme, 1)) { + wlr_log(L_ERROR, "Cannot load xwayland xcursor theme"); + } + roots_xcursor_theme_xwayland_set_default(desktop->xcursor_theme, + desktop->xwayland); } #endif diff --git a/rootston/output.c b/rootston/output.c index d853c45f..943e14c0 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -11,6 +11,7 @@ #include "rootston/server.h" #include "rootston/desktop.h" #include "rootston/config.h" +#include "rootston/xcursor.h" static inline int64_t timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; @@ -240,6 +241,11 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } + if (roots_xcursor_theme_load(desktop->xcursor_theme, wlr_output->scale)) { + wlr_log(L_ERROR, "Cannot load xcursor theme with scale %d", + wlr_output->scale); + } + struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { roots_seat_configure_cursor(seat); diff --git a/rootston/seat.c b/rootston/seat.c index 280443ac..376da67f 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -176,12 +176,6 @@ void roots_seat_configure_cursor(struct roots_seat *seat) { } } -static void seat_set_xcursor_image(struct roots_seat *seat, struct - wlr_xcursor_image *image) { - wlr_cursor_set_image(seat->cursor->cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y, 0); -} - static void roots_seat_init_cursor(struct roots_seat *seat) { seat->cursor = roots_cursor_create(seat); if (!seat->cursor) { @@ -192,33 +186,7 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); - seat->cursor->xcursor_theme = wlr_xcursor_theme_load("default", 16); - if (seat->cursor->xcursor_theme == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor theme"); - roots_cursor_destroy(seat->cursor); - seat->cursor = NULL; - return; - } - - struct wlr_xcursor *xcursor = get_default_xcursor(seat->cursor->xcursor_theme); - if (xcursor == NULL) { - wlr_log(L_ERROR, "Cannot load xcursor from theme"); - wlr_xcursor_theme_destroy(seat->cursor->xcursor_theme); - roots_cursor_destroy(seat->cursor); - seat->cursor = NULL; - return; - } - - struct wlr_xcursor_image *image = xcursor->images[0]; - seat_set_xcursor_image(seat, image); - - // XXX: xwayland will always have the theme of the last created seat - if (seat->input->server->desktop->xwayland != NULL) { - wlr_xwayland_set_cursor(seat->input->server->desktop->xwayland, - image->buffer, image->width, image->width, - image->height, image->hotspot_x, - image->hotspot_y); - } + roots_xcursor_theme_set_default(desktop->xcursor_theme, wlr_cursor); wl_list_init(&seat->cursor->touch_points); @@ -476,11 +444,8 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - struct wlr_xcursor *xcursor = - get_default_xcursor(seat->cursor->xcursor_theme); - struct wlr_xcursor_image *image = xcursor->images[0]; - seat_set_xcursor_image(seat, image); - + roots_xcursor_theme_set_default(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); } @@ -557,11 +522,8 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - struct wlr_xcursor *xcursor = get_move_xcursor(seat->cursor->xcursor_theme); - if (xcursor != NULL) { - struct wlr_xcursor_image *image = xcursor->images[0]; - seat_set_xcursor_image(seat, image); - } + roots_xcursor_theme_set_move(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor); } void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, @@ -587,11 +549,8 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - struct wlr_xcursor *xcursor = get_resize_xcursor(cursor->xcursor_theme, edges); - if (xcursor != NULL) { - seat_set_xcursor_image(seat, xcursor->images[0]); - } - + roots_xcursor_theme_set_resize(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor, edges); } void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { @@ -603,8 +562,6 @@ void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - struct wlr_xcursor *xcursor = get_rotate_xcursor(cursor->xcursor_theme); - if (xcursor != NULL) { - seat_set_xcursor_image(seat, xcursor->images[0]); - } + roots_xcursor_theme_set_rotate(seat->input->server->desktop->xcursor_theme, + seat->cursor->cursor); } diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 8697cdc3..6aa74bc4 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -1,6 +1,85 @@ -#include +#define _POSIX_C_SOURCE 200809L +#include +#include +#include "rootston/xcursor.h" #include "rootston/input.h" +struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name) { + struct roots_xcursor_theme *theme = + calloc(1, sizeof(struct roots_xcursor_theme)); + if (theme == NULL) { + return NULL; + } + theme->name = strdup(name); + wl_list_init(&theme->scaled_themes); + return theme; +} + +void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme) { + if (theme == NULL) { + return; + } + struct roots_xcursor_scaled_theme *scaled_theme, *tmp; + wl_list_for_each_safe(scaled_theme, tmp, &theme->scaled_themes, link) { + wl_list_remove(&scaled_theme->link); + wlr_xcursor_theme_destroy(scaled_theme->theme); + free(scaled_theme); + } + free(theme->name); + free(theme); +} + +int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, + uint32_t scale) { + struct roots_xcursor_scaled_theme *scaled_theme; + wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { + if (scaled_theme->scale == scale) { + return 0; + } + } + + scaled_theme = calloc(1, sizeof(struct roots_xcursor_scaled_theme)); + if (scaled_theme == NULL) { + return 1; + } + scaled_theme->scale = scale; + scaled_theme->theme = wlr_xcursor_theme_load(NULL, + ROOTS_XCURSOR_SIZE * scale); + if (scaled_theme->theme == NULL) { + free(scaled_theme); + return 1; + } + wl_list_insert(&theme->scaled_themes, &scaled_theme->link); + return 0; +} + +static void roots_xcursor_theme_set(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor, const char *name) { + struct roots_xcursor_scaled_theme *scaled_theme; + wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { + struct wlr_xcursor *xcursor = + wlr_xcursor_theme_get_cursor(scaled_theme->theme, name); + if (xcursor == NULL) { + continue; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y, + scaled_theme->scale); + } +} + +void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor) { + roots_xcursor_theme_set(theme, cursor, "left_ptr"); +} + +void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor) { + roots_xcursor_theme_set(theme, cursor, "grabbing"); +} + static const char *get_resize_xcursor_name(uint32_t edges) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { @@ -24,19 +103,32 @@ static const char *get_resize_xcursor_name(uint32_t edges) { return "se-resize"; // fallback } -struct wlr_xcursor *get_default_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "left_ptr"); +void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor, uint32_t edges) { + roots_xcursor_theme_set(theme, cursor, get_resize_xcursor_name(edges)); } -struct wlr_xcursor *get_move_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); +void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, + struct wlr_cursor *cursor) { + roots_xcursor_theme_set(theme, cursor, "grabbing"); } -struct wlr_xcursor *get_resize_xcursor(struct wlr_xcursor_theme *theme, - uint32_t edges) { - return wlr_xcursor_theme_get_cursor(theme, get_resize_xcursor_name(edges)); -} +void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, + struct wlr_xwayland *xwayland) { + struct roots_xcursor_scaled_theme *scaled_theme; + wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { + if (scaled_theme->scale == 1) { + struct wlr_xcursor *xcursor = + wlr_xcursor_theme_get_cursor(scaled_theme->theme, "left_ptr"); + if (xcursor == NULL) { + continue; + } -struct wlr_xcursor *get_rotate_xcursor(struct wlr_xcursor_theme *theme) { - return wlr_xcursor_theme_get_cursor(theme, "grabbing"); + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_xwayland_set_cursor(xwayland, image->buffer, image->width, + image->width, image->height, image->hotspot_x, + image->hotspot_y); + break; + } + } } -- cgit v1.2.3 From 09279b90a63c5fdb2e28a61f2dfc936285126177 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 19:09:34 +0100 Subject: Add wlr_output.serial --- backend/drm/util.c | 9 ++++++++- include/wlr/types/wlr_output.h | 1 + rootston/output.c | 5 +++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/backend/drm/util.c b/backend/drm/util.c index 656c070a..c27d7b67 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -106,8 +106,15 @@ void parse_edid(struct wlr_output *restrict output, size_t len, const uint8_t *d if (nl) { *nl = '\0'; } + } else if (flag == 0 && data[i + 3] == 0xFF) { + sprintf(output->serial, "%.13s", &data[i + 5]); - break; + // Monitor serial numbers are terminated by newline if they're too + // short + char *nl = strchr(output->serial, '\n'); + if (nl) { + *nl = '\0'; + } } } } diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index df123639..cf000019 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -43,6 +43,7 @@ struct wlr_output { char name[16]; char make[48]; char model[16]; + char serial[16]; uint32_t scale; int32_t width, height; int32_t phys_width, phys_height; // mm diff --git a/rootston/output.c b/rootston/output.c index d853c45f..a929e6be 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -210,8 +210,9 @@ void output_add_notify(struct wl_listener *listener, void *data) { struct roots_config *config = desktop->config; wlr_log(L_DEBUG, "Output '%s' added", wlr_output->name); - wlr_log(L_DEBUG, "%s %s %"PRId32"mm x %"PRId32"mm", wlr_output->make, - wlr_output->model, wlr_output->phys_width, wlr_output->phys_height); + wlr_log(L_DEBUG, "%s %s %s %"PRId32"mm x %"PRId32"mm", wlr_output->make, + wlr_output->model, wlr_output->serial, wlr_output->phys_width, + wlr_output->phys_height); if (wl_list_length(&wlr_output->modes) > 0) { struct wlr_output_mode *mode = NULL; mode = wl_container_of((&wlr_output->modes)->prev, mode, link); -- cgit v1.2.3 From 2dccb11741abd99fd71d4ccaba1ad42362d8f204 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 11 Nov 2017 23:53:45 +0100 Subject: rootston: keep one xcursor_theme per seat --- include/rootston/cursor.h | 1 + rootston/cursor.c | 2 +- rootston/output.c | 11 ++++++----- rootston/seat.c | 12 +++++++----- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index fc71e31d..575c9d0e 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -30,6 +30,7 @@ struct roots_cursor { enum roots_cursor_mode mode; // state from input (review if this is necessary) + struct roots_xcursor_theme *xcursor_theme; struct wlr_seat *wl_seat; struct wl_client *cursor_client; int offs_x, offs_y; diff --git a/rootston/cursor.c b/rootston/cursor.c index 46f4caea..0795cea6 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -44,7 +44,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - roots_xcursor_theme_set_default(desktop->xcursor_theme, + roots_xcursor_theme_set_default(cursor->xcursor_theme, cursor->cursor); cursor->cursor_client = NULL; } diff --git a/rootston/output.c b/rootston/output.c index 943e14c0..b35e56cd 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -241,13 +241,14 @@ void output_add_notify(struct wl_listener *listener, void *data) { wlr_output_layout_add_auto(desktop->layout, wlr_output); } - if (roots_xcursor_theme_load(desktop->xcursor_theme, wlr_output->scale)) { - wlr_log(L_ERROR, "Cannot load xcursor theme with scale %d", - wlr_output->scale); - } - struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { + if (roots_xcursor_theme_load(seat->cursor->xcursor_theme, + wlr_output->scale)) { + wlr_log(L_ERROR, "Cannot load xcursor theme for output '%s' " + "with scale %d", wlr_output->name, wlr_output->scale); + } + roots_seat_configure_cursor(seat); roots_seat_configure_xcursor(seat); } diff --git a/rootston/seat.c b/rootston/seat.c index 376da67f..ec4e9800 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -186,7 +186,9 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { struct roots_desktop *desktop = seat->input->server->desktop; wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); - roots_xcursor_theme_set_default(desktop->xcursor_theme, wlr_cursor); + // TODO: be able to configure per-seat cursor themes + seat->cursor->xcursor_theme = desktop->xcursor_theme; + roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, wlr_cursor); wl_list_init(&seat->cursor->touch_points); @@ -444,7 +446,7 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - roots_xcursor_theme_set_default(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); @@ -522,7 +524,7 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_move(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_move(seat->cursor->xcursor_theme, seat->cursor->cursor); } @@ -549,7 +551,7 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_resize(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_resize(seat->cursor->xcursor_theme, seat->cursor->cursor, edges); } @@ -562,6 +564,6 @@ void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_rotate(seat->input->server->desktop->xcursor_theme, + roots_xcursor_theme_set_rotate(seat->cursor->xcursor_theme, seat->cursor->cursor); } -- cgit v1.2.3 From 8605243459629f566ed5109ffd896fd57b329ceb Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 12 Nov 2017 11:10:56 +0100 Subject: Introduce wlr_xcursor_manager --- include/rootston/cursor.h | 2 +- include/rootston/desktop.h | 2 +- include/rootston/xcursor.h | 40 ++---------- include/wlr/types/wlr_cursor.h | 1 - include/wlr/types/wlr_xcursor_manager.h | 53 ++++++++++++++++ include/wlr/xcursor.h | 2 +- rootston/cursor.c | 5 +- rootston/desktop.c | 21 +++++-- rootston/output.c | 4 +- rootston/seat.c | 22 ++++--- rootston/xcursor.c | 108 +------------------------------- types/meson.build | 3 +- types/wlr_xcursor_manager.c | 84 +++++++++++++++++++++++++ 13 files changed, 180 insertions(+), 167 deletions(-) create mode 100644 include/wlr/types/wlr_xcursor_manager.h create mode 100644 types/wlr_xcursor_manager.c diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 575c9d0e..f49b6439 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -30,7 +30,7 @@ struct roots_cursor { enum roots_cursor_mode mode; // state from input (review if this is necessary) - struct roots_xcursor_theme *xcursor_theme; + struct wlr_xcursor_manager *xcursor_manager; struct wlr_seat *wl_seat; struct wl_client *cursor_client; int offs_x, offs_y; diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index b12fff70..7371284f 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -30,9 +30,9 @@ struct roots_desktop { struct roots_server *server; struct roots_config *config; - struct roots_xcursor_theme *xcursor_theme; struct wlr_output_layout *layout; + struct wlr_xcursor_manager *xcursor_manager; struct wlr_compositor *compositor; struct wlr_wl_shell *wl_shell; diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h index 45fac481..bc00f79c 100644 --- a/include/rootston/xcursor.h +++ b/include/rootston/xcursor.h @@ -1,44 +1,14 @@ #ifndef _ROOTSTON_XCURSOR_H #define _ROOTSTON_XCURSOR_H -#include -#include -#include -#include +#include #define ROOTS_XCURSOR_SIZE 16 -struct roots_xcursor_scaled_theme { - uint32_t scale; - struct wlr_xcursor_theme *theme; - struct wl_list link; -}; +#define ROOTS_XCURSOR_DEFAULT "left_ptr" +#define ROOTS_XCURSOR_MOVE "grabbing" +#define ROOTS_XCURSOR_ROTATE "grabbing" -struct roots_xcursor_theme { - char *name; - struct wl_list scaled_themes; // roots_xcursor_scaled_theme::link -}; - -struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name); - -void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme); - -int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, - uint32_t scale); - -void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor); - -void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor); - -void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor, uint32_t edges); - -void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor); - -void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, - struct wlr_xwayland *xwayland); +const char *roots_xcursor_get_resize_name(uint32_t edges); #endif diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 3df74d28..0db32eb2 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -6,7 +6,6 @@ #include #include #include -#include struct wlr_cursor_state; diff --git a/include/wlr/types/wlr_xcursor_manager.h b/include/wlr/types/wlr_xcursor_manager.h new file mode 100644 index 00000000..c78a6e8d --- /dev/null +++ b/include/wlr/types/wlr_xcursor_manager.h @@ -0,0 +1,53 @@ +#ifndef WLR_TYPES_WLR_XCURSOR_MANAGER_H +#define WLR_TYPES_WLR_XCURSOR_MANAGER_H + +#include +#include +#include + +/** + * A scaled XCursor theme. + */ +struct wlr_xcursor_manager_theme { + uint32_t scale; + struct wlr_xcursor_theme *theme; + struct wl_list link; +}; + +/** + * Manage multiple XCursor themes with different scales and set `wlr_cursor` + * images. + * + * This manager can be used to display cursor images on multiple outputs having + * different scale factors. + */ +struct wlr_xcursor_manager { + char *name; + uint32_t size; + struct wl_list scaled_themes; // wlr_xcursor_manager_theme::link +}; + +/** + * Create a new XCursor manager. After initialization, scaled themes need to be + * loaded with `wlr_xcursor_manager_load`. `size` is the unscaled cursor theme + * size. + */ +struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name, + uint32_t size); + +void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager); + +int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, + uint32_t scale); + +struct wlr_xcursor *wlr_xcursor_manager_get_xcursor( + struct wlr_xcursor_manager *manager, const char *name, uint32_t scale); + +/** + * Set a `wlr_cursor` image. The manager uses all currently loaded scaled + * themes. + */ +void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager, + const char *name, struct wlr_cursor *cursor); + +#endif diff --git a/include/wlr/xcursor.h b/include/wlr/xcursor.h index c12d5405..b6362b06 100644 --- a/include/wlr/xcursor.h +++ b/include/wlr/xcursor.h @@ -61,7 +61,7 @@ struct wlr_xcursor_theme *wlr_xcursor_theme_load(const char *name, int size); void wlr_xcursor_theme_destroy(struct wlr_xcursor_theme *theme); struct wlr_xcursor *wlr_xcursor_theme_get_cursor( - struct wlr_xcursor_theme *theme, const char *name); + struct wlr_xcursor_theme *theme, const char *name); int wlr_xcursor_frame(struct wlr_xcursor *cursor, uint32_t time); diff --git a/rootston/cursor.c b/rootston/cursor.c index 0795cea6..ecd5e9a0 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -6,6 +6,7 @@ #elif __FreeBSD__ #include #endif +#include #include #include "rootston/xcursor.h" #include "rootston/cursor.h" @@ -44,8 +45,8 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t t set_compositor_cursor = view_client != cursor->cursor_client; } if (set_compositor_cursor) { - roots_xcursor_theme_set_default(cursor->xcursor_theme, - cursor->cursor); + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + ROOTS_XCURSOR_DEFAULT, cursor->cursor); cursor->cursor_client = NULL; } if (view) { diff --git a/rootston/desktop.c b/rootston/desktop.c index e20fceab..bb030e74 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -324,8 +325,10 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->server = server; desktop->config = config; - desktop->xcursor_theme = roots_xcursor_theme_create("default"); - if (desktop->xcursor_theme == NULL) { + desktop->xcursor_manager = wlr_xcursor_manager_create(NULL, + ROOTS_XCURSOR_SIZE); + if (desktop->xcursor_manager == NULL) { + wlr_log(L_ERROR, "Cannot create XCursor manager"); wlr_list_free(desktop->views); free(desktop); return NULL; @@ -353,11 +356,17 @@ struct roots_desktop *desktop_create(struct roots_server *server, &desktop->xwayland_surface); desktop->xwayland_surface.notify = handle_xwayland_surface; - if (roots_xcursor_theme_load(desktop->xcursor_theme, 1)) { - wlr_log(L_ERROR, "Cannot load xwayland xcursor theme"); + if (wlr_xcursor_manager_load(desktop->xcursor_manager, 1)) { + wlr_log(L_ERROR, "Cannot load XWayland XCursor theme"); + } + struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( + desktop->xcursor_manager, ROOTS_XCURSOR_DEFAULT, 1); + if (xcursor != NULL) { + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_xwayland_set_cursor(desktop->xwayland, image->buffer, + image->width, image->width, image->height, image->hotspot_x, + image->hotspot_y); } - roots_xcursor_theme_xwayland_set_default(desktop->xcursor_theme, - desktop->xwayland); } #endif diff --git a/rootston/output.c b/rootston/output.c index b35e56cd..cd288195 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -5,13 +5,13 @@ #include #include #include +#include #include #include #include #include "rootston/server.h" #include "rootston/desktop.h" #include "rootston/config.h" -#include "rootston/xcursor.h" static inline int64_t timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; @@ -243,7 +243,7 @@ void output_add_notify(struct wl_listener *listener, void *data) { struct roots_seat *seat; wl_list_for_each(seat, &input->seats, link) { - if (roots_xcursor_theme_load(seat->cursor->xcursor_theme, + if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager, wlr_output->scale)) { wlr_log(L_ERROR, "Cannot load xcursor theme for output '%s' " "with scale %d", wlr_output->name, wlr_output->scale); diff --git a/rootston/seat.c b/rootston/seat.c index ec4e9800..8a838efe 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -3,6 +3,7 @@ #include #include +#include #include #include "rootston/xcursor.h" @@ -187,8 +188,9 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { wlr_cursor_attach_output_layout(wlr_cursor, desktop->layout); // TODO: be able to configure per-seat cursor themes - seat->cursor->xcursor_theme = desktop->xcursor_theme; - roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, wlr_cursor); + seat->cursor->xcursor_manager = desktop->xcursor_manager; + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_DEFAULT, wlr_cursor); wl_list_init(&seat->cursor->touch_points); @@ -446,8 +448,8 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { - roots_xcursor_theme_set_default(seat->cursor->xcursor_theme, - seat->cursor->cursor); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_DEFAULT, seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); } @@ -524,8 +526,8 @@ void roots_seat_begin_move(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_move(seat->cursor->xcursor_theme, - seat->cursor->cursor); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_MOVE, seat->cursor->cursor); } void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, @@ -551,8 +553,8 @@ void roots_seat_begin_resize(struct roots_seat *seat, struct roots_view *view, view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_resize(seat->cursor->xcursor_theme, - seat->cursor->cursor, edges); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + roots_xcursor_get_resize_name(edges), seat->cursor->cursor); } void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { @@ -564,6 +566,6 @@ void roots_seat_begin_rotate(struct roots_seat *seat, struct roots_view *view) { view_maximize(view, false); wlr_seat_pointer_clear_focus(seat->seat); - roots_xcursor_theme_set_rotate(seat->cursor->xcursor_theme, - seat->cursor->cursor); + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, + ROOTS_XCURSOR_ROTATE, seat->cursor->cursor); } diff --git a/rootston/xcursor.c b/rootston/xcursor.c index 6aa74bc4..74e732c9 100644 --- a/rootston/xcursor.c +++ b/rootston/xcursor.c @@ -4,83 +4,7 @@ #include "rootston/xcursor.h" #include "rootston/input.h" -struct roots_xcursor_theme *roots_xcursor_theme_create(const char *name) { - struct roots_xcursor_theme *theme = - calloc(1, sizeof(struct roots_xcursor_theme)); - if (theme == NULL) { - return NULL; - } - theme->name = strdup(name); - wl_list_init(&theme->scaled_themes); - return theme; -} - -void roots_xcursor_theme_destroy(struct roots_xcursor_theme *theme) { - if (theme == NULL) { - return; - } - struct roots_xcursor_scaled_theme *scaled_theme, *tmp; - wl_list_for_each_safe(scaled_theme, tmp, &theme->scaled_themes, link) { - wl_list_remove(&scaled_theme->link); - wlr_xcursor_theme_destroy(scaled_theme->theme); - free(scaled_theme); - } - free(theme->name); - free(theme); -} - -int roots_xcursor_theme_load(struct roots_xcursor_theme *theme, - uint32_t scale) { - struct roots_xcursor_scaled_theme *scaled_theme; - wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { - if (scaled_theme->scale == scale) { - return 0; - } - } - - scaled_theme = calloc(1, sizeof(struct roots_xcursor_scaled_theme)); - if (scaled_theme == NULL) { - return 1; - } - scaled_theme->scale = scale; - scaled_theme->theme = wlr_xcursor_theme_load(NULL, - ROOTS_XCURSOR_SIZE * scale); - if (scaled_theme->theme == NULL) { - free(scaled_theme); - return 1; - } - wl_list_insert(&theme->scaled_themes, &scaled_theme->link); - return 0; -} - -static void roots_xcursor_theme_set(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor, const char *name) { - struct roots_xcursor_scaled_theme *scaled_theme; - wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { - struct wlr_xcursor *xcursor = - wlr_xcursor_theme_get_cursor(scaled_theme->theme, name); - if (xcursor == NULL) { - continue; - } - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_cursor_set_image(cursor, image->buffer, image->width, - image->width, image->height, image->hotspot_x, image->hotspot_y, - scaled_theme->scale); - } -} - -void roots_xcursor_theme_set_default(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor) { - roots_xcursor_theme_set(theme, cursor, "left_ptr"); -} - -void roots_xcursor_theme_set_move(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor) { - roots_xcursor_theme_set(theme, cursor, "grabbing"); -} - -static const char *get_resize_xcursor_name(uint32_t edges) { +const char *roots_xcursor_get_resize_name(uint32_t edges) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { if (edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { return "ne-resize"; @@ -102,33 +26,3 @@ static const char *get_resize_xcursor_name(uint32_t edges) { } return "se-resize"; // fallback } - -void roots_xcursor_theme_set_resize(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor, uint32_t edges) { - roots_xcursor_theme_set(theme, cursor, get_resize_xcursor_name(edges)); -} - -void roots_xcursor_theme_set_rotate(struct roots_xcursor_theme *theme, - struct wlr_cursor *cursor) { - roots_xcursor_theme_set(theme, cursor, "grabbing"); -} - -void roots_xcursor_theme_xwayland_set_default(struct roots_xcursor_theme *theme, - struct wlr_xwayland *xwayland) { - struct roots_xcursor_scaled_theme *scaled_theme; - wl_list_for_each(scaled_theme, &theme->scaled_themes, link) { - if (scaled_theme->scale == 1) { - struct wlr_xcursor *xcursor = - wlr_xcursor_theme_get_cursor(scaled_theme->theme, "left_ptr"); - if (xcursor == NULL) { - continue; - } - - struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(xwayland, image->buffer, image->width, - image->width, image->height, image->hotspot_x, - image->hotspot_y); - break; - } - } -} diff --git a/types/meson.build b/types/meson.build index 2603ecfd..4669165a 100644 --- a/types/meson.build +++ b/types/meson.build @@ -20,8 +20,9 @@ lib_wlr_types = static_library( 'wlr_tablet_pad.c', 'wlr_tablet_tool.c', 'wlr_touch.c', - 'wlr_xdg_shell_v6.c', 'wlr_wl_shell.c', + 'wlr_xcursor_manager.c', + 'wlr_xdg_shell_v6.c', ), include_directories: wlr_inc, dependencies: [wayland_server, pixman, wlr_protos], diff --git a/types/wlr_xcursor_manager.c b/types/wlr_xcursor_manager.c new file mode 100644 index 00000000..6c12d04b --- /dev/null +++ b/types/wlr_xcursor_manager.c @@ -0,0 +1,84 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include + +struct wlr_xcursor_manager *wlr_xcursor_manager_create(const char *name, + uint32_t size) { + struct wlr_xcursor_manager *manager = + calloc(1, sizeof(struct wlr_xcursor_manager)); + if (manager == NULL) { + return NULL; + } + if (name != NULL) { + manager->name = strdup(name); + } + manager->size = size; + wl_list_init(&manager->scaled_themes); + return manager; +} + +void wlr_xcursor_manager_destroy(struct wlr_xcursor_manager *manager) { + if (manager == NULL) { + return; + } + struct wlr_xcursor_manager_theme *theme, *tmp; + wl_list_for_each_safe(theme, tmp, &manager->scaled_themes, link) { + wl_list_remove(&theme->link); + wlr_xcursor_theme_destroy(theme->theme); + free(theme); + } + free(manager->name); + free(manager); +} + +int wlr_xcursor_manager_load(struct wlr_xcursor_manager *manager, + uint32_t scale) { + struct wlr_xcursor_manager_theme *theme; + wl_list_for_each(theme, &manager->scaled_themes, link) { + if (theme->scale == scale) { + return 0; + } + } + + theme = calloc(1, sizeof(struct wlr_xcursor_manager_theme)); + if (theme == NULL) { + return 1; + } + theme->scale = scale; + theme->theme = wlr_xcursor_theme_load(NULL, manager->size * scale); + if (theme->theme == NULL) { + free(theme); + return 1; + } + wl_list_insert(&manager->scaled_themes, &theme->link); + return 0; +} + +struct wlr_xcursor *wlr_xcursor_manager_get_xcursor( + struct wlr_xcursor_manager *manager, const char *name, uint32_t scale) { + struct wlr_xcursor_manager_theme *theme; + wl_list_for_each(theme, &manager->scaled_themes, link) { + if (theme->scale == scale) { + return wlr_xcursor_theme_get_cursor(theme->theme, name); + } + } + return NULL; +} + +void wlr_xcursor_manager_set_cursor_image(struct wlr_xcursor_manager *manager, + const char *name, struct wlr_cursor *cursor) { + struct wlr_xcursor_manager_theme *theme; + wl_list_for_each(theme, &manager->scaled_themes, link) { + struct wlr_xcursor *xcursor = + wlr_xcursor_theme_get_cursor(theme->theme, name); + if (xcursor == NULL) { + continue; + } + + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_cursor_set_image(cursor, image->buffer, image->width, + image->width, image->height, image->hotspot_x, image->hotspot_y, + theme->scale); + } +} -- cgit v1.2.3 From 0b3f83d93adf23dcc0737928de355f555dd82dee Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 12 Nov 2017 12:38:08 +0100 Subject: Fix pointer input for rotated views on HiDPI outputs --- rootston/desktop.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index 448171ec..dcf36ecf 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -216,7 +216,7 @@ void view_teardown(struct roots_view *view) { struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { - for (int i = desktop->views->length - 1; i >= 0; --i) { + for (ssize_t i = desktop->views->length - 1; i >= 0; --i) { struct roots_view *view = desktop->views->items[i]; if (view->type == ROOTS_WL_SHELL_VIEW && @@ -228,11 +228,12 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, double view_sx = lx - view->x; double view_sy = ly - view->y; + struct wlr_surface_state *state = view->wlr_surface->current; struct wlr_box box = { .x = 0, .y = 0, - .width = view->wlr_surface->current->buffer_width, - .height = view->wlr_surface->current->buffer_height, + .width = state->buffer_width / state->scale, + .height = state->buffer_height / state->scale, }; if (view->rotation != 0.0) { // Coordinates relative to the center of the view -- cgit v1.2.3 From 454bea678b6c253ac102522f7af1ffd75de92de1 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 12 Nov 2017 12:54:45 +0100 Subject: Fix rendering of rotated views on HiDPI outputs --- rootston/desktop.c | 2 -- rootston/output.c | 43 ++++++++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index dcf36ecf..4d744597 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -247,7 +247,6 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, } if (view->type == ROOTS_XDG_SHELL_V6_VIEW) { - // TODO: test if this works with rotated views double popup_sx, popup_sy; struct wlr_xdg_surface_v6 *popup = wlr_xdg_surface_v6_popup_at(view->xdg_surface_v6, @@ -262,7 +261,6 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, } if (view->type == ROOTS_WL_SHELL_VIEW) { - // TODO: test if this works with rotated views double popup_sx, popup_sy; struct wlr_wl_shell_surface *popup = wlr_wl_shell_surface_popup_at(view->wl_shell_surface, diff --git a/rootston/output.c b/rootston/output.c index a929e6be..4b7a4b00 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -20,30 +20,33 @@ static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { if (surface->texture->valid) { - float scale_factor = (float)wlr_output->scale / surface->current->scale; - int width = surface->current->buffer_width * scale_factor; - int height = surface->current->buffer_height * scale_factor; + double surface_scale = surface->current->scale; + double width = (double)surface->current->buffer_width / surface_scale; + double height = (double)surface->current->buffer_height / surface_scale; + int render_width = width * wlr_output->scale; + int render_height = height * wlr_output->scale; double ox = lx, oy = ly; wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); ox *= wlr_output->scale; oy *= wlr_output->scale; if (wlr_output_layout_intersects(desktop->layout, wlr_output, - lx, ly, lx + width, ly + height)) { + lx, ly, lx + render_width, ly + render_height)) { float matrix[16]; float translate_origin[16]; wlr_matrix_translate(&translate_origin, - (int)ox + width / 2, (int)oy + height / 2, 0); + (int)ox + render_width / 2, (int)oy + render_height / 2, 0); float rotate[16]; wlr_matrix_rotate(&rotate, rotation); float translate_center[16]; - wlr_matrix_translate(&translate_center, -width / 2, -height / 2, 0); + wlr_matrix_translate(&translate_center, -render_width / 2, + -render_height / 2, 0); float scale[16]; - wlr_matrix_scale(&scale, width, height, 1); + wlr_matrix_scale(&scale, render_width, render_height, 1); float transform[16]; wlr_matrix_mul(&translate_origin, &rotate, &transform); @@ -51,12 +54,12 @@ static void render_surface(struct wlr_surface *surface, wlr_matrix_mul(&transform, &scale, &transform); wlr_matrix_mul(&wlr_output->transform_matrix, &transform, &matrix); - wlr_render_with_matrix(desktop->server->renderer, - surface->texture, &matrix); + wlr_render_with_matrix(desktop->server->renderer, surface->texture, + &matrix); struct wlr_frame_callback *cb, *cnext; wl_list_for_each_safe(cb, cnext, - &surface->current->frame_callback_list, link) { + &surface->current->frame_callback_list, link) { wl_callback_send_done(cb->resource, timespec_to_msec(when)); wl_resource_destroy(cb->resource); } @@ -64,19 +67,20 @@ static void render_surface(struct wlr_surface *surface, struct wlr_subsurface *subsurface; wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { - double sx = subsurface->surface->current->subsurface_position.x, - sy = subsurface->surface->current->subsurface_position.y; - double sw = subsurface->surface->current->buffer_width, - sh = subsurface->surface->current->buffer_height; + struct wlr_surface_state *state = subsurface->surface->current; + double sx = state->subsurface_position.x; + double sy = state->subsurface_position.y; + double sw = state->buffer_width / state->scale; + double sh = state->buffer_height / state->scale; if (rotation != 0.0) { // Coordinates relative to the center of the subsurface - double ox = sx - (double)width/2 + sw/2, - oy = sy - (double)height/2 + sh/2; + double ox = sx - width/2 + sw/2, + oy = sy - height/2 + sh/2; // Rotated coordinates double rx = cos(-rotation)*ox - sin(-rotation)*oy, ry = cos(-rotation)*oy + sin(-rotation)*ox; - sx = rx + (double)width/2 - sw/2; - sy = ry + (double)height/2 - sh/2; + sx = rx + width/2 - sw/2; + sy = ry + height/2 - sh/2; } render_surface(subsurface->surface, desktop, wlr_output, when, @@ -103,7 +107,8 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, popup->popup_state->geometry.y - popup->geometry->y; render_surface(popup->surface, desktop, wlr_output, when, popup_x, popup_y, rotation); - render_xdg_v6_popups(popup, desktop, wlr_output, when, popup_x, popup_y, rotation); + render_xdg_v6_popups(popup, desktop, wlr_output, when, popup_x, popup_y, + rotation); } } -- cgit v1.2.3 From 5d986f1e874f93f8235fbcc333af63c5c9c99596 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 12 Nov 2017 15:49:27 +0100 Subject: Remove unnecessary include --- include/rootston/desktop.h | 2 +- rootston/desktop.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 7371284f..b809db43 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -7,12 +7,12 @@ #include #include #include +#include #include #include #include #include "rootston/view.h" #include "rootston/config.h" -#include "rootston/xcursor.h" struct roots_output { struct roots_desktop *desktop; diff --git a/rootston/desktop.c b/rootston/desktop.c index bb030e74..51bb0e2a 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -16,6 +16,7 @@ #include #include "rootston/server.h" #include "rootston/seat.h" +#include "rootston/xcursor.h" // TODO replace me with a signal void view_destroy(struct roots_view *view) { -- cgit v1.2.3 From 1e0e73efaa5584b49405e119bf4ce3810785654e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 12 Nov 2017 09:55:28 -0500 Subject: Spawn views on last active output --- include/rootston/seat.h | 2 -- include/wlr/types/wlr_seat.h | 3 ++- rootston/desktop.c | 15 ++++++++++++++- rootston/seat.c | 6 ++---- types/wlr_seat.c | 6 ++++++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/include/rootston/seat.h b/include/rootston/seat.h index b5593651..bef515a4 100644 --- a/include/rootston/seat.h +++ b/include/rootston/seat.h @@ -1,8 +1,6 @@ #ifndef _ROOTSTON_SEAT_H #define _ROOTSTON_SEAT_H - #include - #include "rootston/input.h" #include "rootston/keyboard.h" diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 09d3e282..a5f00402 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -1,6 +1,6 @@ #ifndef WLR_TYPES_WLR_SEAT_H #define WLR_TYPES_WLR_SEAT_H - +#include #include #include #include @@ -109,6 +109,7 @@ struct wlr_seat { struct wl_list clients; char *name; uint32_t capabilities; + struct timespec last_event; struct wlr_data_device *data_device; // TODO needed? struct wlr_data_source *selection_source; diff --git a/rootston/desktop.c b/rootston/desktop.c index 448171ec..75526bcb 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -165,9 +165,22 @@ bool view_center(struct roots_view *view) { view_get_box(view, &box); struct roots_desktop *desktop = view->desktop; + struct roots_input *input = desktop->server->input; + struct roots_seat *seat = NULL, *_seat; + wl_list_for_each(_seat, &input->seats, link) { + if (!seat || (seat->seat->last_event.tv_sec > _seat->seat->last_event.tv_sec && + seat->seat->last_event.tv_nsec > _seat->seat->last_event.tv_nsec)) { + seat = _seat; + } + } + if (!seat) { + return false; + } struct wlr_output *output = - wlr_output_layout_get_center_output(desktop->layout); + wlr_output_layout_output_at(desktop->layout, + seat->cursor->cursor->x, + seat->cursor->cursor->y); if (!output) { // empty layout return false; diff --git a/rootston/seat.c b/rootston/seat.c index 4602aad5..b0688156 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -1,10 +1,8 @@ -#include +#include #include #include -#include - +#include #include - #include "rootston/xcursor.h" #include "rootston/input.h" #include "rootston/seat.h" diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 9de1b3a0..dad88354 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -574,12 +575,14 @@ void wlr_seat_pointer_notify_enter(struct wlr_seat *wlr_seat, void wlr_seat_pointer_notify_motion(struct wlr_seat *wlr_seat, uint32_t time, double sx, double sy) { + clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab; grab->interface->motion(grab, time, sx, sy); } uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat, uint32_t time, uint32_t button, uint32_t state) { + clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); if (state == WL_POINTER_BUTTON_STATE_PRESSED) { if (wlr_seat->pointer_state.button_count == 0) { wlr_seat->pointer_state.grab_button = button; @@ -602,6 +605,7 @@ uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat, void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time, enum wlr_axis_orientation orientation, double value) { + clock_gettime(CLOCK_MONOTONIC, &wlr_seat->last_event); struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab; grab->interface->axis(grab, time, orientation, value); } @@ -804,12 +808,14 @@ void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) { } void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { + clock_gettime(CLOCK_MONOTONIC, &seat->last_event); struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; grab->interface->modifiers(grab); } void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, uint32_t key, uint32_t state) { + clock_gettime(CLOCK_MONOTONIC, &seat->last_event); struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; grab->interface->key(grab, time, key, state); } -- cgit v1.2.3 From a69381ef0ccb15de4cddad317ecf5fdb639ef313 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Sun, 12 Nov 2017 12:15:39 -0500 Subject: rootston: set keyboard on keyboard add --- rootston/seat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rootston/seat.c b/rootston/seat.c index 4602aad5..9eb91a7e 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -322,6 +322,8 @@ static void seat_add_keyboard(struct roots_seat *seat, struct wlr_input_device * keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; wl_signal_add(&keyboard->device->keyboard->events.modifiers, &keyboard->keyboard_modifiers); + + wlr_seat_set_keyboard(seat->seat, device); } static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *device) { -- cgit v1.2.3 From a317ecdab8ef8deb184b72db208794daa4c4a3a0 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 12 Nov 2017 16:01:31 -0500 Subject: Run startup command after xwayland is ready --- include/wlr/xwayland.h | 1 + rootston/main.c | 29 ++++++++++++++++++----------- xwayland/xwayland.c | 3 +++ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index bea97394..6518b703 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -29,6 +29,7 @@ struct wlr_xwayland { struct wlr_xwayland_cursor *cursor; struct { + struct wl_signal ready; struct wl_signal new_surface; } events; diff --git a/rootston/main.c b/rootston/main.c index d55bc682..365ff6e0 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -12,6 +12,18 @@ struct roots_server server = { 0 }; +static void ready(struct wl_listener *listener, void *data) { + if (server.config->startup_cmd != NULL) { + const char *cmd = server.config->startup_cmd; + pid_t pid = fork(); + if (pid < 0) { + wlr_log(L_ERROR, "cannot execute binding command: fork() failed"); + } else if (pid == 0) { + execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); + } + } +} + int main(int argc, char **argv) { assert(server.config = roots_config_create_from_args(argc, argv)); assert(server.wl_display = wl_display_create()); @@ -43,17 +55,12 @@ int main(int argc, char **argv) { } setenv("WAYLAND_DISPLAY", socket, true); - - if (server.config->startup_cmd != NULL) { - const char *cmd = server.config->startup_cmd; - pid_t pid = fork(); - if (pid < 0) { - wlr_log(L_ERROR, "cannot execute binding command: fork() failed"); - return 1; - } else if (pid == 0) { - execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); - } - } +#ifndef HAS_XWAYLAND + ready(NULL, NULL); +#else + struct wl_listener xwayland_ready = { .notify = ready }; + wl_signal_add(&server.desktop->xwayland->events.ready, &xwayland_ready); +#endif wl_display_run(server.wl_display); wlr_backend_destroy(server.backend); diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 0452f04c..ecec785c 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -211,6 +211,8 @@ static int xserver_handle_ready(int signal_number, void *data) { snprintf(display_name, sizeof(display_name), ":%d", wlr_xwayland->display); setenv("DISPLAY", display_name, true); + wl_signal_emit(&wlr_xwayland->events.ready, wlr_xwayland); + return 1; /* wayland event loop dispatcher's count */ } @@ -223,6 +225,7 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, wlr_xwayland->wl_fd[0] = wlr_xwayland->wl_fd[1] = -1; wlr_xwayland->wm_fd[0] = wlr_xwayland->wm_fd[1] = -1; wl_signal_init(&wlr_xwayland->events.new_surface); + wl_signal_init(&wlr_xwayland->events.ready); wlr_xwayland->display = open_display_sockets(wlr_xwayland->x_fd); if (wlr_xwayland->display < 0) { -- cgit v1.2.3 From 2e312a7e27fac0ef299abbdf5f66cf164992f02f Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 12 Nov 2017 22:11:17 +0100 Subject: Fix hidden cursor when output is added before cursor --- rootston/seat.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rootston/seat.c b/rootston/seat.c index 8a838efe..3ec6f1b7 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -189,12 +189,11 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { // TODO: be able to configure per-seat cursor themes seat->cursor->xcursor_manager = desktop->xcursor_manager; - wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, - ROOTS_XCURSOR_DEFAULT, wlr_cursor); wl_list_init(&seat->cursor->touch_points); roots_seat_configure_cursor(seat); + roots_seat_configure_xcursor(seat); // add input signals wl_signal_add(&wlr_cursor->events.motion, &seat->cursor->motion); @@ -448,6 +447,16 @@ void roots_seat_remove_device(struct roots_seat *seat, } void roots_seat_configure_xcursor(struct roots_seat *seat) { + struct roots_output *output; + wl_list_for_each(output, &seat->input->server->desktop->outputs, link) { + if (wlr_xcursor_manager_load(seat->cursor->xcursor_manager, + output->wlr_output->scale)) { + wlr_log(L_ERROR, "Cannot load xcursor theme for output '%s' " + "with scale %d", output->wlr_output->name, + output->wlr_output->scale); + } + } + wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, ROOTS_XCURSOR_DEFAULT, seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, -- cgit v1.2.3 From 94b20da3cecbcfbf36797bc781308eeb18542a75 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 14 Nov 2017 10:20:20 +0100 Subject: Fix popups position for rotated views --- rootston/output.c | 91 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/rootston/output.c b/rootston/output.c index 145016b3..294047d7 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -17,13 +17,40 @@ static inline int64_t timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; } +/** + * Computes the surface size homogeneous to the global compositor coordinates. + */ +static void get_surface_size(struct wlr_surface *surface, double *width, + double *height) { + double surface_scale = surface->current->scale; + *width = (double)surface->current->buffer_width / surface_scale; + *height = (double)surface->current->buffer_height / surface_scale; +} + +/** + * Rotate a child's position relative to a parent. The parent size is (pw, ph), + * the child position is (*sx, *sy) and its size is (sw, sh). + */ +static void rotate_child_position(double *sx, double *sy, double sw, double sh, + double pw, double ph, float rotation) { + if (rotation != 0.0) { + // Coordinates relative to the center of the subsurface + double ox = *sx - pw/2 + sw/2, + oy = *sy - ph/2 + sh/2; + // Rotated coordinates + double rx = cos(-rotation)*ox - sin(-rotation)*oy, + ry = cos(-rotation)*oy + sin(-rotation)*ox; + *sx = rx + pw/2 - sw/2; + *sy = ry + ph/2 - sh/2; + } +} + static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { if (surface->texture->valid) { - double surface_scale = surface->current->scale; - double width = (double)surface->current->buffer_width / surface_scale; - double height = (double)surface->current->buffer_height / surface_scale; + double width, height; + get_surface_size(surface, &width, &height); int render_width = width * wlr_output->scale; int render_height = height * wlr_output->scale; double ox = lx, oy = ly; @@ -73,16 +100,7 @@ static void render_surface(struct wlr_surface *surface, double sy = state->subsurface_position.y; double sw = state->buffer_width / state->scale; double sh = state->buffer_height / state->scale; - if (rotation != 0.0) { - // Coordinates relative to the center of the subsurface - double ox = sx - width/2 + sw/2, - oy = sy - height/2 + sh/2; - // Rotated coordinates - double rx = cos(-rotation)*ox - sin(-rotation)*oy, - ry = cos(-rotation)*oy + sin(-rotation)*ox; - sx = rx + width/2 - sw/2; - sy = ry + height/2 - sh/2; - } + rotate_child_position(&sx, &sy, sw, sh, width, height, rotation); render_surface(subsurface->surface, desktop, wlr_output, when, lx + sx, @@ -95,36 +113,55 @@ static void render_surface(struct wlr_surface *surface, static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double base_x, double base_y, float rotation) { - // TODO: make sure this works with view rotation + double width, height; + get_surface_size(surface->surface, &width, &height); + struct wlr_xdg_surface_v6 *popup; wl_list_for_each(popup, &surface->popups, popup_link) { if (!popup->configured) { continue; } - double popup_x = base_x + surface->geometry->x + - popup->popup_state->geometry.x - popup->geometry->x; - double popup_y = base_y + surface->geometry->y + - popup->popup_state->geometry.y - popup->geometry->y; - render_surface(popup->surface, desktop, wlr_output, when, popup_x, - popup_y, rotation); - render_xdg_v6_popups(popup, desktop, wlr_output, when, popup_x, popup_y, + double sw, sh; + get_surface_size(popup->surface, &sw, &sh); + + double popup_x = surface->geometry->x + popup->popup_state->geometry.x - + popup->geometry->x; + double popup_y = surface->geometry->y + popup->popup_state->geometry.y - + popup->geometry->y; + rotate_child_position(&popup_x, &popup_y, sw, sh, width, height, rotation); + + render_surface(popup->surface, desktop, wlr_output, when, + base_x + popup_x, base_y + popup_y, rotation); + render_xdg_v6_popups(popup, desktop, wlr_output, when, base_x + popup_x, + base_y + popup_y, rotation); } } -static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, struct roots_desktop *desktop, - struct wlr_output *wlr_output, struct timespec *when, double lx, - double ly, float rotation, bool is_child) { +static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, + struct roots_desktop *desktop, struct wlr_output *wlr_output, + struct timespec *when, double lx, double ly, float rotation, + bool is_child) { if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) { render_surface(surface->surface, desktop, wlr_output, when, lx, ly, rotation); + + double width, height; + get_surface_size(surface->surface, &width, &height); + struct wlr_wl_shell_surface *popup; wl_list_for_each(popup, &surface->popups, popup_link) { + double sw, sh; + get_surface_size(popup->surface, &sw, &sh); + + double popup_x = popup->transient_state->x; + double popup_y = popup->transient_state->y; + rotate_child_position(&popup_x, &popup_y, sw, sh, width, height, + rotation); + render_wl_shell_surface(popup, desktop, wlr_output, when, - lx + popup->transient_state->x, - ly + popup->transient_state->y, - rotation, true); + lx + popup_x, ly + popup_y, rotation, true); } } } -- cgit v1.2.3 From 2f44140f4afdab3231d215b913393e3d6a5e36d9 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 14 Nov 2017 15:33:29 +0100 Subject: Don't use buffer size --- rootston/output.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/rootston/output.c b/rootston/output.c index 294047d7..2a39510b 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -17,16 +17,6 @@ static inline int64_t timespec_to_msec(const struct timespec *a) { return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; } -/** - * Computes the surface size homogeneous to the global compositor coordinates. - */ -static void get_surface_size(struct wlr_surface *surface, double *width, - double *height) { - double surface_scale = surface->current->scale; - *width = (double)surface->current->buffer_width / surface_scale; - *height = (double)surface->current->buffer_height / surface_scale; -} - /** * Rotate a child's position relative to a parent. The parent size is (pw, ph), * the child position is (*sx, *sy) and its size is (sw, sh). @@ -49,8 +39,9 @@ static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { if (surface->texture->valid) { - double width, height; - get_surface_size(surface, &width, &height); + double surface_scale = surface->current->scale; + double width = (double)surface->current->buffer_width / surface_scale; + double height = (double)surface->current->buffer_height / surface_scale; int render_width = width * wlr_output->scale; int render_height = height * wlr_output->scale; double ox = lx, oy = ly; @@ -113,8 +104,8 @@ static void render_surface(struct wlr_surface *surface, static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double base_x, double base_y, float rotation) { - double width, height; - get_surface_size(surface->surface, &width, &height); + double width = surface->surface->current->width; + double height = surface->surface->current->height; struct wlr_xdg_surface_v6 *popup; wl_list_for_each(popup, &surface->popups, popup_link) { @@ -122,15 +113,15 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, continue; } - double sw, sh; - get_surface_size(popup->surface, &sw, &sh); + double popup_width = popup->surface->current->width; + double popup_height = popup->surface->current->height; double popup_x = surface->geometry->x + popup->popup_state->geometry.x - popup->geometry->x; double popup_y = surface->geometry->y + popup->popup_state->geometry.y - popup->geometry->y; - rotate_child_position(&popup_x, &popup_y, sw, sh, width, height, - rotation); + rotate_child_position(&popup_x, &popup_y, popup_width, popup_height, + width, height, rotation); render_surface(popup->surface, desktop, wlr_output, when, base_x + popup_x, base_y + popup_y, rotation); @@ -147,18 +138,18 @@ static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface, render_surface(surface->surface, desktop, wlr_output, when, lx, ly, rotation); - double width, height; - get_surface_size(surface->surface, &width, &height); + double width = surface->surface->current->width; + double height = surface->surface->current->height; struct wlr_wl_shell_surface *popup; wl_list_for_each(popup, &surface->popups, popup_link) { - double sw, sh; - get_surface_size(popup->surface, &sw, &sh); + double popup_width = popup->surface->current->width; + double popup_height = popup->surface->current->height; double popup_x = popup->transient_state->x; double popup_y = popup->transient_state->y; - rotate_child_position(&popup_x, &popup_y, sw, sh, width, height, - rotation); + rotate_child_position(&popup_x, &popup_y, popup_width, popup_height, + width, height, rotation); render_wl_shell_surface(popup, desktop, wlr_output, when, lx + popup_x, ly + popup_y, rotation, true); -- cgit v1.2.3 From bb973ff27d5b735d2eb8ec620d7ea74e43eab301 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 14 Nov 2017 21:18:34 +0100 Subject: Remove remaining buffer_{width,height} usage --- rootston/output.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rootston/output.c b/rootston/output.c index 2a39510b..cfab3756 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -39,9 +39,8 @@ static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when, double lx, double ly, float rotation) { if (surface->texture->valid) { - double surface_scale = surface->current->scale; - double width = (double)surface->current->buffer_width / surface_scale; - double height = (double)surface->current->buffer_height / surface_scale; + int width = surface->current->width; + int height = surface->current->height; int render_width = width * wlr_output->scale; int render_height = height * wlr_output->scale; double ox = lx, oy = ly; -- cgit v1.2.3 From 3f6cf517b9b8d5efa0c6001db5ed0871e5d8d2b4 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 15 Nov 2017 14:03:13 +0100 Subject: Add wlr_xdg_surface_v6_popup_get_position --- include/wlr/types/wlr_xdg_shell_v6.h | 6 ++++++ rootston/output.c | 14 ++++++-------- types/wlr_xdg_shell_v6.c | 10 ++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 07911ffa..e3982003 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -209,6 +209,12 @@ void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface, */ void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface); +/** + * Compute the popup position in surface-local coordinates. + */ +void wlr_xdg_surface_v6_popup_get_position(struct wlr_xdg_surface_v6 *surface, + double *popup_sx, double *popup_sy); + /** * Find a popup within this surface at the surface-local coordinates. Returns * the popup and coordinates in the topmost surface coordinate system or NULL if diff --git a/rootston/output.c b/rootston/output.c index cfab3756..28312c2c 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -115,17 +115,15 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface, double popup_width = popup->surface->current->width; double popup_height = popup->surface->current->height; - double popup_x = surface->geometry->x + popup->popup_state->geometry.x - - popup->geometry->x; - double popup_y = surface->geometry->y + popup->popup_state->geometry.y - - popup->geometry->y; - rotate_child_position(&popup_x, &popup_y, popup_width, popup_height, + double popup_sx, popup_sy; + wlr_xdg_surface_v6_popup_get_position(popup, &popup_sx, &popup_sy); + rotate_child_position(&popup_sx, &popup_sy, popup_width, popup_height, width, height, rotation); render_surface(popup->surface, desktop, wlr_output, when, - base_x + popup_x, base_y + popup_y, rotation); - render_xdg_v6_popups(popup, desktop, wlr_output, when, base_x + popup_x, - base_y + popup_y, rotation); + base_x + popup_sx, base_y + popup_sy, rotation); + render_xdg_v6_popups(popup, desktop, wlr_output, when, + base_x + popup_sx, base_y + popup_sy, rotation); } } diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index 05ca2b76..429baa70 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1350,6 +1350,16 @@ void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface) { zxdg_toplevel_v6_send_close(surface->toplevel_state->resource); } +void wlr_xdg_surface_v6_popup_get_position(struct wlr_xdg_surface_v6 *surface, + double *popup_sx, double *popup_sy) { + assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP); + struct wlr_xdg_surface_v6 *parent = surface->popup_state->parent; + *popup_sx = parent->geometry->x + surface->popup_state->geometry.x - + surface->geometry->x; + *popup_sy = parent->geometry->y + surface->popup_state->geometry.y - + surface->geometry->y; +} + struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at( struct wlr_xdg_surface_v6 *surface, double sx, double sy, double *popup_sx, double *popup_sy) { -- cgit v1.2.3 From bf1f461eba320cdeded1d5d8ae80caaa9d4cef98 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 15 Nov 2017 22:35:16 +0100 Subject: Call wl_output_send_done when current mode is updated --- types/wlr_output.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/types/wlr_output.c b/types/wlr_output.c index df02afec..411dd404 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -29,8 +29,7 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { if (version >= WL_OUTPUT_MODE_SINCE_VERSION) { struct wlr_output_mode *mode; wl_list_for_each(mode, &output->modes, link) { - // TODO: mode->flags should just be preferred - uint32_t flags = mode->flags; + uint32_t flags = mode->flags & WL_OUTPUT_MODE_PREFERRED; if (output->current_mode == mode) { flags |= WL_OUTPUT_MODE_CURRENT; } @@ -62,13 +61,17 @@ static void wlr_output_send_current_mode_to_resource( } if (output->current_mode != NULL) { struct wlr_output_mode *mode = output->current_mode; - wl_output_send_mode(resource, mode->flags | WL_OUTPUT_MODE_CURRENT, + uint32_t flags = mode->flags & WL_OUTPUT_MODE_PREFERRED; + wl_output_send_mode(resource, flags | WL_OUTPUT_MODE_CURRENT, mode->width, mode->height, mode->refresh); } else { // Output has no mode, send the current width/height wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT, output->width, output->height, 0); } + if (version >= WL_OUTPUT_DONE_SINCE_VERSION) { + wl_output_send_done(resource); + } } static void wl_output_destroy(struct wl_resource *resource) { @@ -163,6 +166,9 @@ bool wlr_output_set_mode(struct wlr_output *output, void wlr_output_update_size(struct wlr_output *output, int32_t width, int32_t height) { + if (output->width == width && output->height == height) { + return; + } output->width = width; output->height = height; wlr_output_update_matrix(output); -- cgit v1.2.3 From 73c48f2f35ffea2f4fb03f54e652559be4bfe658 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 09:33:47 +0100 Subject: Terminate local display on remote Wayland display error --- backend/wayland/backend.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 532935b8..bfc73e05 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -12,10 +12,15 @@ #include "backend/wayland.h" #include "xdg-shell-unstable-v6-client-protocol.h" - static int dispatch_events(int fd, uint32_t mask, void *data) { struct wlr_wl_backend *backend = data; int count = 0; + + if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) { + wl_display_terminate(backend->local_display); + return 0; + } + if (mask & WL_EVENT_READABLE) { count = wl_display_dispatch(backend->remote_display); } -- cgit v1.2.3 From 7d847efe403c01a842a3e237b49249c95372d9de Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 09:38:24 +0100 Subject: Terminate local display on remote X11 server error --- backend/wayland/backend.c | 7 +++---- backend/x11/backend.c | 10 ++++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index bfc73e05..1801f3e0 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -41,7 +41,7 @@ static bool wlr_wl_backend_start(struct wlr_backend *_backend) { wlr_log(L_INFO, "Initializating wayland backend"); wlr_wl_registry_poll(backend); - if (!(backend->compositor) || (!(backend->shell))) { + if (!backend->compositor || !backend->shell) { wlr_log_errno(L_ERROR, "Could not obtain retrieve required globals"); return false; } @@ -54,10 +54,9 @@ static bool wlr_wl_backend_start(struct wlr_backend *_backend) { struct wl_event_loop *loop = wl_display_get_event_loop(backend->local_display); int fd = wl_display_get_fd(backend->remote_display); - int events = WL_EVENT_READABLE | WL_EVENT_ERROR | - WL_EVENT_HANGUP; + int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP; backend->remote_display_src = wl_event_loop_add_fd(loop, fd, events, - dispatch_events, backend); + dispatch_events, backend); wl_event_source_check(backend->remote_display_src); return true; diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 97b0dd8c..b798daf6 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -155,9 +155,14 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e static int x11_event(int fd, uint32_t mask, void *data) { struct wlr_x11_backend *x11 = data; + + if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) { + wl_display_terminate(x11->wl_display); + return 0; + } + xcb_generic_event_t *e; bool quit = false; - while (!quit && (e = xcb_poll_for_event(x11->xcb_conn))) { quit = handle_x11_event(x11, e); free(e); @@ -205,7 +210,8 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, int fd = xcb_get_file_descriptor(x11->xcb_conn); struct wl_event_loop *ev = wl_display_get_event_loop(display); - x11->event_source = wl_event_loop_add_fd(ev, fd, WL_EVENT_READABLE, x11_event, x11); + int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP; + x11->event_source = wl_event_loop_add_fd(ev, fd, events, x11_event, x11); if (!x11->event_source) { wlr_log(L_ERROR, "Could not create event source"); goto error_x11; -- cgit v1.2.3 From bb79ada49f43be5417bdd55fda3a7cf07c2a69df Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 10:30:54 +0100 Subject: Fix a bunch of mistakes detected with scan-build --- backend/libinput/events.c | 5 +++-- backend/session/session.c | 2 +- rootston/config.c | 2 +- rootston/cursor.c | 2 +- rootston/keyboard.c | 1 + rootston/seat.c | 1 - types/wlr_data_device.c | 5 ++++- types/wlr_keyboard.c | 5 ++++- types/wlr_screenshooter.c | 3 +++ types/wlr_wl_shell.c | 2 +- 10 files changed, 19 insertions(+), 9 deletions(-) diff --git a/backend/libinput/events.c b/backend/libinput/events.c index 5da45c67..3ca41124 100644 --- a/backend/libinput/events.c +++ b/backend/libinput/events.c @@ -66,10 +66,11 @@ static void handle_device_added(struct wlr_libinput_backend *backend, int product = libinput_device_get_id_product(libinput_dev); const char *name = libinput_device_get_name(libinput_dev); struct wl_list *wlr_devices = calloc(1, sizeof(struct wl_list)); - wl_list_init(wlr_devices); if (!wlr_devices) { - goto fail; + wlr_log(L_ERROR, "Allocation failed"); + return; } + wl_list_init(wlr_devices); wlr_log(L_DEBUG, "Added %s [%d:%d]", name, vendor, product); if (libinput_device_has_capability(libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) { diff --git a/backend/session/session.c b/backend/session/session.c index 760830c3..657558fd 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -249,7 +249,7 @@ static size_t explicit_find_gpus(struct wlr_session *session, } } while ((ptr = strtok_r(NULL, ":", &save))); - free(ptr); + free(gpus); return i; } diff --git a/rootston/config.c b/rootston/config.c index 7ffbb786..727b52d0 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -405,7 +405,7 @@ void roots_config_destroy(struct roots_config *config) { } struct roots_keyboard_config *kc, *ktmp = NULL; - wl_list_for_each_safe(kc, ktmp, &config->bindings, link) { + wl_list_for_each_safe(kc, ktmp, &config->keyboards, link) { free(kc->name); free(kc->rules); free(kc->model); diff --git a/rootston/cursor.c b/rootston/cursor.c index ecd5e9a0..5949a364 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -18,9 +18,9 @@ struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { } cursor->cursor = wlr_cursor_create(); if (!cursor->cursor) { + free(cursor); return NULL; } - return cursor; } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index c118e55c..fb648ae5 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -141,6 +141,7 @@ static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, uint32_t consumed = xkb_state_key_get_consumed_mods2( keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); + // TODO: actually use this value modifiers = modifiers & ~consumed; bool handled = false; diff --git a/rootston/seat.c b/rootston/seat.c index 6d8dc749..1fa37c44 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -252,7 +252,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) { seat->seat = wlr_seat_create(input->server->wl_display, name); if (!seat->seat) { free(seat); - roots_cursor_destroy(seat->cursor); return NULL; } diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index df18317b..4d926236 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -636,7 +636,10 @@ static void data_device_start_drag(struct wl_client *client, if (!seat_client_start_drag(seat_client, source, icon)) { wl_resource_post_no_memory(device_resource); - } else { + return; + } + + if (source) { source->seat_client = seat_client; } } diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 98ebeed5..c4f2ed52 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -105,7 +105,10 @@ void wlr_keyboard_init(struct wlr_keyboard *kb, } void wlr_keyboard_destroy(struct wlr_keyboard *kb) { - if (kb && kb->impl && kb->impl->destroy) { + if (kb == NULL) { + return; + } + if (kb->impl && kb->impl->destroy) { kb->impl->destroy(kb); } else { wl_list_remove(&kb->events.key.listener_list); diff --git a/types/wlr_screenshooter.c b/types/wlr_screenshooter.c index a78c7ad7..94b45384 100644 --- a/types/wlr_screenshooter.c +++ b/types/wlr_screenshooter.c @@ -85,6 +85,7 @@ static void screenshooter_shoot(struct wl_client *client, struct wlr_screenshot *screenshot = calloc(1, sizeof(struct wlr_screenshot)); if (!screenshot) { + free(pixels); wl_resource_post_no_memory(screenshooter_resource); return; } @@ -96,6 +97,7 @@ static void screenshooter_shoot(struct wl_client *client, wl_resource_get_version(screenshooter_resource), id); if (screenshot->resource == NULL) { free(screenshot); + free(pixels); wl_resource_post_no_memory(screenshooter_resource); return; } @@ -109,6 +111,7 @@ static void screenshooter_shoot(struct wl_client *client, if (!state) { wl_resource_destroy(screenshot->resource); free(screenshot); + free(pixels); wl_resource_post_no_memory(screenshooter_resource); return; } diff --git a/types/wlr_wl_shell.c b/types/wlr_wl_shell.c index 31032fef..abe967d7 100644 --- a/types/wlr_wl_shell.c +++ b/types/wlr_wl_shell.c @@ -347,7 +347,7 @@ static void shell_surface_protocol_set_popup(struct wl_client *client, transient_state->flags = flags; struct wlr_wl_shell_surface_popup_state *popup_state = - calloc(1, sizeof(struct wlr_wl_shell_surface_transient_state)); + calloc(1, sizeof(struct wlr_wl_shell_surface_popup_state)); if (popup_state == NULL) { free(transient_state); wl_client_post_no_memory(client); -- cgit v1.2.3 From 53d4cb47ffae0f8632ba7aea1687fdf75dd7deb8 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 16:13:23 +0100 Subject: Refactor rootston keyboard --- include/rootston/keyboard.h | 3 +- rootston/keyboard.c | 159 ++++++++++++++++++++++++-------------------- 2 files changed, 90 insertions(+), 72 deletions(-) diff --git a/include/rootston/keyboard.h b/include/rootston/keyboard.h index 15e7c9c4..39650d7c 100644 --- a/include/rootston/keyboard.h +++ b/include/rootston/keyboard.h @@ -16,7 +16,8 @@ struct roots_keyboard { struct wl_listener keyboard_key; struct wl_listener keyboard_modifiers; - xkb_keysym_t pressed_keysyms[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; + xkb_keysym_t pressed_keysyms_translated[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; + xkb_keysym_t pressed_keysyms_raw[ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP]; }; struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, diff --git a/rootston/keyboard.c b/rootston/keyboard.c index fb648ae5..566a1d7e 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -13,16 +13,35 @@ #include "rootston/seat.h" #include "rootston/keyboard.h" -static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard, +static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms, xkb_keysym_t keysym) { - for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; i++) { - if (keyboard->pressed_keysyms[i] == keysym) { + for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; ++i) { + if (pressed_keysyms[i] == keysym) { return i; } } return -1; } +static void pressed_keysyms_add(xkb_keysym_t *pressed_keysyms, + xkb_keysym_t keysym) { + ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); + if (i < 0) { + i = pressed_keysyms_index(pressed_keysyms, XKB_KEY_NoSymbol); + if (i >= 0) { + pressed_keysyms[i] = keysym; + } + } +} + +static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, + xkb_keysym_t keysym) { + ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); + if (i >= 0) { + pressed_keysyms[i] = XKB_KEY_NoSymbol; + } +} + static const char *exec_prefix = "exec "; static void keyboard_binding_execute(struct roots_keyboard *keyboard, @@ -56,21 +75,13 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } /** - * Process a keypress from the keyboard. + * Execute a built-in, hardcoded compositor action when a keysym is pressed. * * Returns true if the keysym was handled by a binding and false if the event * should be propagated to clients. */ -static bool keyboard_keysym_press(struct roots_keyboard *keyboard, +static bool keyboard_press_keysym(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { - ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); - if (i < 0) { - i = keyboard_pressed_keysym_index(keyboard, XKB_KEY_NoSymbol); - if (i >= 0) { - keyboard->pressed_keysyms[i] = keysym; - } - } - if (keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) { struct roots_server *server = keyboard->input->server; @@ -90,7 +101,35 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, wlr_seat_keyboard_end_grab(keyboard->seat->seat); } - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + return false; +} + +/** + * Press or release keysyms. + * + * Returns true if the keysym was handled by a binding and false if the event + * should be propagated to clients. + */ +static bool keyboard_handle_keysyms(struct roots_keyboard *keyboard, + xkb_keysym_t *pressed_keysyms, uint32_t modifiers, + const xkb_keysym_t *keysyms, size_t keysyms_len, + enum wlr_key_state state) { + bool handled = false; + for (size_t i = 0; i < keysyms_len; ++i) { + if (state == WLR_KEY_PRESSED) { + pressed_keysyms_add(pressed_keysyms, keysyms[i]); + handled |= keyboard_press_keysym(keyboard, keysyms[i]); + } else { // WLR_KEY_RELEASED + pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + } + } + if (handled) { + return true; + } + if (state != WLR_KEY_PRESSED) { + return false; + } + struct wl_list *bindings = &keyboard->input->server->config->bindings; struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { @@ -100,7 +139,7 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, bool ok = true; for (size_t i = 0; i < bc->keysyms_len; i++) { - ssize_t j = keyboard_pressed_keysym_index(keyboard, bc->keysyms[i]); + ssize_t j = pressed_keysyms_index(pressed_keysyms, bc->keysyms[i]); if (j < 0) { ok = false; break; @@ -116,86 +155,64 @@ static bool keyboard_keysym_press(struct roots_keyboard *keyboard, return false; } -static void keyboard_keysym_release(struct roots_keyboard *keyboard, - xkb_keysym_t keysym) { - ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym); - if (i >= 0) { - keyboard->pressed_keysyms[i] = XKB_KEY_NoSymbol; - } -} /* - * Process keypresses from the keyboard as xkb sees them. + * Get keysyms and modifiers from the keyboard as xkb sees them. * * This uses the xkb keysyms translation based on pressed modifiers and clears * the consumed modifiers from the list of modifiers passed to keybind * detection. * - * (On US layout) this will trigger: [Alt]+[at] + * On US layout, this will trigger: Alt + @ */ -static bool keyboard_keysyms_xkb(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) { - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - const xkb_keysym_t *syms; - int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, - keycode, &syms); - uint32_t consumed = xkb_state_key_get_consumed_mods2( +static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard, + xkb_keycode_t keycode, const xkb_keysym_t **keysyms, + uint32_t *modifiers) { + *modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods2( keyboard->device->keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_XKB); + *modifiers = *modifiers & ~consumed; - // TODO: actually use this value - modifiers = modifiers & ~consumed; - - bool handled = false; - for (int i = 0; i < syms_len; i++) { - if (state) { - bool keysym_handled = - keyboard_keysym_press(keyboard, syms[i]); - handled = handled || keysym_handled; - } else { // WLR_KEY_RELEASED - keyboard_keysym_release(keyboard, syms[i]); - } - } - - return handled; + return xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, + keycode, keysyms); } + /* - * Process keypresses from the keyboard as if modifiers didn't change keysyms. + * Get keysyms and modifiers from the keyboard as if modifiers didn't change + * keysyms. * * This avoids the xkb keysym translation based on modifiers considered pressed - * in the state and uses the list of modifiers saved on the rootston side. + * in the state. * - * This will trigger the keybind: [Alt]+[Shift]+2 + * This will trigger the keybind: Alt + Shift + 2 */ -static bool keyboard_keysyms_simple(struct roots_keyboard *keyboard, - uint32_t keycode, enum wlr_key_state state) { - const xkb_keysym_t *syms; +static size_t keyboard_keysyms_raw(struct roots_keyboard *keyboard, + xkb_keycode_t keycode, const xkb_keysym_t **keysyms, + uint32_t *modifiers) { + *modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + xkb_layout_index_t layout_index = xkb_state_key_get_layout( keyboard->device->keyboard->xkb_state, keycode); - int syms_len = xkb_keymap_key_get_syms_by_level( - keyboard->device->keyboard->keymap, keycode, layout_index, 0, &syms); - - bool handled = false; - for (int i = 0; i < syms_len; i++) { - if (state) { - bool keysym_handled = keyboard_keysym_press(keyboard, syms[i]); - handled = handled || keysym_handled; - } else { // WLR_KEY_RELEASED - keyboard_keysym_release(keyboard, syms[i]); - } - } - - return handled; + return xkb_keymap_key_get_syms_by_level(keyboard->device->keyboard->keymap, + keycode, layout_index, 0, keysyms); } void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event) { - uint32_t keycode = event->keycode + 8; - - bool handled = keyboard_keysyms_xkb(keyboard, keycode, event->state); + xkb_keycode_t keycode = event->keycode + 8; + uint32_t modifiers; + const xkb_keysym_t *keysyms; + size_t keysyms_len = keyboard_keysyms_translated(keyboard, keycode, + &keysyms, &modifiers); + bool handled = keyboard_handle_keysyms(keyboard, + keyboard->pressed_keysyms_translated, modifiers, keysyms, keysyms_len, + event->state); if (!handled) { - bool key_handled = keyboard_keysyms_simple(keyboard, keycode, + keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, + &modifiers); + handled = keyboard_handle_keysyms(keyboard, + keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len, event->state); - handled = handled || key_handled; } if (!handled) { -- cgit v1.2.3 From e674266b44a5a8991e697ea43d5a0c8b461f76bf Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 16:34:39 +0100 Subject: Fix example config file --- rootston/rootston.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example index 433dc78f..c33b0f04 100644 --- a/rootston/rootston.ini.example +++ b/rootston/rootston.ini.example @@ -40,6 +40,6 @@ meta-key = Logo # - "close" to close the current view # - "next_window" to cycle through windows [bindings] -Logo+Shift+E = exit +Logo+Shift+e = exit Logo+q = close Alt+Tab = next_window -- cgit v1.2.3 From a52ca9482a7583bee22c8435b96a6141d44939f4 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 16 Nov 2017 18:58:33 +0100 Subject: Various keyboard fixes * Ensure keysyms state is always updated * Check if pressed keysyms are exactly the binding keysyms * Do not include modifiers in list of keysyms, these are special cases --- rootston/keyboard.c | 107 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 31 deletions(-) diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 566a1d7e..39f46a32 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -23,6 +23,16 @@ static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms, return -1; } +static size_t pressed_keysyms_length(xkb_keysym_t *pressed_keysyms) { + size_t n = 0; + for (size_t i = 0; i < ROOTS_KEYBOARD_PRESSED_KEYSYMS_CAP; ++i) { + if (pressed_keysyms[i] != XKB_KEY_NoSymbol) { + ++n; + } + } + return n; +} + static void pressed_keysyms_add(xkb_keysym_t *pressed_keysyms, xkb_keysym_t keysym) { ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); @@ -42,6 +52,37 @@ static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, } } +static bool keysym_is_modifier(xkb_keysym_t keysym) { + switch (keysym) { + case XKB_KEY_Shift_L: case XKB_KEY_Shift_R: + case XKB_KEY_Control_L: case XKB_KEY_Control_R: + case XKB_KEY_Caps_Lock: + case XKB_KEY_Shift_Lock: + case XKB_KEY_Meta_L: case XKB_KEY_Meta_R: + case XKB_KEY_Alt_L: case XKB_KEY_Alt_R: + case XKB_KEY_Super_L: case XKB_KEY_Super_R: + case XKB_KEY_Hyper_L: case XKB_KEY_Hyper_R: + return true; + default: + return false; + } +} + +static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms, + const xkb_keysym_t *keysyms, size_t keysyms_len, + enum wlr_key_state state) { + for (size_t i = 0; i < keysyms_len; ++i) { + if (keysym_is_modifier(keysyms[i])) { + continue; + } + if (state == WLR_KEY_PRESSED) { + pressed_keysyms_add(pressed_keysyms, keysyms[i]); + } else { // WLR_KEY_RELEASED + pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + } + } +} + static const char *exec_prefix = "exec "; static void keyboard_binding_execute(struct roots_keyboard *keyboard, @@ -75,12 +116,13 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard, } /** - * Execute a built-in, hardcoded compositor action when a keysym is pressed. + * Execute a built-in, hardcoded compositor binding. These are triggered from a + * single keysym. * * Returns true if the keysym was handled by a binding and false if the event * should be propagated to clients. */ -static bool keyboard_press_keysym(struct roots_keyboard *keyboard, +static bool keyboard_execute_compositor_binding(struct roots_keyboard *keyboard, xkb_keysym_t keysym) { if (keysym >= XKB_KEY_XF86Switch_VT_1 && keysym <= XKB_KEY_XF86Switch_VT_12) { @@ -105,35 +147,27 @@ static bool keyboard_press_keysym(struct roots_keyboard *keyboard, } /** - * Press or release keysyms. + * Execute keyboard bindings. These include compositor bindings and user-defined + * bindings. * * Returns true if the keysym was handled by a binding and false if the event * should be propagated to clients. */ -static bool keyboard_handle_keysyms(struct roots_keyboard *keyboard, +static bool keyboard_execute_binding(struct roots_keyboard *keyboard, xkb_keysym_t *pressed_keysyms, uint32_t modifiers, - const xkb_keysym_t *keysyms, size_t keysyms_len, - enum wlr_key_state state) { - bool handled = false; + const xkb_keysym_t *keysyms, size_t keysyms_len) { for (size_t i = 0; i < keysyms_len; ++i) { - if (state == WLR_KEY_PRESSED) { - pressed_keysyms_add(pressed_keysyms, keysyms[i]); - handled |= keyboard_press_keysym(keyboard, keysyms[i]); - } else { // WLR_KEY_RELEASED - pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + if (keyboard_execute_compositor_binding(keyboard, keysyms[i])) { + return true; } } - if (handled) { - return true; - } - if (state != WLR_KEY_PRESSED) { - return false; - } + // User-defined bindings + size_t n = pressed_keysyms_length(pressed_keysyms); struct wl_list *bindings = &keyboard->input->server->config->bindings; struct roots_binding_config *bc; wl_list_for_each(bc, bindings, link) { - if (modifiers ^ bc->modifiers) { + if (modifiers ^ bc->modifiers || n != bc->keysyms_len) { continue; } @@ -162,7 +196,7 @@ static bool keyboard_handle_keysyms(struct roots_keyboard *keyboard, * the consumed modifiers from the list of modifiers passed to keybind * detection. * - * On US layout, this will trigger: Alt + @ + * On US layout, pressing Alt+Shift+2 will trigger Alt+@. */ static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard, xkb_keycode_t keycode, const xkb_keysym_t **keysyms, @@ -183,7 +217,7 @@ static size_t keyboard_keysyms_translated(struct roots_keyboard *keyboard, * This avoids the xkb keysym translation based on modifiers considered pressed * in the state. * - * This will trigger the keybind: Alt + Shift + 2 + * This will trigger keybinds such as Alt+Shift+2. */ static size_t keyboard_keysyms_raw(struct roots_keyboard *keyboard, xkb_keycode_t keycode, const xkb_keysym_t **keysyms, @@ -200,19 +234,30 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard, struct wlr_event_keyboard_key *event) { xkb_keycode_t keycode = event->keycode + 8; + bool handled = false; uint32_t modifiers; const xkb_keysym_t *keysyms; - size_t keysyms_len = keyboard_keysyms_translated(keyboard, keycode, - &keysyms, &modifiers); - bool handled = keyboard_handle_keysyms(keyboard, - keyboard->pressed_keysyms_translated, modifiers, keysyms, keysyms_len, + size_t keysyms_len; + + // Handle translated keysyms + + keysyms_len = keyboard_keysyms_translated(keyboard, keycode, &keysyms, + &modifiers); + pressed_keysyms_update(keyboard->pressed_keysyms_translated, keysyms, + keysyms_len, event->state); + if (event->state == WLR_KEY_PRESSED) { + handled = keyboard_execute_binding(keyboard, + keyboard->pressed_keysyms_translated, modifiers, keysyms, + keysyms_len); + } + + // Handle raw keysyms + keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, &modifiers); + pressed_keysyms_update(keyboard->pressed_keysyms_raw, keysyms, keysyms_len, event->state); - if (!handled) { - keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &keysyms, - &modifiers); - handled = keyboard_handle_keysyms(keyboard, - keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len, - event->state); + if (event->state == WLR_KEY_PRESSED && !handled) { + handled = keyboard_execute_binding(keyboard, + keyboard->pressed_keysyms_raw, modifiers, keysyms, keysyms_len); } if (!handled) { -- cgit v1.2.3 From a446f735aea6f294bc75a1675f191521d45ed2d0 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 16 Nov 2017 15:39:48 -0500 Subject: readme: add basic running doc --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 0f221e3c..721265ae 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,25 @@ Run these commands: ninja -C build (On FreeBSD, you need to pass an extra flag to prevent a linking error: `meson build -D b_lundef=false`) + +## Running the Reference Compositor + +wlroots comes with a reference compositor called rootston that demonstrates the +features of the library. + +After building, run rootston from a terminal or VT with: + + ./build/rootston/rootston + +Run windows on the compositor with the display variable set: + +```bash +# run gtk apps like this +gnome-calculator --display=wayland-0 + +# run QT apps like this +qgit -platform wayland + +# run X11 apps like this +DISPLAY=:1 firefox +``` -- cgit v1.2.3 From 2bbea060937dd8ab99be2a4878c837298343f02a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 16 Nov 2017 15:59:12 -0500 Subject: readme: change running instructions --- README.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 721265ae..06ef8dcb 100644 --- a/README.md +++ b/README.md @@ -43,15 +43,7 @@ After building, run rootston from a terminal or VT with: ./build/rootston/rootston -Run windows on the compositor with the display variable set: - -```bash -# run gtk apps like this -gnome-calculator --display=wayland-0 - -# run QT apps like this -qgit -platform wayland - -# run X11 apps like this -DISPLAY=:1 firefox -``` +Now you can run windows in the compositor from the command line or by +configuring bindings in your +[`rootston.ini`](https://github.com/swaywm/wlroots/blob/master/rootston/rootston.ini.example) +file. -- cgit v1.2.3 From 632759a49988e545ae9aff636c2095f295492293 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 17 Nov 2017 15:28:22 +0100 Subject: Fix segfault when xwayland is disabled --- rootston/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rootston/main.c b/rootston/main.c index 365ff6e0..814d3aef 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -58,8 +58,12 @@ int main(int argc, char **argv) { #ifndef HAS_XWAYLAND ready(NULL, NULL); #else - struct wl_listener xwayland_ready = { .notify = ready }; - wl_signal_add(&server.desktop->xwayland->events.ready, &xwayland_ready); + if (server.desktop->xwayland != NULL) { + struct wl_listener xwayland_ready = { .notify = ready }; + wl_signal_add(&server.desktop->xwayland->events.ready, &xwayland_ready); + } else { + ready(NULL, NULL); + } #endif wl_display_run(server.wl_display); -- cgit v1.2.3