mirror of
https://github.com/swaywm/sway.git
synced 2024-11-14 14:34:07 +01:00
Merge fbf5887160
into 4cfcb3643b
This commit is contained in:
commit
c172987159
@ -284,7 +284,21 @@ void view_destroy(struct sway_view *view);
|
|||||||
void view_begin_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`
|
* `fullscreen` should be set to true (and optionally `fullscreen_output`
|
||||||
* should be populated) if the view should be made fullscreen immediately.
|
* should be populated) if the view should be made fullscreen immediately.
|
||||||
@ -292,7 +306,7 @@ void view_begin_destroy(struct sway_view *view);
|
|||||||
* `decoration` should be set to true if the client prefers CSD. The client's
|
* `decoration` should be set to true if the client prefers CSD. The client's
|
||||||
* preference may be ignored.
|
* 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);
|
bool fullscreen, struct wlr_output *fullscreen_output, bool decoration);
|
||||||
|
|
||||||
void view_unmap(struct sway_view *view);
|
void view_unmap(struct sway_view *view);
|
||||||
|
@ -277,6 +277,20 @@ static const struct sway_view_impl view_impl = {
|
|||||||
.destroy = destroy,
|
.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) {
|
static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xdg_shell_view *xdg_shell_view =
|
struct sway_xdg_shell_view *xdg_shell_view =
|
||||||
wl_container_of(listener, xdg_shell_view, commit);
|
wl_container_of(listener, xdg_shell_view, commit);
|
||||||
@ -287,10 +301,14 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
|||||||
if (view->xdg_decoration != NULL) {
|
if (view->xdg_decoration != NULL) {
|
||||||
set_xdg_decoration_mode(view->xdg_decoration);
|
set_xdg_decoration_mode(view->xdg_decoration);
|
||||||
}
|
}
|
||||||
// XXX: https://github.com/swaywm/sway/issues/2176
|
|
||||||
wlr_xdg_surface_schedule_configure(xdg_surface);
|
wlr_xdg_surface_schedule_configure(xdg_surface);
|
||||||
wlr_xdg_toplevel_set_wm_capabilities(view->wlr_xdg_toplevel,
|
wlr_xdg_toplevel_set_wm_capabilities(view->wlr_xdg_toplevel,
|
||||||
XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
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()
|
// TODO: wlr_xdg_toplevel_set_bounds()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -465,23 +483,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||||||
view->natural_width = toplevel->base->geometry.width;
|
view->natural_width = toplevel->base->geometry.width;
|
||||||
view->natural_height = toplevel->base->geometry.height;
|
view->natural_height = toplevel->base->geometry.height;
|
||||||
|
|
||||||
bool csd = false;
|
view_setup(view, toplevel->base->surface, false, NULL, view_wants_csd(view));
|
||||||
|
view_map(view, toplevel->base->surface);
|
||||||
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);
|
|
||||||
|
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
|
|
||||||
@ -518,7 +521,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
|||||||
struct sway_xdg_shell_view *xdg_shell_view =
|
struct sway_xdg_shell_view *xdg_shell_view =
|
||||||
wl_container_of(listener, xdg_shell_view, destroy);
|
wl_container_of(listener, xdg_shell_view, destroy);
|
||||||
struct sway_view *view = &xdg_shell_view->view;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
wl_list_remove(&xdg_shell_view->destroy.link);
|
wl_list_remove(&xdg_shell_view->destroy.link);
|
||||||
|
@ -526,7 +526,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
|||||||
xwayland_view->commit.notify = handle_commit;
|
xwayland_view->commit.notify = handle_commit;
|
||||||
|
|
||||||
// Put it back into the tree
|
// 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->surface_tree = wlr_scene_subsurface_tree_create(
|
||||||
xwayland_view->view.content_tree, xsurface->surface);
|
xwayland_view->view.content_tree, xsurface->surface);
|
||||||
|
@ -711,12 +711,23 @@ static void handle_foreign_destroy(
|
|||||||
wl_list_remove(&view->foreign_destroy.link);
|
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 fullscreen, struct wlr_output *fullscreen_output,
|
||||||
bool decoration) {
|
bool decoration) {
|
||||||
if (!sway_assert(view->surface == NULL, "cannot map mapped view")) {
|
if (view->surface) {
|
||||||
|
// Setup has already already completed
|
||||||
return;
|
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->surface = wlr_surface;
|
||||||
view_populate_pid(view);
|
view_populate_pid(view);
|
||||||
view->container = container_create(view);
|
view->container = container_create(view);
|
||||||
@ -843,6 +854,24 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
|||||||
|
|
||||||
view_execute_criteria(view);
|
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);
|
bool set_focus = should_focus(view);
|
||||||
|
|
||||||
#if WLR_HAS_XWAYLAND
|
#if WLR_HAS_XWAYLAND
|
||||||
@ -856,18 +885,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
|||||||
if (set_focus) {
|
if (set_focus) {
|
||||||
input_manager_set_focus(&view->container->node);
|
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) {
|
void view_unmap(struct sway_view *view) {
|
||||||
|
Loading…
Reference in New Issue
Block a user