diff --git a/include/desktop/desktop.h b/include/desktop/desktop.h index 7ea305e..abae8ce 100644 --- a/include/desktop/desktop.h +++ b/include/desktop/desktop.h @@ -18,8 +18,7 @@ struct kiwmi_desktop { struct wlr_data_device_manager *data_device_manager; struct wlr_output_layout *output_layout; struct wl_list outputs; // struct kiwmi_output::link - struct kiwmi_view *focused_view; - struct wl_list views; // struct kiwmi_view::link + struct wl_list views; // struct kiwmi_view::link struct wl_listener xdg_shell_new_surface; struct wl_listener layer_shell_new_surface; diff --git a/include/input/seat.h b/include/input/seat.h index 2b9ffcb..80a19bb 100644 --- a/include/input/seat.h +++ b/include/input/seat.h @@ -9,16 +9,27 @@ #define KIWMI_INPUT_SEAT_H #include +#include +#include "desktop/layer_shell.h" +#include "desktop/view.h" #include "input/input.h" struct kiwmi_seat { struct kiwmi_input *input; struct wlr_seat *seat; + struct kiwmi_view *focused_view; + struct kiwmi_layer *focused_layer; + struct wl_listener request_set_cursor; }; +void +seat_focus_surface(struct kiwmi_seat *seat, struct wlr_surface *wlr_surface); +void seat_focus_layer(struct kiwmi_seat *seat, struct kiwmi_layer *layer); +void seat_focus_view(struct kiwmi_seat *seat, struct kiwmi_view *view); + struct kiwmi_seat *seat_create(struct kiwmi_input *input); void seat_destroy(struct kiwmi_seat *seat); diff --git a/kiwmi/desktop/desktop.c b/kiwmi/desktop/desktop.c index f2c5bad..baa0597 100644 --- a/kiwmi/desktop/desktop.c +++ b/kiwmi/desktop/desktop.c @@ -28,6 +28,7 @@ bool desktop_init(struct kiwmi_desktop *desktop, struct wlr_renderer *renderer) { struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + desktop->compositor = wlr_compositor_create(server->wl_display, renderer); desktop->data_device_manager = wlr_data_device_manager_create(server->wl_display); @@ -49,8 +50,6 @@ desktop_init(struct kiwmi_desktop *desktop, struct wlr_renderer *renderer) &desktop->layer_shell->events.new_surface, &desktop->layer_shell_new_surface); - desktop->focused_view = NULL; - wl_list_init(&desktop->outputs); wl_list_init(&desktop->views); diff --git a/kiwmi/desktop/layer_shell.c b/kiwmi/desktop/layer_shell.c index a13dbd9..8b001ff 100644 --- a/kiwmi/desktop/layer_shell.c +++ b/kiwmi/desktop/layer_shell.c @@ -14,8 +14,8 @@ #include #include "desktop/desktop.h" -#include "wayland-util.h" -#include "wlr-layer-shell-unstable-v1-protocol.h" +#include "input/seat.h" +#include "server.h" static void kiwmi_layer_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) @@ -27,6 +27,8 @@ kiwmi_layer_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) wlr_layer_surface_v1_close(layer->layer_surface); + arrange_layers(layer->output); + free(layer); } @@ -291,7 +293,11 @@ arrange_layers(struct kiwmi_output *output) } } - // TODO: focus topmost + struct kiwmi_desktop *desktop = output->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + struct kiwmi_seat *seat = server->input.seat; + + seat_focus_layer(seat, topmost); } void diff --git a/kiwmi/desktop/view.c b/kiwmi/desktop/view.c index 39aa4bd..8c6f1eb 100644 --- a/kiwmi/desktop/view.c +++ b/kiwmi/desktop/view.c @@ -81,41 +81,6 @@ view_surface_at( return NULL; } -void -view_focus(struct kiwmi_view *view) -{ - 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->seat; - - if (view == desktop->focused_view) { - return; - } - - if (desktop->focused_view) { - view_set_activated(desktop->focused_view, 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); - - desktop->focused_view = view; - view_set_activated(view, true); - wlr_seat_keyboard_notify_enter( - seat, - view->wlr_surface, - keyboard->keycodes, - keyboard->num_keycodes, - &keyboard->modifiers); -} - static bool surface_at( struct kiwmi_view *view, diff --git a/kiwmi/desktop/xdg_shell.c b/kiwmi/desktop/xdg_shell.c index 70ba796..a6b6225 100644 --- a/kiwmi/desktop/xdg_shell.c +++ b/kiwmi/desktop/xdg_shell.c @@ -13,6 +13,8 @@ #include "desktop/desktop.h" #include "desktop/view.h" +#include "input/input.h" +#include "input/seat.h" #include "server.h" static void @@ -38,9 +40,11 @@ xdg_surface_destroy_notify(struct wl_listener *listener, void *UNUSED(data)) { struct kiwmi_view *view = wl_container_of(listener, view, destroy); struct kiwmi_desktop *desktop = view->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + struct kiwmi_seat *seat = server->input.seat; - if (desktop->focused_view == view) { - desktop->focused_view = NULL; + if (seat->focused_view == view) { + seat->focused_view = NULL; } wl_list_remove(&view->link); diff --git a/kiwmi/input/seat.c b/kiwmi/input/seat.c index 91347ed..81a3cbf 100644 --- a/kiwmi/input/seat.c +++ b/kiwmi/input/seat.c @@ -9,14 +9,82 @@ #include -#include #include +#include #include #include +#include "desktop/layer_shell.h" +#include "desktop/view.h" #include "input/cursor.h" #include "server.h" +void +seat_focus_surface(struct kiwmi_seat *seat, struct wlr_surface *wlr_surface) +{ + if (seat->focused_layer) { + return; + } + + struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->seat); + if (!keyboard) { + wlr_seat_keyboard_enter(seat->seat, wlr_surface, NULL, 0, NULL); + } + + wlr_seat_keyboard_enter( + seat->seat, + wlr_surface, + keyboard->keycodes, + keyboard->num_keycodes, + &keyboard->modifiers); +} + +void +seat_focus_view(struct kiwmi_seat *seat, struct kiwmi_view *view) +{ + if (!view) { + seat_focus_surface(seat, NULL); + } + + struct kiwmi_desktop *desktop = view->desktop; + + if (seat->focused_view) { + view_set_activated(seat->focused_view, false); + } + + // move view to front + wl_list_remove(&view->link); + wl_list_insert(&desktop->views, &view->link); + + seat->focused_view = view; + view_set_activated(view, true); + seat_focus_surface(seat, view->wlr_surface); +} + +void +seat_focus_layer(struct kiwmi_seat *seat, struct kiwmi_layer *layer) +{ + if (!layer) { + if (seat->focused_layer) { + seat_focus_surface(seat, NULL); + seat_focus_surface( + seat, seat->focused_layer->layer_surface->surface); + } + + return; + } + + if (seat->focused_layer == layer) { + return; + } + + seat->focused_layer = NULL; + + seat_focus_surface(seat, layer->layer_surface->surface); + + seat->focused_layer = layer; +} + static void request_set_cursor_notify(struct wl_listener *listener, void *data) { @@ -57,6 +125,9 @@ seat_create(struct kiwmi_input *input) seat->input = input; seat->seat = wlr_seat_create(server->wl_display, "seat-0"); + seat->focused_view = NULL; + seat->focused_layer = NULL; + seat->request_set_cursor.notify = request_set_cursor_notify; wl_signal_add( &seat->seat->events.request_set_cursor, &seat->request_set_cursor); diff --git a/kiwmi/luak/kiwmi_server.c b/kiwmi/luak/kiwmi_server.c index 8c5dbf1..f139049 100644 --- a/kiwmi/luak/kiwmi_server.c +++ b/kiwmi/luak/kiwmi_server.c @@ -18,6 +18,8 @@ #include "desktop/view.h" #include "input/cursor.h" +#include "input/input.h" +#include "input/seat.h" #include "luak/kiwmi_cursor.h" #include "luak/kiwmi_keyboard.h" #include "luak/kiwmi_lua_callback.h" @@ -47,12 +49,12 @@ l_kiwmi_server_focused_view(lua_State *L) struct kiwmi_server *server = *(struct kiwmi_server **)luaL_checkudata(L, 1, "kiwmi_server"); - if (!server->desktop.focused_view) { + if (!server->input.seat->focused_view) { return 0; } lua_pushcfunction(L, luaK_kiwmi_view_new); - lua_pushlightuserdata(L, server->desktop.focused_view); + lua_pushlightuserdata(L, server->input.seat->focused_view); if (lua_pcall(L, 1, 1, 0)) { wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); return 0; diff --git a/kiwmi/luak/kiwmi_view.c b/kiwmi/luak/kiwmi_view.c index f29fc40..3d28137 100644 --- a/kiwmi/luak/kiwmi_view.c +++ b/kiwmi/luak/kiwmi_view.c @@ -10,10 +10,12 @@ #include #include +#include #include #include #include "desktop/view.h" +#include "input/seat.h" #include "luak/kiwmi_lua_callback.h" #include "server.h" @@ -34,7 +36,11 @@ l_kiwmi_view_focus(lua_State *L) struct kiwmi_view *view = *(struct kiwmi_view **)luaL_checkudata(L, 1, "kiwmi_view"); - view_focus(view); + struct kiwmi_desktop *desktop = view->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + struct kiwmi_seat *seat = server->input.seat; + + seat_focus_view(seat, view); return 0; }