struct desktop_shell *shell;
+ struct wl_list children_list;
+ struct wl_list children_link;
+
int32_t saved_x, saved_y;
bool saved_position_valid;
bool saved_rotation_valid;
wl_list_init(&shsurf->workspace_transform.link);
+ /*
+ * initialize list as well as link. The latter allows to use
+ * wl_list_remove() even when this surface is not in another list.
+ */
+ wl_list_init(&shsurf->children_list);
+ wl_list_init(&shsurf->children_link);
+
weston_desktop_surface_set_user_data(desktop_surface, shsurf);
weston_desktop_surface_set_activated(desktop_surface,
shsurf->focus_count > 0);
{
struct shell_surface *shsurf =
weston_desktop_surface_get_user_data(desktop_surface);
+ struct shell_surface *shsurf_child, *tmp;
struct weston_surface *surface =
weston_desktop_surface_get_surface(desktop_surface);
if (!shsurf)
return;
+ wl_list_for_each_safe(shsurf_child, tmp, &shsurf->children_list, children_link) {
+ wl_list_remove(&shsurf_child->children_link);
+ wl_list_init(&shsurf_child->children_link);
+ }
+ wl_list_remove(&shsurf->children_link);
+
wl_signal_emit(&shsurf->destroy_signal, shsurf);
if (shsurf->fullscreen.black_view)
wl_resource_post_no_memory(resource);
}
+static void
+desktop_surface_set_parent(struct weston_desktop_surface *desktop_surface,
+ struct weston_desktop_surface *parent,
+ void *shell)
+{
+ struct shell_surface *shsurf =
+ weston_desktop_surface_get_user_data(desktop_surface);
+ struct shell_surface *shsurf_parent =
+ weston_desktop_surface_get_user_data(parent);
+
+ wl_list_insert(shsurf_parent->children_list.prev,
+ &shsurf->children_link);
+}
+
static void
desktop_surface_fullscreen_requested(struct weston_desktop_surface *desktop_surface,
bool fullscreen,
.committed = desktop_surface_committed,
.move = desktop_surface_move,
.resize = desktop_surface_resize,
+ .set_parent = desktop_surface_set_parent,
.fullscreen_requested = desktop_surface_fullscreen_requested,
.maximized_requested = desktop_surface_maximized_requested,
.minimized_requested = desktop_surface_minimized_requested,
}
}
+static struct shell_surface *get_last_child(struct shell_surface *shsurf)
+{
+ struct shell_surface *shsurf_child;
+
+ wl_list_for_each_reverse(shsurf_child, &shsurf->children_list, children_link) {
+ if (weston_view_is_mapped(shsurf_child->view))
+ return shsurf_child;
+ }
+
+ return NULL;
+}
+
void
activate(struct desktop_shell *shell, struct weston_view *view,
struct weston_seat *seat, uint32_t flags)
struct focus_state *state;
struct workspace *ws;
struct weston_surface *old_es;
- struct shell_surface *shsurf;
+ struct shell_surface *shsurf, *shsurf_child;
main_surface = weston_surface_get_main_surface(es);
shsurf = get_shell_surface(main_surface);
assert(shsurf);
+ shsurf_child = get_last_child(shsurf);
+ if (shsurf_child) {
+ /* Activate last xdg child instead of parent. */
+ activate(shell, shsurf_child->view, seat, flags);
+ return;
+ }
+
/* Only demote fullscreen surfaces on the output of activated shsurf.
* Leave fullscreen surfaces on unrelated outputs alone. */
if (shsurf->output)