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

view: unconditionally center views in output layout #278

Open
wants to merge 2 commits 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
47 changes: 16 additions & 31 deletions view.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,36 +52,11 @@ view_activate(struct cg_view *view, bool activate)
view->impl->activate(view, activate);
}

static bool
static inline bool
view_extends_output_layout(struct cg_view *view, struct wlr_box *layout_box)
{
int width, height;
view->impl->get_geometry(view, &width, &height);

return (layout_box->height < height || layout_box->width < width);
}

static void
view_maximize(struct cg_view *view, struct wlr_box *layout_box)
{
view->lx = layout_box->x;
view->ly = layout_box->y;

wlr_scene_node_set_position(&view->scene_tree->node, view->lx, view->ly);

view->impl->maximize(view, layout_box->width, layout_box->height);
}

static void
view_center(struct cg_view *view, struct wlr_box *layout_box)
{
int width, height;
view->impl->get_geometry(view, &width, &height);

view->lx = (layout_box->width - width) / 2;
view->ly = (layout_box->height - height) / 2;

wlr_scene_node_set_position(&view->scene_tree->node, view->lx, view->ly);
// View width and height are expected to be set before calling this function
return (layout_box->height < view->height || layout_box->width < view->width);
}

void
Expand All @@ -90,10 +65,20 @@ view_position(struct cg_view *view)
struct wlr_box layout_box;
wlr_output_layout_get_box(view->server->output_layout, NULL, &layout_box);

struct wlr_box view_box;
view->impl->get_geometry(view, &view_box);

// If view dimensions are not the same as output layout ones, it will be centered first
// Do not forget to adjust position according to top left corner declared in view geometry
view->lx = layout_box.x + (layout_box.width - view_box.width) / 2 - view_box.x;
view->ly = layout_box.y + (layout_box.height - view_box.height) / 2 - view_box.y;
view->width = view_box.width;
view->height = view_box.height;

wlr_scene_node_set_position(&view->scene_tree->node, view->lx, view->ly);

if (view_is_primary(view) || view_extends_output_layout(view, &layout_box)) {
view_maximize(view, &layout_box);
} else {
view_center(view, &layout_box);
view->impl->maximize(view, layout_box.width, layout_box.height);
}
}

Expand Down
3 changes: 2 additions & 1 deletion view.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ struct cg_view {

/* The view has a position in layout coordinates. */
int lx, ly;
int width, height;

enum cg_view_type type;
const struct cg_view_impl *impl;
};

struct cg_view_impl {
char *(*get_title)(struct cg_view *view);
void (*get_geometry)(struct cg_view *view, int *width_out, int *height_out);
void (*get_geometry)(struct cg_view *view, struct wlr_box *view_box);
bool (*is_primary)(struct cg_view *view);
bool (*is_transient_for)(struct cg_view *child, struct cg_view *parent);
void (*activate)(struct cg_view *view, bool activate);
Expand Down
27 changes: 21 additions & 6 deletions xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,10 @@ get_title(struct cg_view *view)
}

static void
get_geometry(struct cg_view *view, int *width_out, int *height_out)
get_geometry(struct cg_view *view, struct wlr_box *view_box)
{
struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
struct wlr_box geom;

wlr_xdg_surface_get_geometry(xdg_shell_view->xdg_toplevel->base, &geom);
*width_out = geom.width;
*height_out = geom.height;
wlr_xdg_surface_get_geometry(xdg_shell_view->xdg_toplevel->base, view_box);
}

static bool
Expand Down Expand Up @@ -183,15 +179,34 @@ handle_xdg_shell_surface_unmap(struct wl_listener *listener, void *data)
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, unmap);
struct cg_view *view = &xdg_shell_view->view;

wl_list_remove(&xdg_shell_view->commit.link);

view_unmap(view);
}

static void
handle_xdg_shell_surface_commit(struct wl_listener *listener, void *data)
{
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, commit);
struct cg_view *view = &xdg_shell_view->view;

// Check if view dimensions have changed
struct wlr_box view_box;
get_geometry(view, &view_box);
if (view_box.width != view->width || view_box.height != view->height) {
view_position(view);
}
}

static void
handle_xdg_shell_surface_map(struct wl_listener *listener, void *data)
{
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, map);
struct cg_view *view = &xdg_shell_view->view;

xdg_shell_view->commit.notify = handle_xdg_shell_surface_commit;
wl_signal_add(&xdg_shell_view->xdg_toplevel->base->surface->events.commit, &xdg_shell_view->commit);

view_map(view, xdg_shell_view->xdg_toplevel->base->surface);
}

Expand Down
1 change: 1 addition & 0 deletions xdg_shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct cg_xdg_shell_view {
struct wl_listener unmap;
struct wl_listener map;
struct wl_listener request_fullscreen;
struct wl_listener commit;
};

struct cg_xdg_decoration {
Expand Down
14 changes: 9 additions & 5 deletions xwayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,22 @@ get_title(struct cg_view *view)
}

static void
get_geometry(struct cg_view *view, int *width_out, int *height_out)
get_geometry(struct cg_view *view, struct wlr_box *view_box)
{
struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view);
struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface;

view_box->x = 0;
view_box->y = 0;

if (xsurface->surface == NULL) {
*width_out = 0;
*height_out = 0;
view_box->width = 0;
view_box->height = 0;
return;
}

*width_out = xsurface->surface->current.width;
*height_out = xsurface->surface->current.height;
view_box->width = xwayland_view->xwayland_surface->surface->current.width;
view_box->height = xwayland_view->xwayland_surface->surface->current.height;
}

static bool
Expand Down
Loading