diff options
author | Alexander Orzechowski <alex@ozal.ski> | 2023-12-06 14:28:59 -0500 |
---|---|---|
committer | Kirill Primak <vyivel@eclair.cafe> | 2024-01-18 18:36:54 +0300 |
commit | b38ed8b4792928dca3e1580e8160792ea41e25c4 (patch) | |
tree | b080710c7a3f37de868ff4d5d96e6971f7105675 /sway/tree/view.c | |
parent | transaction: ready signals will return success bools (diff) | |
download | sway-b38ed8b4792928dca3e1580e8160792ea41e25c4.tar.gz sway-b38ed8b4792928dca3e1580e8160792ea41e25c4.tar.zst sway-b38ed8b4792928dca3e1580e8160792ea41e25c4.zip |
scene_graph: Port xdg_shell
Diffstat (limited to 'sway/tree/view.c')
-rw-r--r-- | sway/tree/view.c | 272 |
1 files changed, 0 insertions, 272 deletions
diff --git a/sway/tree/view.c b/sway/tree/view.c index 7af2fd3f..ee25faf1 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -488,24 +488,6 @@ void view_for_each_popup_surface(struct sway_view *view, | |||
488 | view->impl->for_each_popup_surface(view, iterator, user_data); | 488 | view->impl->for_each_popup_surface(view, iterator, user_data); |
489 | } | 489 | } |
490 | } | 490 | } |
491 | |||
492 | static void view_subsurface_create(struct sway_view *view, | ||
493 | struct wlr_subsurface *subsurface); | ||
494 | |||
495 | static void view_init_subsurfaces(struct sway_view *view, | ||
496 | struct wlr_surface *surface); | ||
497 | |||
498 | static void view_child_init_subsurfaces(struct sway_view_child *view_child, | ||
499 | struct wlr_surface *surface); | ||
500 | |||
501 | static void view_handle_surface_new_subsurface(struct wl_listener *listener, | ||
502 | void *data) { | ||
503 | struct sway_view *view = | ||
504 | wl_container_of(listener, view, surface_new_subsurface); | ||
505 | struct wlr_subsurface *subsurface = data; | ||
506 | view_subsurface_create(view, subsurface); | ||
507 | } | ||
508 | |||
509 | static bool view_has_executed_criteria(struct sway_view *view, | 491 | static bool view_has_executed_criteria(struct sway_view *view, |
510 | struct criteria *criteria) { | 492 | struct criteria *criteria) { |
511 | for (int i = 0; i < view->executed_criteria->length; ++i) { | 493 | for (int i = 0; i < view->executed_criteria->length; ++i) { |
@@ -826,11 +808,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | |||
826 | } | 808 | } |
827 | ipc_event_window(view->container, "new"); | 809 | ipc_event_window(view->container, "new"); |
828 | 810 | ||
829 | view_init_subsurfaces(view, wlr_surface); | ||
830 | wl_signal_add(&wlr_surface->events.new_subsurface, | ||
831 | &view->surface_new_subsurface); | ||
832 | view->surface_new_subsurface.notify = view_handle_surface_new_subsurface; | ||
833 | |||
834 | if (decoration) { | 811 | if (decoration) { |
835 | view_update_csd_from_client(view, decoration); | 812 | view_update_csd_from_client(view, decoration); |
836 | } | 813 | } |
@@ -897,8 +874,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | |||
897 | void view_unmap(struct sway_view *view) { | 874 | void view_unmap(struct sway_view *view) { |
898 | wl_signal_emit_mutable(&view->events.unmap, view); | 875 | wl_signal_emit_mutable(&view->events.unmap, view); |
899 | 876 | ||
900 | wl_list_remove(&view->surface_new_subsurface.link); | ||
901 | |||
902 | view->executed_criteria->length = 0; | 877 | view->executed_criteria->length = 0; |
903 | 878 | ||
904 | if (view->urgent_timer) { | 879 | if (view->urgent_timer) { |
@@ -962,253 +937,6 @@ void view_center_surface(struct sway_view *view) { | |||
962 | (con->current.content_height - view->geometry.height) / 2); | 937 | (con->current.content_height - view->geometry.height) / 2); |
963 | } | 938 | } |
964 | 939 | ||
965 | static const struct sway_view_child_impl subsurface_impl; | ||
966 | |||
967 | static void subsurface_get_view_coords(struct sway_view_child *child, | ||
968 | int *sx, int *sy) { | ||
969 | struct wlr_surface *surface = child->surface; | ||
970 | if (child->parent && child->parent->impl && | ||
971 | child->parent->impl->get_view_coords) { | ||
972 | child->parent->impl->get_view_coords(child->parent, sx, sy); | ||
973 | } else { | ||
974 | *sx = *sy = 0; | ||
975 | } | ||
976 | struct wlr_subsurface *subsurface = | ||
977 | wlr_subsurface_try_from_wlr_surface(surface); | ||
978 | *sx += subsurface->current.x; | ||
979 | *sy += subsurface->current.y; | ||
980 | } | ||
981 | |||
982 | static void subsurface_destroy(struct sway_view_child *child) { | ||
983 | if (!sway_assert(child->impl == &subsurface_impl, | ||
984 | "Expected a subsurface")) { | ||
985 | return; | ||
986 | } | ||
987 | struct sway_subsurface *subsurface = (struct sway_subsurface *)child; | ||
988 | wl_list_remove(&subsurface->destroy.link); | ||
989 | free(subsurface); | ||
990 | } | ||
991 | |||
992 | static const struct sway_view_child_impl subsurface_impl = { | ||
993 | .get_view_coords = subsurface_get_view_coords, | ||
994 | .destroy = subsurface_destroy, | ||
995 | }; | ||
996 | |||
997 | static void subsurface_handle_destroy(struct wl_listener *listener, | ||
998 | void *data) { | ||
999 | struct sway_subsurface *subsurface = | ||
1000 | wl_container_of(listener, subsurface, destroy); | ||
1001 | struct sway_view_child *child = &subsurface->child; | ||
1002 | view_child_destroy(child); | ||
1003 | } | ||
1004 | |||
1005 | static void view_child_damage(struct sway_view_child *child, bool whole); | ||
1006 | |||
1007 | static void view_subsurface_create(struct sway_view *view, | ||
1008 | struct wlr_subsurface *wlr_subsurface) { | ||
1009 | struct sway_subsurface *subsurface = | ||
1010 | calloc(1, sizeof(struct sway_subsurface)); | ||
1011 | if (subsurface == NULL) { | ||
1012 | sway_log(SWAY_ERROR, "Allocation failed"); | ||
1013 | return; | ||
1014 | } | ||
1015 | view_child_init(&subsurface->child, &subsurface_impl, view, | ||
1016 | wlr_subsurface->surface); | ||
1017 | |||
1018 | wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); | ||
1019 | subsurface->destroy.notify = subsurface_handle_destroy; | ||
1020 | |||
1021 | subsurface->child.mapped = true; | ||
1022 | |||
1023 | view_child_damage(&subsurface->child, true); | ||
1024 | } | ||
1025 | |||
1026 | static void view_child_subsurface_create(struct sway_view_child *child, | ||
1027 | struct wlr_subsurface *wlr_subsurface) { | ||
1028 | struct sway_subsurface *subsurface = | ||
1029 | calloc(1, sizeof(struct sway_subsurface)); | ||
1030 | if (subsurface == NULL) { | ||
1031 | sway_log(SWAY_ERROR, "Allocation failed"); | ||
1032 | return; | ||
1033 | } | ||
1034 | subsurface->child.parent = child; | ||
1035 | wl_list_insert(&child->children, &subsurface->child.link); | ||
1036 | view_child_init(&subsurface->child, &subsurface_impl, child->view, | ||
1037 | wlr_subsurface->surface); | ||
1038 | |||
1039 | wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); | ||
1040 | subsurface->destroy.notify = subsurface_handle_destroy; | ||
1041 | |||
1042 | subsurface->child.mapped = true; | ||
1043 | |||
1044 | view_child_damage(&subsurface->child, true); | ||
1045 | } | ||
1046 | |||
1047 | static bool view_child_is_mapped(struct sway_view_child *child) { | ||
1048 | while (child) { | ||
1049 | if (!child->mapped) { | ||
1050 | return false; | ||
1051 | } | ||
1052 | child = child->parent; | ||
1053 | } | ||
1054 | return true; | ||
1055 | } | ||
1056 | |||
1057 | static void view_child_damage(struct sway_view_child *child, bool whole) { | ||
1058 | if (!child || !view_child_is_mapped(child) || !child->view || !child->view->container) { | ||
1059 | return; | ||
1060 | } | ||
1061 | int sx, sy; | ||
1062 | child->impl->get_view_coords(child, &sx, &sy); | ||
1063 | desktop_damage_surface(child->surface, | ||
1064 | child->view->container->pending.content_x - | ||
1065 | child->view->geometry.x + sx, | ||
1066 | child->view->container->pending.content_y - | ||
1067 | child->view->geometry.y + sy, whole); | ||
1068 | } | ||
1069 | |||
1070 | static void view_child_handle_surface_commit(struct wl_listener *listener, | ||
1071 | void *data) { | ||
1072 | struct sway_view_child *child = | ||
1073 | wl_container_of(listener, child, surface_commit); | ||
1074 | view_child_damage(child, false); | ||
1075 | } | ||
1076 | |||
1077 | static void view_child_handle_surface_new_subsurface( | ||
1078 | struct wl_listener *listener, void *data) { | ||
1079 | struct sway_view_child *child = | ||
1080 | wl_container_of(listener, child, surface_new_subsurface); | ||
1081 | struct wlr_subsurface *subsurface = data; | ||
1082 | view_child_subsurface_create(child, subsurface); | ||
1083 | } | ||
1084 | |||
1085 | static void view_child_handle_surface_destroy(struct wl_listener *listener, | ||
1086 | void *data) { | ||
1087 | struct sway_view_child *child = | ||
1088 | wl_container_of(listener, child, surface_destroy); | ||
1089 | view_child_destroy(child); | ||
1090 | } | ||
1091 | |||
1092 | static void view_init_subsurfaces(struct sway_view *view, | ||
1093 | struct wlr_surface *surface) { | ||
1094 | struct wlr_subsurface *subsurface; | ||
1095 | wl_list_for_each(subsurface, &surface->current.subsurfaces_below, | ||
1096 | current.link) { | ||
1097 | view_subsurface_create(view, subsurface); | ||
1098 | } | ||
1099 | wl_list_for_each(subsurface, &surface->current.subsurfaces_above, | ||
1100 | current.link) { | ||
1101 | view_subsurface_create(view, subsurface); | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | static void view_child_init_subsurfaces(struct sway_view_child *view_child, | ||
1106 | struct wlr_surface *surface) { | ||
1107 | struct wlr_subsurface *subsurface; | ||
1108 | wl_list_for_each(subsurface, &surface->current.subsurfaces_below, | ||
1109 | current.link) { | ||
1110 | view_child_subsurface_create(view_child, subsurface); | ||
1111 | } | ||
1112 | wl_list_for_each(subsurface, &surface->current.subsurfaces_above, | ||
1113 | current.link) { | ||
1114 | view_child_subsurface_create(view_child, subsurface); | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | static void view_child_handle_surface_map(struct wl_listener *listener, | ||
1119 | void *data) { | ||
1120 | struct sway_view_child *child = | ||
1121 | wl_container_of(listener, child, surface_map); | ||
1122 | child->mapped = true; | ||
1123 | view_child_damage(child, true); | ||
1124 | } | ||
1125 | |||
1126 | static void view_child_handle_surface_unmap(struct wl_listener *listener, | ||
1127 | void *data) { | ||
1128 | struct sway_view_child *child = | ||
1129 | wl_container_of(listener, child, surface_unmap); | ||
1130 | view_child_damage(child, true); | ||
1131 | child->mapped = false; | ||
1132 | } | ||
1133 | |||
1134 | static void view_child_handle_view_unmap(struct wl_listener *listener, | ||
1135 | void *data) { | ||
1136 | struct sway_view_child *child = | ||
1137 | wl_container_of(listener, child, view_unmap); | ||
1138 | view_child_damage(child, true); | ||
1139 | child->mapped = false; | ||
1140 | } | ||
1141 | |||
1142 | void view_child_init(struct sway_view_child *child, | ||
1143 | const struct sway_view_child_impl *impl, struct sway_view *view, | ||
1144 | struct wlr_surface *surface) { | ||
1145 | child->impl = impl; | ||
1146 | child->view = view; | ||
1147 | child->surface = surface; | ||
1148 | wl_list_init(&child->children); | ||
1149 | |||
1150 | wl_signal_add(&surface->events.commit, &child->surface_commit); | ||
1151 | child->surface_commit.notify = view_child_handle_surface_commit; | ||
1152 | wl_signal_add(&surface->events.new_subsurface, | ||
1153 | &child->surface_new_subsurface); | ||
1154 | child->surface_new_subsurface.notify = | ||
1155 | view_child_handle_surface_new_subsurface; | ||
1156 | wl_signal_add(&surface->events.destroy, &child->surface_destroy); | ||
1157 | child->surface_destroy.notify = view_child_handle_surface_destroy; | ||
1158 | |||
1159 | // Not all child views have a map/unmap event | ||
1160 | child->surface_map.notify = view_child_handle_surface_map; | ||
1161 | wl_list_init(&child->surface_map.link); | ||
1162 | child->surface_unmap.notify = view_child_handle_surface_unmap; | ||
1163 | wl_list_init(&child->surface_unmap.link); | ||
1164 | |||
1165 | wl_signal_add(&view->events.unmap, &child->view_unmap); | ||
1166 | child->view_unmap.notify = view_child_handle_view_unmap; | ||
1167 | |||
1168 | struct sway_container *container = child->view->container; | ||
1169 | if (container != NULL) { | ||
1170 | struct sway_workspace *workspace = container->pending.workspace; | ||
1171 | if (workspace) { | ||
1172 | surface_enter_output(child->surface, workspace->output); | ||
1173 | } | ||
1174 | } | ||
1175 | |||
1176 | view_child_init_subsurfaces(child, surface); | ||
1177 | } | ||
1178 | |||
1179 | void view_child_destroy(struct sway_view_child *child) { | ||
1180 | if (view_child_is_mapped(child) && child->view->container != NULL) { | ||
1181 | view_child_damage(child, true); | ||
1182 | } | ||
1183 | |||
1184 | if (child->parent != NULL) { | ||
1185 | wl_list_remove(&child->link); | ||
1186 | child->parent = NULL; | ||
1187 | } | ||
1188 | |||
1189 | struct sway_view_child *subchild, *tmpchild; | ||
1190 | wl_list_for_each_safe(subchild, tmpchild, &child->children, link) { | ||
1191 | wl_list_remove(&subchild->link); | ||
1192 | subchild->parent = NULL; | ||
1193 | // The subchild lost its parent link, so it cannot see that the parent | ||
1194 | // is unmapped. Unmap it directly. | ||
1195 | subchild->mapped = false; | ||
1196 | } | ||
1197 | |||
1198 | wl_list_remove(&child->surface_commit.link); | ||
1199 | wl_list_remove(&child->surface_destroy.link); | ||
1200 | wl_list_remove(&child->surface_map.link); | ||
1201 | wl_list_remove(&child->surface_unmap.link); | ||
1202 | wl_list_remove(&child->view_unmap.link); | ||
1203 | wl_list_remove(&child->surface_new_subsurface.link); | ||
1204 | |||
1205 | if (child->impl && child->impl->destroy) { | ||
1206 | child->impl->destroy(child); | ||
1207 | } else { | ||
1208 | free(child); | ||
1209 | } | ||
1210 | } | ||
1211 | |||
1212 | struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) { | 940 | struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) { |
1213 | struct wlr_xdg_surface *xdg_surface; | 941 | struct wlr_xdg_surface *xdg_surface; |
1214 | if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface))) { | 942 | if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface))) { |