From d74ac69f7b932a8833527a41351e3310ad391d7c Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Thu, 7 Dec 2017 11:19:43 -0500 Subject: bring edges into wlr --- include/rootston/cursor.h | 7 ------- include/rootston/xcursor.h | 2 -- 2 files changed, 9 deletions(-) (limited to 'include/rootston') diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index e2a371bf..2d9a9215 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -10,13 +10,6 @@ enum roots_cursor_mode { 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; diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h index bc00f79c..285db78d 100644 --- a/include/rootston/xcursor.h +++ b/include/rootston/xcursor.h @@ -9,6 +9,4 @@ #define ROOTS_XCURSOR_MOVE "grabbing" #define ROOTS_XCURSOR_ROTATE "grabbing" -const char *roots_xcursor_get_resize_name(uint32_t edges); - #endif -- cgit v1.2.3 From c5fa415a0373e0fbd974d4a8aee94014050b93f2 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 8 Dec 2017 14:23:33 +0100 Subject: Send wl_surface.{enter,leave} to cursor surfaces --- include/rootston/xcursor.h | 2 +- include/wlr/types/wlr_output.h | 4 +++ types/wlr_output.c | 75 +++++++++++++++++++++++++++++------------- 3 files changed, 58 insertions(+), 23 deletions(-) (limited to 'include/rootston') diff --git a/include/rootston/xcursor.h b/include/rootston/xcursor.h index 285db78d..a7d2b960 100644 --- a/include/rootston/xcursor.h +++ b/include/rootston/xcursor.h @@ -3,7 +3,7 @@ #include -#define ROOTS_XCURSOR_SIZE 16 +#define ROOTS_XCURSOR_SIZE 24 #define ROOTS_XCURSOR_DEFAULT "left_ptr" #define ROOTS_XCURSOR_MOVE "grabbing" diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 42c46233..895536e1 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -16,6 +16,7 @@ struct wlr_output_cursor { struct wlr_output *output; double x, y; bool enabled; + bool visible; uint32_t width, height; int32_t hotspot_x, hotspot_y; struct wl_list link; @@ -98,6 +99,9 @@ void wlr_output_set_fullscreen_surface(struct wlr_output *output, struct wlr_surface *surface); struct wlr_output_cursor *wlr_output_cursor_create(struct wlr_output *output); +/** + * Sets the cursor image. The image must be already scaled for the output. + */ 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); diff --git a/types/wlr_output.c b/types/wlr_output.c index ed74004d..3141e9ef 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -316,6 +316,11 @@ static void output_cursor_get_box(struct wlr_output_cursor *cursor, box->y = cursor->y - cursor->hotspot_y; box->width = cursor->width; box->height = cursor->height; + + if (cursor->surface != NULL) { + box->x += cursor->surface->current->sx; + box->y += cursor->surface->current->sy; + } } static void output_cursor_render(struct wlr_output_cursor *cursor, @@ -331,36 +336,29 @@ static void output_cursor_render(struct wlr_output_cursor *cursor, return; } - struct wlr_box output_box; - 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; + glViewport(0, 0, cursor->output->width, cursor->output->height); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 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 translate[16]; + wlr_matrix_translate(&translate, cursor_box.x, cursor_box.y, 0); - int x = cursor->x - cursor->hotspot_x; - int y = cursor->y - cursor->hotspot_y; + // Assume cursors without a surface are already scaled for the output if (cursor->surface != NULL) { - x += cursor->surface->current->sx; - y += cursor->surface->current->sy; + cursor_box.width *= cursor->output->scale; + cursor_box.height *= cursor->output->scale; } + float scale[16]; + wlr_matrix_scale(&scale, cursor_box.width, cursor_box.height, 1); + float matrix[16]; - wlr_texture_get_matrix(texture, &matrix, &cursor->output->transform_matrix, - x, y); + wlr_matrix_mul(&translate, &scale, &matrix); + wlr_matrix_mul(&cursor->output->transform_matrix, &matrix, &matrix); + wlr_render_with_matrix(renderer, texture, &matrix); if (cursor->surface != NULL) { @@ -381,7 +379,8 @@ void wlr_output_swap_buffers(struct wlr_output *output) { struct wlr_output_cursor *cursor; wl_list_for_each(cursor, &output->cursors, link) { - if (!cursor->enabled || output->hardware_cursor == cursor) { + if (!cursor->enabled || !cursor->visible || + output->hardware_cursor == cursor) { continue; } output_cursor_render(cursor, &now); @@ -516,6 +515,34 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, stride, width, height, pixels); } +static void output_cursor_update_visible(struct wlr_output_cursor *cursor) { + struct wlr_box output_box; + 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); + + struct wlr_box intersection; + struct wlr_box *intersection_ptr = &intersection; + bool visible = + wlr_box_intersection(&output_box, &cursor_box, &intersection_ptr); + + if (cursor->surface != NULL) { + if (cursor->visible && !visible) { + wlr_surface_send_leave(cursor->surface, cursor->output); + } + if (!cursor->visible && visible) { + wlr_surface_send_enter(cursor->surface, cursor->output); + } + } + + cursor->visible = visible; +} + static void output_cursor_commit(struct wlr_output_cursor *cursor) { // Some clients commit a cursor surface with a NULL buffer to hide it. cursor->enabled = wlr_surface_has_buffer(cursor->surface); @@ -584,6 +611,9 @@ void wlr_output_cursor_set_surface(struct wlr_output_cursor *cursor, wl_signal_add(&surface->events.commit, &cursor->surface_commit); wl_signal_add(&surface->events.destroy, &cursor->surface_destroy); output_cursor_commit(cursor); + + cursor->visible = false; + output_cursor_update_visible(cursor); } else { cursor->enabled = false; cursor->width = 0; @@ -599,6 +629,7 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, y *= cursor->output->scale; cursor->x = x; cursor->y = y; + output_cursor_update_visible(cursor); if (cursor->output->hardware_cursor != cursor) { cursor->output->needs_swap = true; -- cgit v1.2.3 From a3c0f9781073a29c020d8f5c992b8019264dc219 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 8 Dec 2017 17:03:05 +0100 Subject: Make keyboard repeat info configurable --- include/rootston/config.h | 1 + include/wlr/types/wlr_keyboard.h | 8 ++++++++ include/wlr/types/wlr_seat.h | 1 + rootston/config.c | 4 ++++ rootston/keyboard.c | 13 +++++++++++-- types/wlr_keyboard.c | 15 +++++++++++++++ types/wlr_seat.c | 33 +++++++++++++++++++++++++++++---- 7 files changed, 69 insertions(+), 6 deletions(-) (limited to 'include/rootston') diff --git a/include/rootston/config.h b/include/rootston/config.h index de20fb8e..233692dc 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -42,6 +42,7 @@ struct roots_keyboard_config { char *layout; char *variant; char *options; + int repeat_rate, repeat_delay; struct wl_list link; }; diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index e2d50b03..c259189d 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -51,10 +51,16 @@ struct wlr_keyboard { xkb_mod_mask_t group; } modifiers; + struct { + int32_t rate; + int32_t delay; + } repeat_info; + struct { struct wl_signal key; struct wl_signal modifiers; struct wl_signal keymap; + struct wl_signal repeat_info; } events; void *data; @@ -74,6 +80,8 @@ struct wlr_event_keyboard_key { void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, struct xkb_keymap *keymap); +void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate, + int32_t delay); void wlr_keyboard_led_update(struct wlr_keyboard *keyboard, uint32_t leds); uint32_t wlr_keyboard_get_modifiers(struct wlr_keyboard *keyboard); diff --git a/include/wlr/types/wlr_seat.h b/include/wlr/types/wlr_seat.h index 6d59315b..6c04380e 100644 --- a/include/wlr/types/wlr_seat.h +++ b/include/wlr/types/wlr_seat.h @@ -146,6 +146,7 @@ struct wlr_seat_keyboard_state { struct wl_listener keyboard_destroy; struct wl_listener keyboard_keymap; + struct wl_listener keyboard_repeat_info; struct wl_listener surface_destroy; struct wl_listener resource_destroy; diff --git a/rootston/config.c b/rootston/config.c index 59adf13c..6e596852 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -213,6 +213,10 @@ static void config_handle_keyboard(struct roots_config *config, kc->variant = strdup(value); } else if (strcmp(name, "options") == 0) { kc->options = strdup(value); + } else if (strcmp(name, "repeat-rate") == 0) { + kc->repeat_rate = strtol(value, NULL, 10); + } else if (strcmp(name, "repeat-delay") == 0) { + kc->repeat_delay = strtol(value, NULL, 10); } else { wlr_log(L_ERROR, "got unknown keyboard config: %s", name); } diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 85033613..4aaf2d48 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -306,6 +306,12 @@ static void keyboard_config_merge(struct roots_keyboard_config *config, if (config->name == NULL) { config->name = fallback->name; } + if (config->repeat_rate <= 0) { + config->repeat_rate = fallback->repeat_rate; + } + if (config->repeat_delay <= 0) { + config->repeat_delay = fallback->repeat_delay; + } } struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, @@ -337,8 +343,7 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, keyboard_config_merge(config, &env_config); keyboard->config = config; - struct xkb_rule_names rules; - memset(&rules, 0, sizeof(rules)); + struct xkb_rule_names rules = { 0 }; rules.rules = config->rules; rules.model = config->model; rules.layout = config->layout; @@ -353,6 +358,10 @@ struct roots_keyboard *roots_keyboard_create(struct wlr_input_device *device, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); xkb_context_unref(context); + int repeat_rate = (config->repeat_rate > 0) ? config->repeat_rate : 25; + int repeat_delay = (config->repeat_delay > 0) ? config->repeat_delay : 600; + wlr_keyboard_set_repeat_info(device->keyboard, repeat_rate, repeat_delay); + return keyboard; } diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index c4f2ed52..c494b45d 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -102,6 +102,11 @@ void wlr_keyboard_init(struct wlr_keyboard *kb, wl_signal_init(&kb->events.key); wl_signal_init(&kb->events.modifiers); wl_signal_init(&kb->events.keymap); + wl_signal_init(&kb->events.repeat_info); + + // Sane defaults + kb->repeat_info.rate = 25; + kb->repeat_info.delay = 600; } void wlr_keyboard_destroy(struct wlr_keyboard *kb) { @@ -167,6 +172,16 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, wl_signal_emit(&kb->events.keymap, kb); } +void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate, + int32_t delay) { + if (kb->repeat_info.rate == rate && kb->repeat_info.delay == delay) { + return; + } + kb->repeat_info.rate = rate; + kb->repeat_info.delay = delay; + wl_signal_emit(&kb->events.repeat_info, kb); +} + uint32_t wlr_keyboard_get_modifiers(struct wlr_keyboard *kb) { xkb_mod_mask_t mask = kb->modifiers.depressed | kb->modifiers.latched; uint32_t modifiers = 0; diff --git a/types/wlr_seat.c b/types/wlr_seat.c index ff1cbf7f..ab3e990d 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -109,10 +109,18 @@ static void seat_client_send_keymap(struct wlr_seat_client *client, wl_keyboard_send_keymap(client->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keyboard->keymap_fd, keyboard->keymap_size); +} + +static void seat_client_send_repeat_info(struct wlr_seat_client *client, + struct wlr_keyboard *keyboard) { + if (!keyboard || !client->keyboard) { + return; + } if (wl_resource_get_version(client->keyboard) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { - wl_keyboard_send_repeat_info(client->keyboard, 25, 600); + wl_keyboard_send_repeat_info(client->keyboard, + keyboard->repeat_info.rate, keyboard->repeat_info.delay); } } @@ -138,8 +146,9 @@ static void wl_seat_get_keyboard(struct wl_client *client, wl_resource_set_implementation(seat_client->keyboard, &wl_keyboard_impl, seat_client, &wl_keyboard_destroy); - seat_client_send_keymap(seat_client, - seat_client->seat->keyboard_state.keyboard); + struct wlr_keyboard *keyboard = seat_client->seat->keyboard_state.keyboard; + seat_client_send_keymap(seat_client, keyboard); + seat_client_send_repeat_info(seat_client, keyboard); // TODO possibly handle the case where this keyboard needs an enter // right away @@ -695,6 +704,16 @@ static void handle_keyboard_keymap(struct wl_listener *listener, void *data) { } } +static void handle_keyboard_repeat_info(struct wl_listener *listener, + void *data) { + struct wlr_seat_keyboard_state *state = + wl_container_of(listener, state, keyboard_repeat_info); + struct wlr_seat_client *client; + wl_list_for_each(client, &state->seat->clients, link) { + seat_client_send_repeat_info(client, state->keyboard); + } +} + static void handle_keyboard_destroy(struct wl_listener *listener, void *data) { struct wlr_seat_keyboard_state *state = wl_container_of(listener, state, keyboard_destroy); @@ -713,22 +732,28 @@ void wlr_seat_set_keyboard(struct wlr_seat *seat, if (seat->keyboard_state.keyboard) { wl_list_remove(&seat->keyboard_state.keyboard_destroy.link); wl_list_remove(&seat->keyboard_state.keyboard_keymap.link); + wl_list_remove(&seat->keyboard_state.keyboard_repeat_info.link); seat->keyboard_state.keyboard = NULL; } if (device) { assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); + wl_signal_add(&device->events.destroy, &seat->keyboard_state.keyboard_destroy); seat->keyboard_state.keyboard_destroy.notify = handle_keyboard_destroy; - wl_signal_add(&device->keyboard->events.keymap, &seat->keyboard_state.keyboard_keymap); seat->keyboard_state.keyboard_keymap.notify = handle_keyboard_keymap; + wl_signal_add(&device->keyboard->events.repeat_info, + &seat->keyboard_state.keyboard_repeat_info); + seat->keyboard_state.keyboard_repeat_info.notify = + handle_keyboard_repeat_info; struct wlr_seat_client *client; wl_list_for_each(client, &seat->clients, link) { seat_client_send_keymap(client, device->keyboard); + seat_client_send_repeat_info(client, device->keyboard); } seat->keyboard_state.keyboard = device->keyboard; -- cgit v1.2.3 From 925497fbeaed9a2eb8420490e6cdfa4fd162e79e Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 11 Dec 2017 10:36:22 +0100 Subject: Set default cursor image in rootston --- include/rootston/config.h | 1 + include/rootston/cursor.h | 2 ++ rootston/config.c | 4 ++++ rootston/cursor.c | 3 ++- rootston/desktop.c | 6 +++++- rootston/seat.c | 5 ++++- 6 files changed, 18 insertions(+), 3 deletions(-) (limited to 'include/rootston') diff --git a/include/rootston/config.h b/include/rootston/config.h index 233692dc..1d54314e 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -51,6 +51,7 @@ struct roots_cursor_config { char *mapped_output; struct wlr_box *mapped_box; char *theme; + char *default_image; struct wl_list link; }; diff --git a/include/rootston/cursor.h b/include/rootston/cursor.h index 2d9a9215..de6b7b92 100644 --- a/include/rootston/cursor.h +++ b/include/rootston/cursor.h @@ -20,6 +20,8 @@ struct roots_cursor { struct roots_seat *seat; struct wlr_cursor *cursor; + const char *default_xcursor; + enum roots_cursor_mode mode; // state from input (review if this is necessary) diff --git a/rootston/config.c b/rootston/config.c index 6e596852..db77506f 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -176,6 +176,9 @@ static void config_handle_cursor(struct roots_config *config, } else if (strcmp(name, "theme") == 0) { free(cc->theme); cc->theme = strdup(value); + } else if (strcmp(name, "default-image") == 0) { + free(cc->default_image); + cc->default_image = strdup(value); } else { wlr_log(L_ERROR, "got unknown cursor config: %s", name); } @@ -454,6 +457,7 @@ void roots_config_destroy(struct roots_config *config) { free(cc->mapped_output); free(cc->mapped_box); free(cc->theme); + free(cc->default_image); free(cc); } diff --git a/rootston/cursor.c b/rootston/cursor.c index d38e40a1..95e8ce2a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -22,6 +22,7 @@ struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { free(cursor); return NULL; } + cursor->default_xcursor = ROOTS_XCURSOR_DEFAULT; return cursor; } @@ -48,7 +49,7 @@ static void roots_cursor_update_position(struct roots_cursor *cursor, } if (set_compositor_cursor) { wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - ROOTS_XCURSOR_DEFAULT, cursor->cursor); + cursor->default_xcursor, cursor->cursor); cursor->cursor_client = NULL; } if (view) { diff --git a/rootston/desktop.c b/rootston/desktop.c index 244f7c94..ef459e69 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -408,10 +408,14 @@ struct roots_desktop *desktop_create(struct roots_server *server, desktop->config = config; const char *cursor_theme = NULL; + const char *cursor_default = ROOTS_XCURSOR_DEFAULT; struct roots_cursor_config *cc = roots_config_get_cursor(config, ROOTS_CONFIG_DEFAULT_SEAT_NAME); if (cc != NULL) { cursor_theme = cc->theme; + if (cc->default_image != NULL) { + cursor_default = cc->default_image; + } } desktop->xcursor_manager = wlr_xcursor_manager_create(cursor_theme, @@ -449,7 +453,7 @@ struct roots_desktop *desktop_create(struct roots_server *server, 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); + desktop->xcursor_manager, cursor_default, 1); if (xcursor != NULL) { struct wlr_xcursor_image *image = xcursor->images[0]; wlr_xwayland_set_cursor(desktop->xwayland, image->buffer, diff --git a/rootston/seat.c b/rootston/seat.c index cb245ca8..8a581157 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -442,6 +442,9 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { roots_config_get_cursor(seat->input->config, seat->seat->name); if (cc != NULL) { cursor_theme = cc->theme; + if (cc->default_image != NULL) { + seat->cursor->default_xcursor = cc->default_image; + } } if (!seat->cursor->xcursor_manager) { @@ -465,7 +468,7 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { } wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, - ROOTS_XCURSOR_DEFAULT, seat->cursor->cursor); + seat->cursor->default_xcursor, seat->cursor->cursor); wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, seat->cursor->cursor->y); } -- cgit v1.2.3