Merge remote-tracking branch 'upstream/master' into output-damage

This commit is contained in:
emersion 2018-01-21 22:16:55 +01:00
commit 59c53e8333
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
16 changed files with 220 additions and 92 deletions

View file

@ -194,6 +194,9 @@ static bool wlr_drm_connector_swap_buffers(struct wlr_output *output) {
struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_crtc *crtc = conn->crtc;
if (!crtc) {
return false;
}
struct wlr_drm_plane *plane = crtc->primary; struct wlr_drm_plane *plane = crtc->primary;
struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&plane->surf); struct gbm_bo *bo = wlr_drm_surface_swap_buffers(&plane->surf);
@ -237,6 +240,9 @@ void wlr_drm_connector_start_renderer(struct wlr_drm_connector *conn) {
struct wlr_drm_backend *drm = (struct wlr_drm_backend *)conn->output.backend; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)conn->output.backend;
struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_crtc *crtc = conn->crtc;
if (!crtc) {
return;
}
struct wlr_drm_plane *plane = crtc->primary; struct wlr_drm_plane *plane = crtc->primary;
struct gbm_bo *bo = wlr_drm_surface_get_front( struct gbm_bo *bo = wlr_drm_surface_get_front(
@ -457,6 +463,9 @@ static bool wlr_drm_connector_set_mode(struct wlr_output *output,
} }
struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_crtc *crtc = conn->crtc;
if (!crtc) {
return false;
}
wlr_log(L_DEBUG, "%s: crtc=%ju ovr=%jd pri=%jd cur=%jd", conn->output.name, wlr_log(L_DEBUG, "%s: crtc=%ju ovr=%jd pri=%jd cur=%jd", conn->output.name,
crtc - drm->crtcs, crtc - drm->crtcs,
crtc->overlay ? crtc->overlay - drm->overlay_planes : -1, crtc->overlay ? crtc->overlay - drm->overlay_planes : -1,
@ -508,6 +517,9 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,
struct wlr_drm_renderer *renderer = &drm->renderer; struct wlr_drm_renderer *renderer = &drm->renderer;
struct wlr_drm_crtc *crtc = conn->crtc; struct wlr_drm_crtc *crtc = conn->crtc;
if (!crtc) {
return false;
}
struct wlr_drm_plane *plane = crtc->cursor; struct wlr_drm_plane *plane = crtc->cursor;
// We don't have a real cursor plane, so we make a fake one // We don't have a real cursor plane, so we make a fake one
@ -633,6 +645,9 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output,
int x, int y) { int x, int y) {
struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
if (!conn->crtc) {
return false;
}
struct wlr_drm_plane *plane = conn->crtc->cursor; struct wlr_drm_plane *plane = conn->crtc->cursor;
struct wlr_box box; struct wlr_box box;

View file

@ -330,7 +330,9 @@ static bool add_signal_matches(struct logind_session *session) {
static int dbus_event(int fd, uint32_t mask, void *data) { static int dbus_event(int fd, uint32_t mask, void *data) {
sd_bus *bus = data; sd_bus *bus = data;
while (sd_bus_process(bus, NULL) > 0); while (sd_bus_process(bus, NULL) > 0) {
// Do nothing.
}
return 1; return 1;
} }

View file

@ -307,8 +307,9 @@ size_t wlr_session_find_gpus(struct wlr_session *session,
} }
const char *seat = udev_device_get_property_value(dev, "ID_SEAT"); const char *seat = udev_device_get_property_value(dev, "ID_SEAT");
if (!seat) if (!seat) {
seat = "seat0"; seat = "seat0";
}
if (session->seat[0] && strcmp(session->seat, seat) != 0) { if (session->seat[0] && strcmp(session->seat, seat) != 0) {
udev_device_unref(dev); udev_device_unref(dev);
continue; continue;

View file

@ -85,12 +85,24 @@ static void wlr_wl_backend_destroy(struct wlr_backend *_backend) {
wl_event_source_remove(backend->remote_display_src); wl_event_source_remove(backend->remote_display_src);
wlr_egl_finish(&backend->egl); wlr_egl_finish(&backend->egl);
if (backend->seat) wl_seat_destroy(backend->seat); if (backend->seat) {
if (backend->shm) wl_shm_destroy(backend->shm); wl_seat_destroy(backend->seat);
if (backend->shell) zxdg_shell_v6_destroy(backend->shell); }
if (backend->compositor) wl_compositor_destroy(backend->compositor); if (backend->shm) {
if (backend->registry) wl_registry_destroy(backend->registry); wl_shm_destroy(backend->shm);
if (backend->remote_display) wl_display_disconnect(backend->remote_display); }
if (backend->shell) {
zxdg_shell_v6_destroy(backend->shell);
}
if (backend->compositor) {
wl_compositor_destroy(backend->compositor);
}
if (backend->registry) {
wl_registry_destroy(backend->registry);
}
if (backend->remote_display) {
wl_display_disconnect(backend->remote_display);
}
free(backend); free(backend);
} }

View file

@ -64,8 +64,12 @@ static void handle_output_frame(struct output_state *output, struct timespec *ts
odata->x_offs += odata->x_vel * seconds; odata->x_offs += odata->x_vel * seconds;
odata->y_offs += odata->y_vel * seconds; odata->y_offs += odata->y_vel * seconds;
if (odata->x_offs > 128) odata->x_offs = 0; if (odata->x_offs > 128) {
if (odata->y_offs > 128) odata->y_offs = 0; odata->x_offs = 0;
}
if (odata->y_offs > 128) {
odata->y_offs = 0;
}
} }
static void handle_output_add(struct output_state *output) { static void handle_output_add(struct output_state *output) {

View file

@ -277,9 +277,10 @@ int main(int argc, char *argv[]) {
screenshooter, output->output, output->buffer); screenshooter, output->output, output->buffer);
orbital_screenshot_add_listener(screenshot, &screenshot_listener, screenshot); orbital_screenshot_add_listener(screenshot, &screenshot_listener, screenshot);
buffer_copy_done = 0; buffer_copy_done = 0;
while (!buffer_copy_done) while (!buffer_copy_done) {
wl_display_roundtrip(display); wl_display_roundtrip(display);
} }
}
write_image("wayland-screenshot.png", width, height); write_image("wayland-screenshot.png", width, height);
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -32,6 +32,13 @@ enum wlr_keyboard_modifier {
struct wlr_keyboard_impl; struct wlr_keyboard_impl;
struct wlr_keyboard_modifiers {
xkb_mod_mask_t depressed;
xkb_mod_mask_t latched;
xkb_mod_mask_t locked;
xkb_mod_mask_t group;
};
struct wlr_keyboard { struct wlr_keyboard {
struct wlr_keyboard_impl *impl; struct wlr_keyboard_impl *impl;
// TODO: Should this store key repeat info too? // TODO: Should this store key repeat info too?
@ -45,12 +52,7 @@ struct wlr_keyboard {
uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP]; uint32_t keycodes[WLR_KEYBOARD_KEYS_CAP];
size_t num_keycodes; size_t num_keycodes;
struct { struct wlr_keyboard_modifiers modifiers;
xkb_mod_mask_t depressed;
xkb_mod_mask_t latched;
xkb_mod_mask_t locked;
xkb_mod_mask_t group;
} modifiers;
struct { struct {
int32_t rate; int32_t rate;

View file

@ -68,10 +68,12 @@ struct wlr_seat_keyboard_grab;
struct wlr_keyboard_grab_interface { struct wlr_keyboard_grab_interface {
void (*enter)(struct wlr_seat_keyboard_grab *grab, void (*enter)(struct wlr_seat_keyboard_grab *grab,
struct wlr_surface *surface); struct wlr_surface *surface, uint32_t keycodes[],
size_t num_keycodes, struct wlr_keyboard_modifiers *modifiers);
void (*key)(struct wlr_seat_keyboard_grab *grab, uint32_t time, void (*key)(struct wlr_seat_keyboard_grab *grab, uint32_t time,
uint32_t key, uint32_t state); uint32_t key, uint32_t state);
void (*modifiers)(struct wlr_seat_keyboard_grab *grab); void (*modifiers)(struct wlr_seat_keyboard_grab *grab,
struct wlr_keyboard_modifiers *modifiers);
void (*cancel)(struct wlr_seat_keyboard_grab *grab); void (*cancel)(struct wlr_seat_keyboard_grab *grab);
}; };
@ -344,6 +346,11 @@ bool wlr_seat_pointer_has_grab(struct wlr_seat *seat);
*/ */
void wlr_seat_set_keyboard(struct wlr_seat *seat, struct wlr_input_device *dev); void wlr_seat_set_keyboard(struct wlr_seat *seat, struct wlr_input_device *dev);
/**
* Get the active keyboard for the seat.
*/
struct wlr_keyboard *wlr_seat_get_keyboard(struct wlr_seat *seat);
/** /**
* Start a grab of the keyboard of this seat. The grabber is responsible for * Start a grab of the keyboard of this seat. The grabber is responsible for
* handling all keyboard events until the grab ends. * handling all keyboard events until the grab ends.
@ -375,21 +382,24 @@ void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time,
* Send the modifier state to focused keyboard resources. Compositors should use * Send the modifier state to focused keyboard resources. Compositors should use
* `wlr_seat_keyboard_notify_modifiers()` to respect any keyboard grabs. * `wlr_seat_keyboard_notify_modifiers()` to respect any keyboard grabs.
*/ */
void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat); void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat,
struct wlr_keyboard_modifiers *modifiers);
/** /**
* Notify the seat that the modifiers for the keyboard have changed. Defers to * Notify the seat that the modifiers for the keyboard have changed. Defers to
* any keyboard grabs. * any keyboard grabs.
*/ */
void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat); void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat,
struct wlr_keyboard_modifiers *modifiers);
/** /**
* Notify the seat that the keyboard focus has changed and request it to be the * Notify the seat that the keyboard focus has changed and request it to be the
* focused surface for this keyboard. Defers to any current grab of the seat's * focused surface for this keyboard. Defers to any current grab of the seat's
* keyboard. * keyboard.
*/ */
void wlr_seat_keyboard_notify_enter(struct wlr_seat *wlr_seat, void wlr_seat_keyboard_notify_enter(struct wlr_seat *seat,
struct wlr_surface *surface); struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
struct wlr_keyboard_modifiers *modifiers);
/** /**
* Send a keyboard enter event to the given surface and consider it to be the * Send a keyboard enter event to the given surface and consider it to be the
@ -398,8 +408,9 @@ void wlr_seat_keyboard_notify_enter(struct wlr_seat *wlr_seat,
* `wlr_seat_keyboard_notify_enter()` to change keyboard focus to respect * `wlr_seat_keyboard_notify_enter()` to change keyboard focus to respect
* keyboard grabs. * keyboard grabs.
*/ */
void wlr_seat_keyboard_enter(struct wlr_seat *wlr_seat, void wlr_seat_keyboard_enter(struct wlr_seat *seat,
struct wlr_surface *surface); struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
struct wlr_keyboard_modifiers *modifiers);
/** /**
* Clear the focused surface for the keyboard and leave all entered surfaces. * Clear the focused surface for the keyboard and leave all entered surfaces.

View file

@ -288,7 +288,8 @@ void roots_keyboard_handle_key(struct roots_keyboard *keyboard,
void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) { void roots_keyboard_handle_modifiers(struct roots_keyboard *r_keyboard) {
struct wlr_seat *seat = r_keyboard->seat->seat; struct wlr_seat *seat = r_keyboard->seat->seat;
wlr_seat_set_keyboard(seat, r_keyboard->device); wlr_seat_set_keyboard(seat, r_keyboard->device);
wlr_seat_keyboard_notify_modifiers(seat); wlr_seat_keyboard_notify_modifiers(seat,
&r_keyboard->device->keyboard->modifiers);
} }
static void keyboard_config_merge(struct roots_keyboard_config *config, static void keyboard_config_merge(struct roots_keyboard_config *config,

View file

@ -293,11 +293,6 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) {
return NULL; return NULL;
} }
wlr_seat_set_capabilities(seat->seat,
WL_SEAT_CAPABILITY_KEYBOARD |
WL_SEAT_CAPABILITY_POINTER |
WL_SEAT_CAPABILITY_TOUCH);
wl_list_insert(&input->seats, &seat->link); wl_list_insert(&input->seats, &seat->link);
seat->seat_destroy.notify = roots_seat_handle_seat_destroy; seat->seat_destroy.notify = roots_seat_handle_seat_destroy;
@ -306,6 +301,28 @@ struct roots_seat *roots_seat_create(struct roots_input *input, char *name) {
return seat; return seat;
} }
static void seat_update_capabilities(struct roots_seat *seat) {
uint32_t caps = 0;
if (!wl_list_empty(&seat->keyboards)) {
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
}
if (!wl_list_empty(&seat->pointers) || !wl_list_empty(&seat->tablet_tools)) {
caps |= WL_SEAT_CAPABILITY_POINTER;
}
if (!wl_list_empty(&seat->touch)) {
caps |= WL_SEAT_CAPABILITY_TOUCH;
}
wlr_seat_set_capabilities(seat->seat, caps);
// Hide cursor if seat doesn't have pointer capability
if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
wlr_cursor_set_image(seat->cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
} else {
wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager,
seat->cursor->default_xcursor, seat->cursor->cursor);
}
}
static void seat_add_keyboard(struct roots_seat *seat, static void seat_add_keyboard(struct roots_seat *seat,
struct wlr_input_device *device) { struct wlr_input_device *device) {
assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); assert(device->type == WLR_INPUT_DEVICE_KEYBOARD);
@ -404,6 +421,8 @@ void roots_seat_add_device(struct roots_seat *seat,
seat_add_tablet_tool(seat, device); seat_add_tablet_tool(seat, device);
break; break;
} }
seat_update_capabilities(seat);
} }
static void seat_remove_keyboard(struct roots_seat *seat, static void seat_remove_keyboard(struct roots_seat *seat,
@ -480,6 +499,8 @@ void roots_seat_remove_device(struct roots_seat *seat,
seat_remove_tablet_tool(seat, device); seat_remove_tablet_tool(seat, device);
break; break;
} }
seat_update_capabilities(seat);
} }
void roots_seat_configure_xcursor(struct roots_seat *seat) { void roots_seat_configure_xcursor(struct roots_seat *seat) {
@ -641,7 +662,16 @@ void roots_seat_set_focus(struct roots_seat *seat, struct roots_view *view) {
seat->has_focus = true; seat->has_focus = true;
wl_list_remove(&seat_view->link); wl_list_remove(&seat_view->link);
wl_list_insert(&seat->views, &seat_view->link); wl_list_insert(&seat->views, &seat_view->link);
wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface);
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->seat);
if (keyboard != NULL) {
wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface,
keyboard->keycodes, keyboard->num_keycodes,
&keyboard->modifiers);
} else {
wlr_seat_keyboard_notify_enter(seat->seat, view->wlr_surface,
NULL, 0, NULL);
}
} }
void roots_seat_cycle_focus(struct roots_seat *seat) { void roots_seat_cycle_focus(struct roots_seat *seat) {

View file

@ -585,7 +585,8 @@ const struct wlr_touch_grab_interface wlr_data_device_touch_drag_interface = {
}; };
static void keyboard_drag_enter(struct wlr_seat_keyboard_grab *grab, static void keyboard_drag_enter(struct wlr_seat_keyboard_grab *grab,
struct wlr_surface *surface) { struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
struct wlr_keyboard_modifiers *modifiers) {
// nothing has keyboard focus during drags // nothing has keyboard focus during drags
} }
@ -594,7 +595,8 @@ static void keyboard_drag_key(struct wlr_seat_keyboard_grab *grab,
// no keyboard input during drags // no keyboard input during drags
} }
static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab) { static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab,
struct wlr_keyboard_modifiers *modifiers) {
//struct wlr_keyboard *keyboard = grab->seat->keyboard_state.keyboard; //struct wlr_keyboard *keyboard = grab->seat->keyboard_state.keyboard;
// TODO change the dnd action based on what modifier is pressed on the // TODO change the dnd action based on what modifier is pressed on the
// keyboard // keyboard

View file

@ -11,6 +11,10 @@
int os_create_anonymous_file(off_t size); int os_create_anonymous_file(off_t size);
static void keyboard_led_update(struct wlr_keyboard *keyboard) { static void keyboard_led_update(struct wlr_keyboard *keyboard) {
if (keyboard->xkb_state == NULL) {
return;
}
uint32_t leds = 0; uint32_t leds = 0;
for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) { for (uint32_t i = 0; i < WLR_LED_COUNT; ++i) {
if (xkb_state_led_index_is_active(keyboard->xkb_state, if (xkb_state_led_index_is_active(keyboard->xkb_state,
@ -21,7 +25,15 @@ static void keyboard_led_update(struct wlr_keyboard *keyboard) {
wlr_keyboard_led_update(keyboard, leds); wlr_keyboard_led_update(keyboard, leds);
} }
static void keyboard_modifier_update(struct wlr_keyboard *keyboard) { /**
* Update the modifier state of the wlr-keyboard. Returns true if the modifier
* state changed.
*/
static bool keyboard_modifier_update(struct wlr_keyboard *keyboard) {
if (keyboard->xkb_state == NULL) {
return false;
}
xkb_mod_mask_t depressed = xkb_state_serialize_mods(keyboard->xkb_state, xkb_mod_mask_t depressed = xkb_state_serialize_mods(keyboard->xkb_state,
XKB_STATE_MODS_DEPRESSED); XKB_STATE_MODS_DEPRESSED);
xkb_mod_mask_t latched = xkb_state_serialize_mods(keyboard->xkb_state, xkb_mod_mask_t latched = xkb_state_serialize_mods(keyboard->xkb_state,
@ -34,7 +46,7 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) {
latched == keyboard->modifiers.latched && latched == keyboard->modifiers.latched &&
locked == keyboard->modifiers.locked && locked == keyboard->modifiers.locked &&
group == keyboard->modifiers.group) { group == keyboard->modifiers.group) {
return; return false;
} }
keyboard->modifiers.depressed = depressed; keyboard->modifiers.depressed = depressed;
@ -42,7 +54,7 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) {
keyboard->modifiers.locked = locked; keyboard->modifiers.locked = locked;
keyboard->modifiers.group = group; keyboard->modifiers.group = group;
wl_signal_emit(&keyboard->events.modifiers, keyboard); return true;
} }
// https://www.geeksforgeeks.org/move-zeroes-end-array/ // https://www.geeksforgeeks.org/move-zeroes-end-array/
@ -90,17 +102,21 @@ static void keyboard_key_update(struct wlr_keyboard *keyboard,
void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard,
uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked,
uint32_t group) { uint32_t group) {
if (!keyboard->xkb_state) { if (keyboard->xkb_state == NULL) {
return; return;
} }
xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched,
mods_locked, 0, 0, group); mods_locked, 0, 0, group);
keyboard_modifier_update(keyboard);
bool updated = keyboard_modifier_update(keyboard);
if (updated) {
wl_signal_emit(&keyboard->events.modifiers, keyboard);
}
} }
void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard, void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,
struct wlr_event_keyboard_key *event) { struct wlr_event_keyboard_key *event) {
if (!keyboard->xkb_state) { if (keyboard->xkb_state == NULL) {
return; return;
} }
if (event->update_state) { if (event->update_state) {
@ -109,7 +125,12 @@ void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,
event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP);
} }
keyboard_led_update(keyboard); keyboard_led_update(keyboard);
keyboard_modifier_update(keyboard);
bool updated = keyboard_modifier_update(keyboard);
if (updated) {
wl_signal_emit(&keyboard->events.modifiers, keyboard);
}
keyboard_key_update(keyboard, event); keyboard_key_update(keyboard, event);
wl_signal_emit(&keyboard->events.key, event); wl_signal_emit(&keyboard->events.key, event);
} }
@ -150,20 +171,16 @@ void wlr_keyboard_led_update(struct wlr_keyboard *kb, uint32_t leds) {
void wlr_keyboard_set_keymap(struct wlr_keyboard *kb, void wlr_keyboard_set_keymap(struct wlr_keyboard *kb,
struct xkb_keymap *keymap) { struct xkb_keymap *keymap) {
if (kb->keymap) { char *keymap_str = NULL;
xkb_keymap_unref(kb->keymap); xkb_keymap_unref(kb->keymap);
} kb->keymap = xkb_keymap_ref(keymap);
xkb_keymap_ref(keymap);
kb->keymap = keymap;
if (kb->xkb_state) {
xkb_state_unref(kb->xkb_state); xkb_state_unref(kb->xkb_state);
}
kb->xkb_state = xkb_state_new(kb->keymap); kb->xkb_state = xkb_state_new(kb->keymap);
if (kb->xkb_state == NULL) { if (kb->xkb_state == NULL) {
wlr_log(L_ERROR, "Failed to create XKB state"); wlr_log(L_ERROR, "Failed to create XKB state");
return; goto err;
} }
const char *led_names[WLR_LED_COUNT] = { const char *led_names[WLR_LED_COUNT] = {
@ -190,7 +207,7 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb,
kb->mod_indexes[i] = xkb_map_mod_get_index(kb->keymap, mod_names[i]); kb->mod_indexes[i] = xkb_map_mod_get_index(kb->keymap, mod_names[i]);
} }
char *keymap_str = xkb_keymap_get_as_string(kb->keymap, keymap_str = xkb_keymap_get_as_string(kb->keymap,
XKB_KEYMAP_FORMAT_TEXT_V1); XKB_KEYMAP_FORMAT_TEXT_V1);
kb->keymap_size = strlen(keymap_str) + 1; kb->keymap_size = strlen(keymap_str) + 1;
if (kb->keymap_fd) { if (kb->keymap_fd) {
@ -199,16 +216,34 @@ void wlr_keyboard_set_keymap(struct wlr_keyboard *kb,
kb->keymap_fd = os_create_anonymous_file(kb->keymap_size); kb->keymap_fd = os_create_anonymous_file(kb->keymap_size);
if (kb->keymap_fd < 0) { if (kb->keymap_fd < 0) {
wlr_log(L_ERROR, "creating a keymap file for %lu bytes failed", kb->keymap_size); wlr_log(L_ERROR, "creating a keymap file for %lu bytes failed", kb->keymap_size);
goto err;
} }
void *ptr = mmap(NULL, kb->keymap_size, void *ptr = mmap(NULL, kb->keymap_size,
PROT_READ | PROT_WRITE, MAP_SHARED, kb->keymap_fd, 0); PROT_READ | PROT_WRITE, MAP_SHARED, kb->keymap_fd, 0);
if (ptr == (void*)-1) { if (ptr == (void*)-1) {
wlr_log(L_ERROR, "failed to mmap() %lu bytes", kb->keymap_size); wlr_log(L_ERROR, "failed to mmap() %lu bytes", kb->keymap_size);
goto err;
} }
strcpy(ptr, keymap_str); strcpy(ptr, keymap_str);
free(keymap_str); free(keymap_str);
for (size_t i = 0; i < kb->num_keycodes; ++i) {
xkb_keycode_t keycode = kb->keycodes[i] + 8;
xkb_state_update_key(kb->xkb_state, keycode, XKB_KEY_DOWN);
}
keyboard_modifier_update(kb);
wl_signal_emit(&kb->events.keymap, kb); wl_signal_emit(&kb->events.keymap, kb);
return;
err:
xkb_state_unref(kb->xkb_state);
kb->xkb_state = NULL;
xkb_keymap_unref(keymap);
kb->keymap = NULL;
close(kb->keymap_fd);
free(keymap_str);
} }
void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate, void wlr_keyboard_set_repeat_info(struct wlr_keyboard *kb, int32_t rate,

View file

@ -282,8 +282,9 @@ static const struct wlr_pointer_grab_interface default_pointer_grab_impl = {
}; };
static void default_keyboard_enter(struct wlr_seat_keyboard_grab *grab, static void default_keyboard_enter(struct wlr_seat_keyboard_grab *grab,
struct wlr_surface *surface) { struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
wlr_seat_keyboard_enter(grab->seat, surface); struct wlr_keyboard_modifiers *modifiers) {
wlr_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes, modifiers);
} }
static void default_keyboard_key(struct wlr_seat_keyboard_grab *grab, static void default_keyboard_key(struct wlr_seat_keyboard_grab *grab,
@ -291,8 +292,9 @@ static void default_keyboard_key(struct wlr_seat_keyboard_grab *grab,
wlr_seat_keyboard_send_key(grab->seat, time, key, state); wlr_seat_keyboard_send_key(grab->seat, time, key, state);
} }
static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab) { static void default_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab,
wlr_seat_keyboard_send_modifiers(grab->seat); struct wlr_keyboard_modifiers *modifiers) {
wlr_seat_keyboard_send_modifiers(grab->seat, modifiers);
} }
static void default_keyboard_cancel(struct wlr_seat_keyboard_grab *grab) { static void default_keyboard_cancel(struct wlr_seat_keyboard_grab *grab) {
@ -773,6 +775,7 @@ void wlr_seat_set_keyboard(struct wlr_seat *seat,
if (keyboard) { if (keyboard) {
assert(device->type == WLR_INPUT_DEVICE_KEYBOARD); assert(device->type == WLR_INPUT_DEVICE_KEYBOARD);
seat->keyboard_state.keyboard = keyboard;
wl_signal_add(&device->events.destroy, wl_signal_add(&device->events.destroy,
&seat->keyboard_state.keyboard_destroy); &seat->keyboard_state.keyboard_destroy);
@ -787,14 +790,18 @@ void wlr_seat_set_keyboard(struct wlr_seat *seat,
struct wlr_seat_client *client; struct wlr_seat_client *client;
wl_list_for_each(client, &seat->clients, link) { wl_list_for_each(client, &seat->clients, link) {
seat_client_send_keymap(client, device->keyboard); seat_client_send_keymap(client, keyboard);
seat_client_send_repeat_info(client, device->keyboard); seat_client_send_repeat_info(client, keyboard);
} }
wlr_seat_keyboard_send_modifiers(seat, &keyboard->modifiers);
} else {
seat->keyboard_state.keyboard = NULL;
} }
}
seat->keyboard_state.keyboard = keyboard; struct wlr_keyboard *wlr_seat_get_keyboard(struct wlr_seat *seat) {
wlr_seat_keyboard_send_modifiers(seat); return seat->keyboard_state.keyboard;
} }
void wlr_seat_keyboard_start_grab(struct wlr_seat *wlr_seat, void wlr_seat_keyboard_start_grab(struct wlr_seat *wlr_seat,
@ -835,28 +842,29 @@ static void keyboard_resource_destroy_notify(struct wl_listener *listener,
wlr_seat_keyboard_clear_focus(state->seat); wlr_seat_keyboard_clear_focus(state->seat);
} }
void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat) { void wlr_seat_keyboard_send_modifiers(struct wlr_seat *seat,
struct wlr_keyboard_modifiers *modifiers) {
struct wlr_seat_client *client = seat->keyboard_state.focused_client; struct wlr_seat_client *client = seat->keyboard_state.focused_client;
if (client == NULL) { if (client == NULL) {
return; return;
} }
struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard;
if (keyboard == NULL) {
return;
}
uint32_t serial = wl_display_next_serial(seat->display); uint32_t serial = wl_display_next_serial(seat->display);
struct wl_resource *resource; struct wl_resource *resource;
wl_resource_for_each(resource, &client->keyboards) { wl_resource_for_each(resource, &client->keyboards) {
if (modifiers == NULL) {
wl_keyboard_send_modifiers(resource, serial, 0, 0, 0, 0);
} else {
wl_keyboard_send_modifiers(resource, serial, wl_keyboard_send_modifiers(resource, serial,
keyboard->modifiers.depressed, keyboard->modifiers.latched, modifiers->depressed, modifiers->latched,
keyboard->modifiers.locked, keyboard->modifiers.group); modifiers->locked, modifiers->group);
}
} }
} }
void wlr_seat_keyboard_enter(struct wlr_seat *seat, void wlr_seat_keyboard_enter(struct wlr_seat *seat,
struct wlr_surface *surface) { struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
struct wlr_keyboard_modifiers *modifiers) {
if (seat->keyboard_state.focused_surface == surface) { if (seat->keyboard_state.focused_surface == surface) {
// this surface already got an enter notify // this surface already got an enter notify
return; return;
@ -884,19 +892,17 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat,
} }
// enter the current surface // enter the current surface
if (client != NULL && seat->keyboard_state.keyboard != NULL) { if (client != NULL) {
struct wlr_keyboard *keyboard = seat->keyboard_state.keyboard;
struct wl_array keys; struct wl_array keys;
wl_array_init(&keys); wl_array_init(&keys);
for (size_t i = 0; i < keyboard->num_keycodes; ++i) { for (size_t i = 0; i < num_keycodes; ++i) {
uint32_t *p = wl_array_add(&keys, sizeof(uint32_t)); uint32_t *p = wl_array_add(&keys, sizeof(uint32_t));
if (!p) { if (!p) {
wlr_log(L_ERROR, "Cannot allocate memory, skipping keycode: %d\n", wlr_log(L_ERROR, "Cannot allocate memory, skipping keycode: %d\n",
keyboard->keycodes[i]); keycodes[i]);
continue; continue;
} }
*p = keyboard->keycodes[i]; *p = keycodes[i];
} }
uint32_t serial = wl_display_next_serial(seat->display); uint32_t serial = wl_display_next_serial(seat->display);
struct wl_resource *resource; struct wl_resource *resource;
@ -928,33 +934,34 @@ void wlr_seat_keyboard_enter(struct wlr_seat *seat,
seat->keyboard_state.focused_client = client; seat->keyboard_state.focused_client = client;
seat->keyboard_state.focused_surface = surface; seat->keyboard_state.focused_surface = surface;
if (client != NULL && seat->keyboard_state.keyboard != NULL) { if (client != NULL) {
// tell new client about any modifier change last, // tell new client about any modifier change last,
// as it targets seat->keyboard_state.focused_client // as it targets seat->keyboard_state.focused_client
wlr_seat_keyboard_send_modifiers(seat); wlr_seat_keyboard_send_modifiers(seat, modifiers);
} }
} }
void wlr_seat_keyboard_notify_enter(struct wlr_seat *seat, struct void wlr_seat_keyboard_notify_enter(struct wlr_seat *seat,
wlr_surface *surface) { struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
struct wlr_keyboard_modifiers *modifiers) {
struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab;
grab->interface->enter(grab, surface); grab->interface->enter(grab, surface, keycodes, num_keycodes, modifiers);
} }
void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) { void wlr_seat_keyboard_clear_focus(struct wlr_seat *seat) {
struct wl_array keys; // TODO respect grabs here?
wl_array_init(&keys); wlr_seat_keyboard_enter(seat, NULL, NULL, 0, NULL);
wlr_seat_keyboard_enter(seat, NULL);
} }
bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat) { bool wlr_seat_keyboard_has_grab(struct wlr_seat *seat) {
return seat->keyboard_state.grab->interface != &default_keyboard_grab_impl; return seat->keyboard_state.grab->interface != &default_keyboard_grab_impl;
} }
void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat) { void wlr_seat_keyboard_notify_modifiers(struct wlr_seat *seat,
struct wlr_keyboard_modifiers *modifiers) {
clock_gettime(CLOCK_MONOTONIC, &seat->last_event); clock_gettime(CLOCK_MONOTONIC, &seat->last_event);
struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab; struct wlr_seat_keyboard_grab *grab = seat->keyboard_state.grab;
grab->interface->modifiers(grab); grab->interface->modifiers(grab, modifiers);
} }
void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time, void wlr_seat_keyboard_notify_key(struct wlr_seat *seat, uint32_t time,

View file

@ -731,9 +731,10 @@ static struct wlr_subsurface *subsurface_find_sibling(
struct wlr_subsurface *sibling; struct wlr_subsurface *sibling;
wl_list_for_each(sibling, &parent->subsurface_list, parent_link) { wl_list_for_each(sibling, &parent->subsurface_list, parent_link) {
if (sibling->surface == surface && sibling != subsurface) if (sibling->surface == surface && sibling != subsurface) {
return sibling; return sibling;
} }
}
return NULL; return NULL;
} }

View file

@ -103,7 +103,9 @@ static const struct wlr_pointer_grab_interface xdg_pointer_grab_impl = {
.axis = xdg_pointer_grab_axis, .axis = xdg_pointer_grab_axis,
}; };
static void xdg_keyboard_grab_enter(struct wlr_seat_keyboard_grab *grab, struct wlr_surface *surface) { static void xdg_keyboard_grab_enter(struct wlr_seat_keyboard_grab *grab,
struct wlr_surface *surface, uint32_t keycodes[], size_t num_keycodes,
struct wlr_keyboard_modifiers *modifiers) {
// keyboard focus should remain on the popup // keyboard focus should remain on the popup
} }
@ -112,8 +114,9 @@ static void xdg_keyboard_grab_key(struct wlr_seat_keyboard_grab *grab, uint32_t
wlr_seat_keyboard_send_key(grab->seat, time, key, state); wlr_seat_keyboard_send_key(grab->seat, time, key, state);
} }
static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab) { static void xdg_keyboard_grab_modifiers(struct wlr_seat_keyboard_grab *grab,
wlr_seat_keyboard_send_modifiers(grab->seat); struct wlr_keyboard_modifiers *modifiers) {
wlr_seat_keyboard_send_modifiers(grab->seat, modifiers);
} }
static void xdg_keyboard_grab_cancel(struct wlr_seat_keyboard_grab *grab) { static void xdg_keyboard_grab_cancel(struct wlr_seat_keyboard_grab *grab) {

View file

@ -480,13 +480,14 @@ static void read_surface_net_wm_state(struct wlr_xwm *xwm,
xsurface->fullscreen = 0; xsurface->fullscreen = 0;
xcb_atom_t *atom = xcb_get_property_value(reply); xcb_atom_t *atom = xcb_get_property_value(reply);
for (uint32_t i = 0; i < reply->value_len; i++) { for (uint32_t i = 0; i < reply->value_len; i++) {
if (atom[i] == xwm->atoms[_NET_WM_STATE_FULLSCREEN]) if (atom[i] == xwm->atoms[_NET_WM_STATE_FULLSCREEN]) {
xsurface->fullscreen = true; xsurface->fullscreen = true;
if (atom[i] == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT]) } else if (atom[i] == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT]) {
xsurface->maximized_vert = true; xsurface->maximized_vert = true;
if (atom[i] == xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ]) } else if (atom[i] == xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ]) {
xsurface->maximized_horz = true; xsurface->maximized_horz = true;
} }
}
} }
static void read_surface_property(struct wlr_xwm *xwm, static void read_surface_property(struct wlr_xwm *xwm,