diff --git a/include/desktop/view.h b/include/desktop/view.h index c3e8a12..a7475c8 100644 --- a/include/desktop/view.h +++ b/include/desktop/view.h @@ -52,4 +52,6 @@ void kiwmi_view_for_each_surface( wlr_surface_iterator_func_t iterator, void *user_data); +void focus_view(struct kiwmi_view *view, struct wlr_surface *surface); + #endif /* KIWMI_DESKTOP_VIEW_H */ diff --git a/include/input/input.h b/include/input/input.h index 2bbe0f5..be9e4d7 100644 --- a/include/input/input.h +++ b/include/input/input.h @@ -14,6 +14,7 @@ struct kiwmi_input { struct wl_list keyboards; // struct kiwmi_keyboard::link struct wl_listener new_input; struct kiwmi_cursor *cursor; + struct wlr_seat *seat; }; bool input_init(struct kiwmi_input *input); diff --git a/kiwmi/desktop/view.c b/kiwmi/desktop/view.c index 878cba5..a0d091f 100644 --- a/kiwmi/desktop/view.c +++ b/kiwmi/desktop/view.c @@ -6,6 +6,7 @@ */ #include "desktop/view.h" +#include "server.h" void kiwmi_view_for_each_surface( @@ -17,3 +18,40 @@ kiwmi_view_for_each_surface( view->impl->for_each_surface(view, iterator, user_data); } } + +void +focus_view(struct kiwmi_view *view, struct wlr_surface *surface) +{ + if (!view) { + return; + } + + struct kiwmi_desktop *desktop = view->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + struct wlr_seat *seat = server->input.seat; + struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface; + + if (prev_surface == surface) { + return; + } + + if (prev_surface) { + struct wlr_xdg_surface *previous = wlr_xdg_surface_from_wlr_surface( + seat->keyboard_state.focused_surface); + wlr_xdg_toplevel_set_activated(previous, false); + } + + struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat); + + // move view to front + wl_list_remove(&view->link); + wl_list_insert(&desktop->views, &view->link); + + wlr_xdg_toplevel_set_activated(view->xdg_surface, true); + wlr_seat_keyboard_notify_enter( + seat, + view->xdg_surface->surface, + keyboard->keycodes, + keyboard->num_keycodes, + &keyboard->modifiers); +} diff --git a/kiwmi/desktop/xdg_shell.c b/kiwmi/desktop/xdg_shell.c index 4bf9b0e..dfdfb04 100644 --- a/kiwmi/desktop/xdg_shell.c +++ b/kiwmi/desktop/xdg_shell.c @@ -19,6 +19,7 @@ xdg_surface_map_notify(struct wl_listener *listener, void *UNUSED(data)) { struct kiwmi_view *view = wl_container_of(listener, view, map); view->mapped = true; + focus_view(view, view->xdg_surface->surface); } static void diff --git a/kiwmi/input/input.c b/kiwmi/input/input.c index 6dffaf5..22455ed 100644 --- a/kiwmi/input/input.c +++ b/kiwmi/input/input.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "desktop/desktop.h" @@ -56,6 +57,13 @@ new_input_notify(struct wl_listener *listener, void *data) // NOT HANDLED break; } + + uint32_t caps = WL_SEAT_CAPABILITY_POINTER; + if (!wl_list_empty(&input->keyboards)) { + caps |= WL_SEAT_CAPABILITY_KEYBOARD; + } + + wlr_seat_set_capabilities(input->seat, caps); } bool @@ -69,6 +77,8 @@ input_init(struct kiwmi_input *input) return false; } + input->seat = wlr_seat_create(server->wl_display, "seat-0"); + wl_list_init(&input->keyboards); input->new_input.notify = new_input_notify; diff --git a/kiwmi/input/keyboard.c b/kiwmi/input/keyboard.c index 68e3088..190fc0b 100644 --- a/kiwmi/input/keyboard.c +++ b/kiwmi/input/keyboard.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -41,10 +42,13 @@ switch_vt(const xkb_keysym_t *syms, int nsyms, struct wlr_backend *backend) } static void -keyboard_modifiers_notify( - struct wl_listener *UNUSED(listener), - void *UNUSED(data)) +keyboard_modifiers_notify(struct wl_listener *listener, void *UNUSED(data)) { + struct kiwmi_keyboard *keyboard = + wl_container_of(listener, keyboard, modifiers); + wlr_seat_set_keyboard(keyboard->server->input.seat, keyboard->device); + wlr_seat_keyboard_notify_modifiers( + keyboard->server->input.seat, &keyboard->device->keyboard->modifiers); } static void @@ -78,6 +82,12 @@ keyboard_key_notify(struct wl_listener *listener, void *data) } } } + + if (!handled) { + wlr_seat_set_keyboard(server->input.seat, keyboard->device); + wlr_seat_keyboard_notify_key( + server->input.seat, event->time_msec, event->keycode, event->state); + } } struct kiwmi_keyboard * @@ -109,5 +119,7 @@ keyboard_create(struct kiwmi_server *server, struct wlr_input_device *device) xkb_context_unref(context); wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); + wlr_seat_set_keyboard(server->input.seat, device); + return keyboard; }