Commit 35fb5518f44b97e24c96c75da753efbe14e20559 Parent: aa7ab1a348e62e41d361b2e2bd589cf6f99e7af1 Author: mcol <mcol@posteo.net> Date: 2021-02-12 10:07:11 +0000 Committer: mcol <mcol@posteo.net> Committed: 2021-02-12 10:07:11 +0000 Fix focussing and damage tracking for layer shell surfaces
src/shell.h Modified
@@ -5,7 +5,9 @@ void unmap_view(struct view *view); void map_view(struct view *view); +void focus(void *aview, struct wlr_surface *surface, bool is_layer); void focus_view(struct view *view, struct wlr_surface *surface); +void find_focus(); void pan_to_view(struct view *view); void fullscreen_xdg_surface( struct view *view, struct wlr_xdg_surface *xdg_surface, struct wlr_output *output
src/shell.c Modified
@@ -1,3 +1,4 @@ +#include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_output_damage.h> #include <wlr/types/wlr_xdg_shell.h> #include <wlr/util/edges.h> @@ -18,22 +19,60 @@ } -void focus_view(struct view *view, struct wlr_surface *surface) { +void focus(void *data, struct wlr_surface *surface, bool is_layer) { /* view can be NULL. In that case focus is removed from any focussed surface. */ /* surface can be NULL. In that case focus goes to view->surface->surface. */ + struct layer_view *lview; + struct view *view; + if (data) { + if (is_layer) { + lview = (struct layer_view *)data; + if (!surface) { + surface = lview->surface->surface; + } + } else { + view = (struct view *)data; + if (!surface) { + surface = view->surface->surface; + } + } + } struct wlr_surface *prev_surface = wimp.seat->keyboard_state.focused_surface; - if (prev_surface == surface) { + + if (surface == prev_surface) { return; } wlr_seat_keyboard_notify_clear_focus(wimp.seat); if (prev_surface && wlr_surface_is_xdg_surface(prev_surface)) { - struct wlr_xdg_surface *previous = wlr_xdg_surface_from_wlr_surface(prev_surface); - wlr_xdg_toplevel_set_activated(previous, false); - damage_by_view(previous->data, true); + struct wlr_xdg_surface *prev_xdg_surface = wlr_xdg_surface_from_wlr_surface(prev_surface); + wlr_xdg_toplevel_set_activated(prev_xdg_surface, false); + damage_by_view(prev_xdg_surface->data, true); + } + + if (!data) { + wimp.focussed_layer_view = NULL; + return; } - if (view) { + struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(wimp.seat); + + if (is_layer) { + if (!lview->surface->mapped || !lview->surface->current.keyboard_interactive) { + return; + } + if (!surface) { + surface = lview->surface->surface; + } + wlr_seat_keyboard_notify_enter( + wimp.seat, surface, keyboard->keycodes, + keyboard->num_keycodes, &keyboard->modifiers + ); + wlr_surface_send_enter(surface, lview->surface->output); + wimp.focussed_layer_view = lview; + damage_by_lview(lview); + + } else { if (view->is_scratchpad) { struct scratchpad *scratchpad = scratchpad_from_view(view); scratchpad->is_mapped = true; @@ -47,9 +86,8 @@ if (wlr_surface_is_xdg_surface(surface)) { wlr_xdg_toplevel_set_activated(view->surface, true); } - struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(wimp.seat); wlr_seat_keyboard_notify_enter( - wimp.seat, view->surface->surface, keyboard->keycodes, + wimp.seat, surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers ); damage_by_view(view, true); @@ -57,6 +95,30 @@ } +void focus_view(struct view *view, struct wlr_surface *surface) { + focus(view, surface, false); +} + + +void find_focus() { + struct scratchpad *scratchpad; + wl_list_for_each(scratchpad, &wimp.scratchpads, link) { + if (scratchpad->is_mapped) { + focus_view(scratchpad->view, NULL); + return; + } + } + + if (!wl_list_empty(&wimp.current_desk->views)) { + struct view *view = wl_container_of(wimp.current_desk->views.next, view, link); + focus_view(view, NULL); + return; + }; + + focus_view(NULL, NULL); +} + + void pan_to_view(struct view *view) { int border_width = wimp.current_desk->border_width; double x = view->x - border_width; @@ -183,10 +245,9 @@ static void on_unmap(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, unmap_listener); - struct scratchpad *scratchpad; if (view->is_scratchpad) { - scratchpad = scratchpad_from_view(view); + struct scratchpad *scratchpad = scratchpad_from_view(view); scratchpad->is_mapped = false; } else { wl_list_remove(&view->link); @@ -196,26 +257,9 @@ wl_list_remove(&view->commit_listener.link); damage_by_view(view, true); - if (view->surface->surface != wimp.seat->keyboard_state.focused_surface) { - return; + if (view->surface->surface == wimp.seat->keyboard_state.focused_surface) { + find_focus(); } - - wl_list_for_each(scratchpad, &wimp.scratchpads, link) { - if (scratchpad->is_mapped) { - focus_view(scratchpad->view, NULL); - return; - } - } - - if (!wl_list_empty(&wimp.current_desk->views)) { - struct view *next = wl_container_of(wimp.current_desk->views.next, view, link); - if (view != next) { - focus_view(next, NULL); - return; - } - }; - - focus_view(NULL, NULL); }
src/output.h Modified
@@ -6,6 +6,7 @@ void set_up_outputs(); void damage_box(struct wlr_box *geo, bool add_borders); void damage_by_view(struct view *view, bool with_borders); +void damage_by_lview(struct layer_view *lview); void damage_all_outputs(); #endif
src/output.c Modified
@@ -258,6 +258,11 @@ } +void damage_by_lview(struct layer_view *lview) { + damage_box(&lview->geo, false); +} + + void damage_all_outputs() { struct output *output; wl_list_for_each(output, &wimp.outputs, link) {
src/layer_shell.c Modified
@@ -3,6 +3,7 @@ #include "layer_shell.h" #include "output.h" +#include "shell.h" static void layer(struct output *output) { @@ -61,18 +62,18 @@ ZWLR_LAYER_SHELL_V1_LAYER_TOP, }; size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]); - struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(wimp.seat); + bool found = false; for (size_t i = 0; i < nlayers; ++i) { wl_list_for_each_reverse(lview, &output->layer_views[layers_above_shell[i]], link) { if (lview->surface->current.keyboard_interactive && lview->surface->mapped) { - wlr_seat_keyboard_notify_enter( - wimp.seat, lview->surface->surface, keyboard->keycodes, - keyboard->num_keycodes, &keyboard->modifiers - ); - wimp.focussed_layer_view = lview; + focus(lview, NULL, true); + found = true; break; } } + if (found) { + break; + } } wlr_output_damage_add_whole(output->wlr_output_damage); @@ -94,7 +95,7 @@ static void on_commit(struct wl_listener *listener, void *data) { struct layer_view *lview = wl_container_of(listener, lview, commit_listener); - damage_box(&lview->geo, false); + damage_by_lview(lview); } @@ -102,15 +103,9 @@ struct layer_view *lview = wl_container_of(listener, lview, unmap_listener); lview->surface->mapped = false; layer(lview->output); - - if (wimp.focussed_layer_view == lview && !wl_list_empty(&wimp.current_desk->views)) { - struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(wimp.seat); - struct view *view = wl_container_of(wimp.current_desk->views.next, view, link); - wlr_seat_keyboard_notify_enter( - wimp.seat, view->surface->surface, keyboard->keycodes, - keyboard->num_keycodes, &keyboard->modifiers - ); + if (wimp.focussed_layer_view == lview) { wimp.focussed_layer_view = NULL; + find_focus(); } }
src/cursor.c Modified
@@ -158,7 +158,6 @@ double sx, sy; struct wlr_seat *seat; struct wlr_surface *surface; - struct view *view; double zoom = wimp.current_desk->zoom; switch (wimp.cursor_mode) { @@ -166,7 +165,7 @@ seat = wimp.seat; surface = NULL; bool is_layer; - view = under_pointer(&surface, &sx, &sy, &is_layer); + struct view *view = under_pointer(&surface, &sx, &sy, &is_layer); if (!view) { wlr_xcursor_manager_set_cursor_image(wimp.cursor_manager, "left_ptr", wimp.cursor); } @@ -176,7 +175,7 @@ wlr_seat_pointer_notify_motion(seat, time, sx, sy); } if (wimp.auto_focus && seat->keyboard_state.focused_surface != surface) { - focus_view(view, surface); + focus(view, surface, is_layer); } } else { wlr_seat_pointer_clear_focus(seat);