From 7ea733761b5defc3927242eda75fbdfde6c9ee11 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Fri, 18 Feb 2022 00:07:37 +0100 Subject: [PATCH] Use view->scene_tree as toplevel for view + some legwork: desktop.c move_to_front() calls wlr_scene_node_raise_to_top desktop.c, ssd/include.h add LAB_SSD_{OSD, MENU, LAYER_SURFACE} enums desktop.c desktop_surface_and_view_at() -> desktop_node_and_view_at() cursor.c reenable cursor_rebase() cursor.c reenable button click on layer surface --- include/labwc.h | 11 +++--- include/ssd.h | 3 ++ src/cursor.c | 96 ++++++++++++++++++++++++++++--------------------- src/desktop.c | 44 ++++++++++++++++++----- src/view.c | 8 ++--- src/xdg.c | 14 ++++++-- src/xwayland.c | 14 ++++++-- 7 files changed, 126 insertions(+), 64 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index d0555290..d5ff2d95 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -234,6 +234,7 @@ struct view { #endif }; struct wlr_surface *surface; + struct wlr_scene_tree *scene_tree; struct wlr_scene_node *scene_node; bool mapped; @@ -419,11 +420,13 @@ void desktop_focus_topmost_mapped_view(struct server *server); bool isfocusable(struct view *view); /** - * desktop_surface_and_view_at - find view and surface at (lx, ly) - * Note: If surface points to layer-surface, view will be set to NULL + * desktop_node_and_view_at - find view and scene_node at (lx, ly) + * Note: If node points to layer-surface, view_area will be set + * to LAB_SSD_LAYER_SURFACE, if view points to another surface + * view_area will be LAB_SSD_CLIENT */ -struct view *desktop_surface_and_view_at(struct server *server, double lx, - double ly, struct wlr_surface **surface, double *sx, double *sy, +struct view *desktop_node_and_view_at(struct server *server, double lx, + double ly, struct wlr_scene_node **scene_node, double *sx, double *sy, enum ssd_part_type *view_area); struct view *desktop_view_at_cursor(struct server *server); diff --git a/include/ssd.h b/include/ssd.h index aeeedf0d..d711c060 100644 --- a/include/ssd.h +++ b/include/ssd.h @@ -26,6 +26,9 @@ enum ssd_part_type { LAB_SSD_CLIENT, LAB_SSD_FRAME, LAB_SSD_ROOT, + LAB_SSD_MENU, + LAB_SSD_OSD, + LAB_SSD_LAYER_SURFACE, LAB_SSD_END_MARKER }; diff --git a/src/cursor.c b/src/cursor.c index 37668dcf..633b0c0a 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -12,25 +12,29 @@ #include "ssd.h" #include "config/mousebind.h" -// void -// cursor_rebase(struct seat *seat, uint32_t time_msec) -// { -// double sx, sy; -// struct wlr_surface *surface; -// enum ssd_part_type view_area = LAB_SSD_NONE; -// -// desktop_surface_and_view_at(seat->server, seat->cursor->x, -// seat->cursor->y, &surface, &sx, &sy, &view_area); -// -// if (surface) { -// wlr_seat_pointer_notify_clear_focus(seat->seat); -// wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); -// wlr_seat_pointer_notify_motion(seat->seat, time_msec, sx, sy); -// } else { -// cursor_set(seat, "left_ptr"); -// wlr_seat_pointer_notify_clear_focus(seat->seat); -// } -// } +void +cursor_rebase(struct seat *seat, uint32_t time_msec) +{ + double sx, sy; + struct wlr_scene_node *node; + enum ssd_part_type view_area = LAB_SSD_NONE; + struct wlr_surface *surface = NULL; + + desktop_node_and_view_at(seat->server, seat->cursor->x, + seat->cursor->y, &node, &sx, &sy, &view_area); + if (view_area == LAB_SSD_CLIENT || view_area == LAB_SSD_LAYER_SURFACE) { + surface = wlr_scene_surface_from_node(node)->surface; + } + + if (surface) { + wlr_seat_pointer_notify_clear_focus(seat->seat); + wlr_seat_pointer_notify_enter(seat->seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat->seat, time_msec, sx, sy); + } else { + cursor_set(seat, "left_ptr"); + wlr_seat_pointer_notify_clear_focus(seat->seat); + } +} static void request_cursor_notify(struct wl_listener *listener, void *data) @@ -201,12 +205,17 @@ process_cursor_motion(struct server *server, uint32_t time) /* Otherwise, find view under the pointer and send the event along */ double sx, sy; struct wlr_seat *wlr_seat = server->seat.seat; - struct wlr_surface *surface = NULL; + struct wlr_scene_node *node; enum ssd_part_type view_area = LAB_SSD_NONE; - struct view *view = desktop_surface_and_view_at(server, - server->seat.cursor->x, server->seat.cursor->y, &surface, + struct view *view = desktop_node_and_view_at(server, + server->seat.cursor->x, server->seat.cursor->y, &node, &sx, &sy, &view_area); + struct wlr_surface *surface = NULL; + if (view_area == LAB_SSD_CLIENT || view_area == LAB_SSD_LAYER_SURFACE) { + surface = wlr_scene_surface_from_node(node)->surface; + } + /* resize handles */ uint32_t resize_edges = ssd_resize_edges(view_area); @@ -593,17 +602,22 @@ cursor_button(struct wl_listener *listener, void *data) wlr_idle_notify_activity(seat->wlr_idle, seat->seat); double sx, sy; - struct wlr_surface *surface; + struct wlr_scene_node *node; enum ssd_part_type view_area = LAB_SSD_NONE; uint32_t resize_edges; /* bindings to the Frame context swallow mouse events if activated */ bool triggered_frame_binding = false; - struct view *view = desktop_surface_and_view_at(server, - server->seat.cursor->x, server->seat.cursor->y, &surface, + struct view *view = desktop_node_and_view_at(server, + server->seat.cursor->x, server->seat.cursor->y, &node, &sx, &sy, &view_area); + struct wlr_surface *surface = NULL; + if (view_area == LAB_SSD_CLIENT || view_area == LAB_SSD_LAYER_SURFACE) { + surface = wlr_scene_surface_from_node(node)->surface; + } + /* get modifiers */ struct wlr_input_device *device = seat->keyboard_group->input_device; uint32_t modifiers = wlr_keyboard_get_modifiers(device->keyboard); @@ -622,7 +636,7 @@ cursor_button(struct wl_listener *listener, void *data) server->input_mode = LAB_INPUT_STATE_PASSTHROUGH; server->grabbed_view = NULL; } -// cursor_rebase(&server->seat, event->time_msec); + cursor_rebase(&server->seat, event->time_msec); } /* Handle _release_ on root window */ @@ -640,24 +654,24 @@ cursor_button(struct wl_listener *listener, void *data) menu_action_selected(server, server->windowmenu); } server->input_mode = LAB_INPUT_STATE_PASSTHROUGH; -// cursor_rebase(&server->seat, event->time_msec); + cursor_rebase(&server->seat, event->time_msec); return; } /* Handle _press_ on a layer surface */ -// if (!view && surface) { -// if (!wlr_surface_is_layer_surface(surface)) { -// return; -// } -// struct wlr_layer_surface_v1 *layer = -// wlr_layer_surface_v1_from_wlr_surface(surface); -// if (layer->current.keyboard_interactive) { -// seat_set_focus_layer(&server->seat, layer); -// } -// wlr_seat_pointer_notify_button(seat->seat, event->time_msec, -// event->button, event->state); -// return; -// } + if (view_area == LAB_SSD_LAYER_SURFACE && surface) { + if (!wlr_surface_is_layer_surface(surface)) { + return; + } + struct wlr_layer_surface_v1 *layer = + wlr_layer_surface_v1_from_wlr_surface(surface); + if (layer->current.keyboard_interactive) { + seat_set_focus_layer(&server->seat, layer); + } + wlr_seat_pointer_notify_button(seat->seat, event->time_msec, + event->button, event->state); + return; + } /* Handle _press_ on root window */ if (!view) { @@ -704,7 +718,7 @@ cursor_axis(struct wl_listener *listener, void *data) wlr_idle_notify_activity(seat->wlr_idle, seat->seat); /* Notify the client with pointer focus of the axis event. */ -// cursor_rebase(seat, event->time_msec); + cursor_rebase(seat, event->time_msec); wlr_seat_pointer_notify_axis(seat->seat, event->time_msec, event->orientation, event->delta, event->delta_discrete, event->source); diff --git a/src/desktop.c b/src/desktop.c index 19881f18..7b6afa0a 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -10,6 +10,7 @@ move_to_front(struct view *view) { wl_list_remove(&view->link); wl_list_insert(&view->server->views, &view->link); + wlr_scene_node_raise_to_top(&view->scene_tree->node); } #if HAVE_XWAYLAND @@ -256,32 +257,57 @@ desktop_focus_topmost_mapped_view(struct server *server) } struct view * -desktop_surface_and_view_at(struct server *server, double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy, +desktop_node_and_view_at(struct server *server, double lx, double ly, + struct wlr_scene_node **scene_node, double *sx, double *sy, enum ssd_part_type *view_area) { struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->node, lx, ly, sx, sy); - if (!node || node->type != WLR_SCENE_NODE_SURFACE) { + *scene_node = node; + if (!node) { + *view_area = LAB_SSD_NONE; return NULL; } - *surface = wlr_scene_surface_from_node(node)->surface; + if (node->type == WLR_SCENE_NODE_SURFACE) { + struct wlr_surface *surface = + wlr_scene_surface_from_node(node)->surface; + if (wlr_surface_is_layer_surface(surface)) { + *view_area = LAB_SSD_LAYER_SURFACE; + return NULL; + } + *view_area = LAB_SSD_CLIENT; + } else { + /* TODO: remove */ + *view_area = LAB_SSD_NONE; + } + struct wlr_scene_node *osd = &server->osd_tree->node; while (node && !node->data) { + if (node == osd) { + *view_area = LAB_SSD_OSD; + return NULL; + } + /* TODO: node == &server->menu_tree->node */ node = node->parent; } - assert(node); - return node->data; + if (!node) { + wlr_log(WLR_ERROR, "Unknown node detected"); + *view_area = LAB_SSD_NONE; + return NULL; + } + struct view *view = node->data; + /* TODO: *view_area = ssd_get_type(view, node) */ + return view; } struct view * desktop_view_at_cursor(struct server *server) { double sx, sy; - struct wlr_surface *surface; + struct wlr_scene_node *node; enum ssd_part_type view_area = LAB_SSD_NONE; - return desktop_surface_and_view_at(server, + return desktop_node_and_view_at(server, server->seat.cursor->x, server->seat.cursor->y, - &surface, &sx, &sy, &view_area); + &node, &sx, &sy, &view_area); } diff --git a/src/view.c b/src/view.c index 9379cdf7..34c04fca 100644 --- a/src/view.c +++ b/src/view.c @@ -31,7 +31,7 @@ view_move(struct view *view, double x, double y) view->impl->move(view, x, y); } view_discover_output(view); - wlr_scene_node_set_position(view->scene_node, view->x, view->y); + wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); } void @@ -45,7 +45,7 @@ view_move_resize(struct view *view, struct wlr_box geo) } ssd_update_title(view); view_discover_output(view); - wlr_scene_node_set_position(view->scene_node, view->x, view->y); + wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); } #define MIN_VIEW_WIDTH (100) @@ -147,7 +147,7 @@ view_center(struct view *view) if (view_compute_centered_position(view, view->w, view->h, &x, &y)) { view_move(view, x, y); } - wlr_scene_node_set_position(view->scene_node, view->x, view->y); + wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); } static void @@ -223,7 +223,7 @@ view_maximize(struct view *view, bool maximize) if (view->fullscreen) { return; } - wlr_scene_node_set_position(view->scene_node, view->x, view->y); + wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); if (view->impl->maximize) { view->impl->maximize(view, maximize); } diff --git a/src/xdg.c b/src/xdg.c index c3a8b0af..fc78c6b5 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -86,7 +86,11 @@ handle_destroy(struct wl_listener *listener, void *data) interactive_end(view); wl_list_remove(&view->link); wl_list_remove(&view->destroy.link); - ssd_destroy(view); + if (view->scene_tree) { + ssd_destroy(view); + wlr_scene_node_destroy(&view->scene_tree->node); + view->scene_tree = NULL; + } free(view); } @@ -388,13 +392,17 @@ xdg_surface_new(struct wl_listener *listener, void *data) view->xdg_surface = xdg_surface; wl_list_init(&view->ssd.parts); + view->scene_tree = wlr_scene_tree_create(&view->server->view_tree->node); view->scene_node = wlr_scene_xdg_surface_create( - &view->server->view_tree->node, view->xdg_surface); + &view->scene_tree->node, view->xdg_surface); if (!view->scene_node) { + wlr_scene_node_destroy(&view->scene_tree->node); + view->scene_tree = NULL; wl_resource_post_no_memory(view->surface->resource); + /* TODO: should we free(view) here? */ return; } - view->scene_node->data = view; + view->scene_tree->node.data = view; /* In support of xdg_toplevel_decoration */ xdg_surface->data = view; diff --git a/src/xwayland.c b/src/xwayland.c index 29475148..c72fe471 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -90,7 +90,11 @@ handle_destroy(struct wl_listener *listener, void *data) wl_list_remove(&view->request_configure.link); wl_list_remove(&view->request_maximize.link); wl_list_remove(&view->request_fullscreen.link); - ssd_destroy(view); + if (view->scene_tree) { + ssd_destroy(view); + wlr_scene_node_destroy(&view->scene_tree->node); + view->scene_tree = NULL; + } free(view); } @@ -256,13 +260,17 @@ map(struct view *view) } view->surface = view->xwayland_surface->surface; + view->scene_tree = wlr_scene_tree_create(&view->server->view_tree->node); view->scene_node = wlr_scene_subsurface_tree_create( - &view->server->view_tree->node, view->surface); + &view->scene_tree->node, view->surface); if (!view->scene_node) { + wlr_scene_node_destroy(&view->scene_tree->node); + view->scene_tree = NULL; wl_resource_post_no_memory(view->surface->resource); + /* TODO: should we free(view) here? */ return; } - view->scene_node->data = view; + view->scene_tree->node.data = view; view->ssd.enabled = want_deco(view);