Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tree/view: Send configure before mapping #8314

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions include/sway/tree/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,29 @@ void view_destroy(struct sway_view *view);
void view_begin_destroy(struct sway_view *view);

/**
* Map a view, ie. make it visible in the tree.
* Perform post-map setup like updating focus. view_setup must be called before
* calling view_map.
*/
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface);

/**
* Prepare the view for its upcoming mapping, sending the intended dimensions
* so that the first frame has a chance of being correct. If CSD preferences or
* floating tendency changes, this may turn out to be inaccurate but no worse
* than skipping the step.
*
* This may bail early for some views if the surface is not mapped, in which
* case it should be called again before view_map once the surface is mapped.
* It is safe to call view_setup adancegain even if the first call before
* surface map succeeded.
*
* `fullscreen` should be set to true (and optionally `fullscreen_output`
* should be populated) if the view should be made fullscreen immediately.
*
* `decoration` should be set to true if the client prefers CSD. The client's
* preference may be ignored.
*/
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
void view_setup(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, struct wlr_output *fullscreen_output, bool decoration);

void view_unmap(struct sway_view *view);
Expand Down
42 changes: 23 additions & 19 deletions sway/desktop/xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,20 @@ static const struct sway_view_impl view_impl = {
.destroy = destroy,
};

static bool view_wants_csd(struct sway_view *view) {
struct wlr_xdg_toplevel *toplevel = view->wlr_xdg_toplevel;
struct wlr_xdg_surface *xdg_surface = toplevel->base;
if (view->xdg_decoration) {
enum wlr_xdg_toplevel_decoration_v1_mode mode =
view->xdg_decoration->wlr_xdg_decoration->requested_mode;
return mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
}
struct sway_server_decoration *deco =
decoration_from_surface(xdg_surface->surface);
return !deco || deco->wlr_server_decoration->mode ==
WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT;
}

static void handle_commit(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, commit);
Expand All @@ -287,10 +301,14 @@ static void handle_commit(struct wl_listener *listener, void *data) {
if (view->xdg_decoration != NULL) {
set_xdg_decoration_mode(view->xdg_decoration);
}
// XXX: https://github.com/swaywm/sway/issues/2176

wlr_xdg_surface_schedule_configure(xdg_surface);
wlr_xdg_toplevel_set_wm_capabilities(view->wlr_xdg_toplevel,
XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
view_setup(&xdg_shell_view->view, xdg_surface->surface, false, NULL,
view_wants_csd(&xdg_shell_view->view));
transaction_commit_dirty();

// TODO: wlr_xdg_toplevel_set_bounds()
return;
}
Expand Down Expand Up @@ -465,23 +483,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
view->natural_width = toplevel->base->geometry.width;
view->natural_height = toplevel->base->geometry.height;

bool csd = false;

if (view->xdg_decoration) {
enum wlr_xdg_toplevel_decoration_v1_mode mode =
view->xdg_decoration->wlr_xdg_decoration->requested_mode;
csd = mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
} else {
struct sway_server_decoration *deco =
decoration_from_surface(toplevel->base->surface);
csd = !deco || deco->wlr_server_decoration->mode ==
WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT;
}

view_map(view, toplevel->base->surface,
toplevel->requested.fullscreen,
toplevel->requested.fullscreen_output,
csd);
view_setup(view, toplevel->base->surface, false, NULL, view_wants_csd(view));
view_map(view, toplevel->base->surface);

transaction_commit_dirty();

Expand Down Expand Up @@ -518,7 +521,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_xdg_shell_view *xdg_shell_view =
wl_container_of(listener, xdg_shell_view, destroy);
struct sway_view *view = &xdg_shell_view->view;
if (!sway_assert(view->surface == NULL, "Tried to destroy a mapped view")) {
if (!sway_assert(view->surface == NULL ||
!view->surface->mapped, "Tried to destroy a mapped view")) {
return;
}
wl_list_remove(&xdg_shell_view->destroy.link);
Expand Down
3 changes: 2 additions & 1 deletion sway/desktop/xwayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
xwayland_view->commit.notify = handle_commit;

// Put it back into the tree
view_map(view, xsurface->surface, xsurface->fullscreen, NULL, false);
view_setup(view, xsurface->surface, xsurface->fullscreen, NULL, false);
view_map(view, xsurface->surface);

xwayland_view->surface_tree = wlr_scene_subsurface_tree_create(
xwayland_view->view.content_tree, xsurface->surface);
Expand Down
45 changes: 31 additions & 14 deletions sway/tree/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,12 +714,23 @@ static void handle_foreign_destroy(
wl_list_remove(&view->foreign_destroy.link);
}

void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
void view_setup(struct sway_view *view, struct wlr_surface *wlr_surface,
bool fullscreen, struct wlr_output *fullscreen_output,
bool decoration) {
if (!sway_assert(view->surface == NULL, "cannot map mapped view")) {
if (view->surface) {
// Setup has already already completed
return;
}
if (!wlr_surface->mapped && view->impl->wants_floating &&
view->impl->wants_floating(view)) {
// Configuring floating containers before the surface is mapped lead to
// us accidentally sending the configured minimum dimensions, which we
// only want to send if the client comes up with unreasonably small
// dimensions. As a hack, just skip this scenario for now and have the
// caller call view_setup again after the surface has been mapped.
return;
}

view->surface = wlr_surface;
view_populate_pid(view);
view->container = container_create(view);
Expand Down Expand Up @@ -846,6 +857,24 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,

view_execute_criteria(view);

const char *app_id;
const char *class;
if ((app_id = view_get_app_id(view)) != NULL) {
wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel, app_id);
} else if ((class = view_get_class(view)) != NULL) {
wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel, class);
}

if (view->ext_foreign_toplevel) {
update_ext_foreign_toplevel(view);
}
}

void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
if (!sway_assert(view->surface != NULL, "cannot map view that has not been setup")) {
return;
}

bool set_focus = should_focus(view);

#if WLR_HAS_XWAYLAND
Expand All @@ -859,18 +888,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
if (set_focus) {
input_manager_set_focus(&view->container->node);
}

if (view->ext_foreign_toplevel) {
update_ext_foreign_toplevel(view);
}

const char *app_id;
const char *class;
if ((app_id = view_get_app_id(view)) != NULL) {
wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel, app_id);
} else if ((class = view_get_class(view)) != NULL) {
wlr_foreign_toplevel_handle_v1_set_app_id(view->foreign_toplevel, class);
}
}

void view_unmap(struct sway_view *view) {
Expand Down