Skip to content

Commit 4925882

Browse files
kennylevinsenRedSoxFan
authored andcommitted
Use parent get_root_coords in subsurfaces
Subsurfaces need access to the parent get_root_coords impl for positioning in popups. To do this, we store a reference to the parent view_child where applicable. Fixes #4191.
1 parent c3532bc commit 4925882

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

include/sway/tree/view.h

+3
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,11 @@ struct sway_view_child_impl {
192192
*/
193193
struct sway_view_child {
194194
const struct sway_view_child_impl *impl;
195+
struct wl_list link;
195196

196197
struct sway_view *view;
198+
struct sway_view_child *parent;
199+
struct wl_list children; // sway_view_child::link
197200
struct wlr_surface *surface;
198201
bool mapped;
199202

sway/tree/view.c

+51-9
Original file line numberDiff line numberDiff line change
@@ -728,15 +728,23 @@ static void subsurface_get_root_coords(struct sway_view_child *child,
728728
*root_sx = -child->view->geometry.x;
729729
*root_sy = -child->view->geometry.y;
730730

731-
while (surface && wlr_surface_is_subsurface(surface)) {
732-
struct wlr_subsurface *subsurface =
733-
wlr_subsurface_from_wlr_surface(surface);
734-
if (subsurface == NULL) {
735-
break;
731+
if (child->parent && child->parent->impl &&
732+
child->parent->impl->get_root_coords) {
733+
int sx, sy;
734+
child->parent->impl->get_root_coords(child->parent, &sx, &sy);
735+
*root_sx += sx;
736+
*root_sy += sy;
737+
} else {
738+
while (surface && wlr_surface_is_subsurface(surface)) {
739+
struct wlr_subsurface *subsurface =
740+
wlr_subsurface_from_wlr_surface(surface);
741+
if (subsurface == NULL) {
742+
break;
743+
}
744+
*root_sx += subsurface->current.x;
745+
*root_sy += subsurface->current.y;
746+
surface = subsurface->parent;
736747
}
737-
*root_sx += subsurface->current.x;
738-
*root_sy += subsurface->current.y;
739-
surface = subsurface->parent;
740748
}
741749
}
742750

@@ -780,6 +788,28 @@ static void view_subsurface_create(struct sway_view *view,
780788
subsurface->destroy.notify = subsurface_handle_destroy;
781789

782790
subsurface->child.mapped = true;
791+
792+
view_child_damage(&subsurface->child, true);
793+
}
794+
795+
static void view_child_subsurface_create(struct sway_view_child *child,
796+
struct wlr_subsurface *wlr_subsurface) {
797+
struct sway_subsurface *subsurface =
798+
calloc(1, sizeof(struct sway_subsurface));
799+
if (subsurface == NULL) {
800+
sway_log(SWAY_ERROR, "Allocation failed");
801+
return;
802+
}
803+
subsurface->child.parent = child;
804+
wl_list_insert(&child->children, &subsurface->child.link);
805+
view_child_init(&subsurface->child, &subsurface_impl, child->view,
806+
wlr_subsurface->surface);
807+
808+
wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
809+
subsurface->destroy.notify = subsurface_handle_destroy;
810+
811+
subsurface->child.mapped = true;
812+
783813
view_child_damage(&subsurface->child, true);
784814
}
785815

@@ -806,7 +836,7 @@ static void view_child_handle_surface_new_subsurface(
806836
struct sway_view_child *child =
807837
wl_container_of(listener, child, surface_new_subsurface);
808838
struct wlr_subsurface *subsurface = data;
809-
view_subsurface_create(child->view, subsurface);
839+
view_child_subsurface_create(child, subsurface);
810840
}
811841

812842
static void view_child_handle_surface_destroy(struct wl_listener *listener,
@@ -854,6 +884,7 @@ void view_child_init(struct sway_view_child *child,
854884
child->impl = impl;
855885
child->view = view;
856886
child->surface = surface;
887+
wl_list_init(&child->children);
857888

858889
wl_signal_add(&surface->events.commit, &child->surface_commit);
859890
child->surface_commit.notify = view_child_handle_surface_commit;
@@ -882,6 +913,17 @@ void view_child_destroy(struct sway_view_child *child) {
882913
view_child_damage(child, true);
883914
}
884915

916+
if (child->parent != NULL) {
917+
wl_list_remove(&child->link);
918+
child->parent = NULL;
919+
}
920+
921+
struct sway_view_child *subchild, *tmpchild;
922+
wl_list_for_each_safe(subchild, tmpchild, &child->children, link) {
923+
wl_list_remove(&subchild->link);
924+
subchild->parent = NULL;
925+
}
926+
885927
wl_list_remove(&child->surface_commit.link);
886928
wl_list_remove(&child->surface_destroy.link);
887929
wl_list_remove(&child->view_unmap.link);

0 commit comments

Comments
 (0)