Commit 23600c53fbdf886fcbc2fc4a5913c75d26821e26 Parent: 3e5fc4b2bd41458c4e5a6c8cebb76c5578ee49a8 Author: mcol <mcol@posteo.net> Date: 2021-01-30 22:05:01 +0000 Committer: mcol <mcol@posteo.net> Committed: 2021-01-30 22:05:01 +0000 Let the pointer interact with layer surfaces
src/shell.c Modified
@@ -24,7 +24,7 @@ if (prev_surface == surface) { return; } - if (prev_surface) { + if (prev_surface && wlr_surface_is_xdg_surface(prev_surface)) { struct wlr_xdg_surface *previous = wlr_xdg_surface_from_wlr_surface( seat->keyboard_state.focused_surface );
src/layer_shell.c Modified
@@ -97,7 +97,7 @@ lview->surface->mapped = false; layer(lview->output); - if (wimp.focussed_layer_view == lview) { + 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(
src/cursor.h Modified
@@ -3,10 +3,7 @@ #include "types.h" -struct view *view_at( - double lx, double ly, struct wlr_surface **surface, double *sx, double *sy -); - +void *under_pointer(struct wlr_surface **surface, double *sx, double *sy, bool *is_layer); void set_up_cursor(); #endif
src/cursor.c Modified
@@ -2,6 +2,7 @@ #include <linux/input-event-codes.h> #include <unistd.h> #include <wlr/types/wlr_cursor.h> +#include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_pointer_gestures_v1.h> #include <wlr/types/wlr_xcursor_manager.h> @@ -46,28 +47,68 @@ } -struct view *view_at( - double lx, double ly, struct wlr_surface **surface, double *sx, double *sy -) { +void *under_pointer(struct wlr_surface **surface, double *sx, double *sy, bool *is_layer) { + double x = wimp.cursor->x; + double y = wimp.cursor->y; + double tsx, tsy; struct view *view; - lx /= wimp.current_desk->zoom; - ly /= wimp.current_desk->zoom; - double _sx, _sy; + struct layer_view *lview; + struct wlr_surface *tsurface; + struct wlr_output *wlr_output = wlr_output_layout_output_at(wimp.output_layout, x, y); + struct output *output = wlr_output->data; + + // overlay and top layers + uint32_t above[] = { ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, ZWLR_LAYER_SHELL_V1_LAYER_TOP }; + size_t nlayers = sizeof(above) / sizeof(above[0]); + for (size_t i = 0; i < nlayers; i++) { + wl_list_for_each(lview, &output->layer_views[above[i]], link) { + tsurface = wlr_layer_surface_v1_surface_at( + lview->surface, x - lview->geo.x, y - lview->geo.y, &tsx, &tsy + ); + if (tsurface) { + *sx = tsx; + *sy = tsy; + *surface = tsurface; + *is_layer = true; + return lview; + } + } + } + + // clients + double zx = x / wimp.current_desk->zoom; + double zy = y / wimp.current_desk->zoom; wl_list_for_each(view, &wimp.current_desk->views, link) { - double view_sx = lx - view->x; - double view_sy = ly - view->y; - struct wlr_surface *_surface = NULL; - _surface = wlr_xdg_surface_surface_at( - view->surface, view_sx, view_sy, &_sx, &_sy + tsurface = wlr_xdg_surface_surface_at( + view->surface, zx - view->x, zy - view->y, &tsx, &tsy ); - if (_surface != NULL) { - *sx = _sx; - *sy = _sy; - *surface = _surface; + if (tsurface) { + *sx = tsx; + *sy = tsy; + *surface = tsurface; + *is_layer = false; return view; } } + + // bottom and background layers + uint32_t below[] = { ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND }; + for (size_t i = 0; i < nlayers; i++) { + wl_list_for_each(lview, &output->layer_views[below[i]], link) { + tsurface = wlr_layer_surface_v1_surface_at( + lview->surface, x - lview->geo.x, y - lview->geo.y, &tsx, &tsy + ); + if (tsurface) { + *sx = tsx; + *sy = tsy; + *surface = tsurface; + *is_layer = true; + return lview; + } + } + } + return NULL; } @@ -78,14 +119,13 @@ struct wlr_surface *surface; struct view *view; double zoom = wimp.current_desk->zoom; - dx /= zoom; - dy /= zoom; switch (wimp.cursor_mode) { case CURSOR_PASSTHROUGH: seat = wimp.seat; surface = NULL; - view = view_at(wimp.cursor->x, wimp.cursor->y, &surface, &sx, &sy); + bool is_layer; + view = under_pointer(&surface, &sx, &sy, &is_layer); if (!view) { wlr_xcursor_manager_set_cursor_image(wimp.cursor_manager, "left_ptr", wimp.cursor); } @@ -103,8 +143,8 @@ case CURSOR_MOD: if (wimp.on_mouse_motion) { struct motion motion = { - .dx = dx, - .dy = dy, + .dx = dx / zoom, + .dy = dy / zoom, .is_percentage = false, }; wimp.on_mouse_motion(&motion); @@ -139,6 +179,9 @@ static void on_cursor_button(struct wl_listener *listener, void *data) { struct wlr_event_pointer_button *event = data; wlr_seat_pointer_notify_button(wimp.seat, event->time_msec, event->button, event->state); + double sx, sy; + struct wlr_surface *surface; + bool is_layer; if (event->state == WLR_BUTTON_RELEASED) { if (wimp.cursor_mode == CURSOR_MOD) { @@ -156,8 +199,9 @@ if (wimp.grabbed_view) { wimp.grabbed_view = NULL; } + } - } else if (wimp.cursor_mode == CURSOR_MOD) { + else if (wimp.cursor_mode == CURSOR_MOD) { bool grab = true; switch (event->button) { case BTN_LEFT: @@ -173,18 +217,15 @@ grab = false; } if (grab) { - struct wlr_surface *surface; - double sx, sy; - wimp.grabbed_view = view_at(wimp.cursor->x, wimp.cursor->y, &surface, &sx, &sy); + wimp.grabbed_view = under_pointer(&surface, &sx, &sy, &is_layer); } + } - } else { - double sx, sy; - struct wlr_surface *surface; - struct view *view = view_at( - wimp.cursor->x, wimp.cursor->y, &surface, &sx, &sy - ); - focus_view(view, surface); + else { + struct view *view = under_pointer(&surface, &sx, &sy, &is_layer); + if (!is_layer) { + focus_view(view, surface); + } } }
src/action.c Modified
@@ -52,8 +52,9 @@ } else { double sx, sy; struct wlr_surface *surface; - view = view_at(wimp.cursor->x, wimp.cursor->y, &surface, &sx, &sy); - if (!view) { + bool is_layer; + view = under_pointer(&surface, &sx, &sy, &is_layer); + if (!view || is_layer) { return; } } @@ -277,8 +278,9 @@ void toggle_fullscreen(void *data) { struct wlr_surface *surface = wimp.seat->keyboard_state.focused_surface; - if (!surface) + if (!surface || !wlr_surface_is_xdg_surface(surface)) { return; + } struct wlr_xdg_surface *xdg_surface = wlr_xdg_surface_from_wlr_surface(surface); struct view *view = wl_container_of(wimp.current_desk->views.next, view, link); fullscreen_xdg_surface(view, xdg_surface, NULL);