view: Use wlr_box for current/pending geometry

This commit is contained in:
John Lindgren 2023-02-08 23:19:14 -05:00
parent 3941991505
commit b75dbd5b38
15 changed files with 169 additions and 186 deletions

View file

@ -2,6 +2,7 @@
#ifndef __LABWC_SSD_INTERNAL_H #ifndef __LABWC_SSD_INTERNAL_H
#define __LABWC_SSD_INTERNAL_H #define __LABWC_SSD_INTERNAL_H
#include <wlr/util/box.h>
#include "ssd.h" #include "ssd.h"
#define FOR_EACH(tmp, ...) \ #define FOR_EACH(tmp, ...) \
@ -40,10 +41,7 @@ struct ssd {
* don't update things we don't have to. * don't update things we don't have to.
*/ */
struct { struct {
int x; struct wlr_box geometry;
int y;
int width;
int height;
struct ssd_state_title { struct ssd_state_title {
char *text; char *text;
struct ssd_state_title_width active; struct ssd_state_title_width active;
@ -51,7 +49,7 @@ struct ssd {
} title; } title;
} state; } state;
/* An invisble area around the view which allows resizing */ /* An invisible area around the view which allows resizing */
struct ssd_sub_tree extents; struct ssd_sub_tree extents;
/* The top of the view, containing buttons, title, .. */ /* The top of the view, containing buttons, title, .. */

View file

@ -58,17 +58,28 @@ struct view {
struct wlr_output *fullscreen; struct wlr_output *fullscreen;
/* geometry of the wlr_surface contained within the view */ /*
int x, y, w, h; * Geometry of the wlr_surface contained within the view, as
* currently displayed. Should be kept in sync with the
/* user defined geometry before maximize / tiling / fullscreen */ * scene-graph at all times.
*/
struct wlr_box current;
/*
* Expected geometry after any pending move/resize requests
* have been processed. Should match current geometry when no
* move/resize requests are pending.
*/
struct wlr_box pending;
/*
* Saved geometry which will be restored when the view returns
* to normal/floating state after being maximized/fullscreen/
* tiled. Values are undefined/out-of-date when the view is not
* maximized/fullscreen/tiled.
*/
struct wlr_box natural_geometry; struct wlr_box natural_geometry;
struct view_pending_move_resize { /* used by xdg-shell views */
int x, y; uint32_t pending_configure_serial;
uint32_t width, height;
uint32_t configure_serial;
} pending_move_resize;
struct ssd *ssd; struct ssd *ssd;

View file

@ -214,8 +214,8 @@ show_menu(struct server *server, struct view *view, const char *menu_name)
int x, y; int x, y;
if (force_menu_top_left) { if (force_menu_top_left) {
x = view->x; x = view->current.x;
y = view->y; y = view->current.y;
} else { } else {
x = server->seat.cursor->x; x = server->seat.cursor->x;
y = server->seat.cursor->y; y = server->seat.cursor->y;

View file

@ -210,9 +210,7 @@ process_cursor_resize(struct server *server, uint32_t time)
double dy = server->seat.cursor->y - server->grab_y; double dy = server->seat.cursor->y - server->grab_y;
struct view *view = server->grabbed_view; struct view *view = server->grabbed_view;
struct wlr_box new_view_geo = { struct wlr_box new_view_geo = view->current;
.x = view->x, .y = view->y, .width = view->w, .height = view->h
};
if (server->resize_edges & WLR_EDGE_TOP) { if (server->resize_edges & WLR_EDGE_TOP) {
new_view_geo.height = server->grab_box.height - dy; new_view_geo.height = server->grab_box.height - dy;
@ -320,8 +318,8 @@ process_cursor_motion_out_of_surface(struct server *server, uint32_t time)
int lx, ly; int lx, ly;
if (view) { if (view) {
lx = view->x; lx = view->current.x;
ly = view->y; ly = view->current.y;
} else if (node && wlr_surface_is_layer_surface(surface)) { } else if (node && wlr_surface_is_layer_surface(surface)) {
wlr_scene_node_coords(node, &lx, &ly); wlr_scene_node_coords(node, &lx, &ly);
#if HAVE_XWAYLAND #if HAVE_XWAYLAND
@ -435,11 +433,12 @@ cursor_get_resize_edges(struct wlr_cursor *cursor, struct cursor_context *ctx)
{ {
uint32_t resize_edges = ssd_resize_edges(ctx->type); uint32_t resize_edges = ssd_resize_edges(ctx->type);
if (ctx->view && !resize_edges) { if (ctx->view && !resize_edges) {
struct wlr_box box = ctx->view->current;
resize_edges |= resize_edges |=
(int)cursor->x < ctx->view->x + ctx->view->w / 2 ? (int)cursor->x < box.x + box.width / 2 ?
WLR_EDGE_LEFT : WLR_EDGE_RIGHT; WLR_EDGE_LEFT : WLR_EDGE_RIGHT;
resize_edges |= resize_edges |=
(int)cursor->y < ctx->view->y + ctx->view->h / 2 ? (int)cursor->y < box.y + box.height / 2 ?
WLR_EDGE_TOP : WLR_EDGE_BOTTOM; WLR_EDGE_TOP : WLR_EDGE_BOTTOM;
} }
return resize_edges; return resize_edges;

View file

@ -111,7 +111,7 @@ foreign_toplevel_update_outputs(struct view *view)
{ {
assert(view->toplevel.handle); assert(view->toplevel.handle);
struct wlr_box view_geo = { view->x, view->y, view->w, view->h }; struct wlr_box view_geo = view->current;
struct wlr_output_layout *layout = view->server->output_layout; struct wlr_output_layout *layout = view->server->output_layout;
struct output *output; struct output *output;

View file

@ -26,12 +26,7 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
*/ */
struct server *server = view->server; struct server *server = view->server;
struct seat *seat = &server->seat; struct seat *seat = &server->seat;
struct wlr_box geometry = { struct wlr_box geometry = view->current;
.x = view->x,
.y = view->y,
.width = view->w,
.height = view->h
};
switch (mode) { switch (mode) {
case LAB_INPUT_STATE_MOVE: case LAB_INPUT_STATE_MOVE:
@ -52,10 +47,12 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
* to keep it (in the snap-to-maximize case). * to keep it (in the snap-to-maximize case).
*/ */
geometry = view->natural_geometry; geometry = view->natural_geometry;
geometry.x = max_move_scale(seat->cursor->x, view->x, geometry.x = max_move_scale(seat->cursor->x,
view->w, geometry.width); view->current.x, view->current.width,
geometry.y = max_move_scale(seat->cursor->y, view->y, geometry.width);
view->h, geometry.height); geometry.y = max_move_scale(seat->cursor->y,
view->current.y, view->current.height,
geometry.height);
view_restore_to(view, geometry); view_restore_to(view, geometry);
} else { } else {
/* Store natural geometry at start of move */ /* Store natural geometry at start of move */

View file

@ -37,10 +37,9 @@ resistance_move_apply(struct view *view, double *x, double *y)
{ {
struct server *server = view->server; struct server *server = view->server;
struct wlr_box mgeom, intersection; struct wlr_box mgeom, intersection;
struct wlr_box vgeom = {.x = view->x, .y = view->y, .width = view->w, struct wlr_box vgeom = view->current;
.height = view->h}; struct wlr_box tgeom = {.x = *x, .y = *y, .width = vgeom.width,
struct wlr_box tgeom = {.x = *x, .y = *y, .width = view->w, .height = vgeom.height};
.height = view->h};
struct output *output; struct output *output;
struct border border = ssd_get_margin(view->ssd); struct border border = ssd_get_margin(view->ssd);
struct edges view_edges; /* The edges of the current view */ struct edges view_edges; /* The edges of the current view */
@ -48,15 +47,15 @@ resistance_move_apply(struct view *view, double *x, double *y)
struct edges other_edges; /* The edges of the monitor/other view */ struct edges other_edges; /* The edges of the monitor/other view */
struct edges flags = { 0 }; struct edges flags = { 0 };
view_edges.left = view->x - border.left + 1; view_edges.left = vgeom.x - border.left + 1;
view_edges.top = view->y - border.top + 1; view_edges.top = vgeom.y - border.top + 1;
view_edges.right = view->x + view->w + border.right; view_edges.right = vgeom.x + vgeom.width + border.right;
view_edges.bottom = view->y + view->h + border.bottom; view_edges.bottom = vgeom.y + vgeom.height + border.bottom;
target_edges.left = *x - border.left; target_edges.left = *x - border.left;
target_edges.top = *y - border.top; target_edges.top = *y - border.top;
target_edges.right = *x + view->w + border.right; target_edges.right = *x + vgeom.width + border.right;
target_edges.bottom = *y + view->h + border.bottom; target_edges.bottom = *y + vgeom.height + border.bottom;
if (!rc.screen_edge_strength) { if (!rc.screen_edge_strength) {
return; return;
@ -86,13 +85,13 @@ resistance_move_apply(struct view *view, double *x, double *y)
if (flags.left == 1) { if (flags.left == 1) {
*x = other_edges.left + border.left; *x = other_edges.left + border.left;
} else if (flags.right == 1) { } else if (flags.right == 1) {
*x = other_edges.right - view->w - border.right; *x = other_edges.right - vgeom.width - border.right;
} }
if (flags.top == 1) { if (flags.top == 1) {
*y = other_edges.top + border.top; *y = other_edges.top + border.top;
} else if (flags.bottom == 1) { } else if (flags.bottom == 1) {
*y = other_edges.bottom - view->h - border.bottom; *y = other_edges.bottom - vgeom.height - border.bottom;
} }
/* reset the flags */ /* reset the flags */
@ -109,20 +108,18 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_view_geo)
struct server *server = view->server; struct server *server = view->server;
struct output *output; struct output *output;
struct wlr_box mgeom, intersection; struct wlr_box mgeom, intersection;
struct wlr_box vgeom = {.x = view->x, .y = view->y, .width = view->w, struct wlr_box vgeom = view->current;
.height = view->h}; struct wlr_box tgeom = *new_view_geo;
struct wlr_box tgeom = {.x = new_view_geo->x, .y = new_view_geo->y,
.width = new_view_geo->width, .height = new_view_geo->height};
struct border border = ssd_get_margin(view->ssd); struct border border = ssd_get_margin(view->ssd);
struct edges view_edges; /* The edges of the current view */ struct edges view_edges; /* The edges of the current view */
struct edges target_edges; /* The desired edges */ struct edges target_edges; /* The desired edges */
struct edges other_edges; /* The edges of the monitor/other view */ struct edges other_edges; /* The edges of the monitor/other view */
struct edges flags = { 0 }; struct edges flags = { 0 };
view_edges.left = view->x - border.left; view_edges.left = vgeom.x - border.left;
view_edges.top = view->y - border.top; view_edges.top = vgeom.y - border.top;
view_edges.right = view->x + view->w + border.right; view_edges.right = vgeom.x + vgeom.width + border.right;
view_edges.bottom = view->y + view->h + border.bottom; view_edges.bottom = vgeom.y + vgeom.height + border.bottom;
target_edges.left = new_view_geo->x - border.left; target_edges.left = new_view_geo->x - border.left;
target_edges.top = new_view_geo->y - border.top; target_edges.top = new_view_geo->y - border.top;
@ -159,7 +156,7 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_view_geo)
if (flags.left == 1) { if (flags.left == 1) {
new_view_geo->x = other_edges.left new_view_geo->x = other_edges.left
+ border.left; + border.left;
new_view_geo->width = view->w; new_view_geo->width = vgeom.width;
} }
} else if (server->resize_edges & WLR_EDGE_RIGHT) { } else if (server->resize_edges & WLR_EDGE_RIGHT) {
if (flags.right == 1) { if (flags.right == 1) {
@ -172,7 +169,7 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_view_geo)
if (server->resize_edges & WLR_EDGE_TOP) { if (server->resize_edges & WLR_EDGE_TOP) {
if (flags.top == 1) { if (flags.top == 1) {
new_view_geo->y = other_edges.top + border.top; new_view_geo->y = other_edges.top + border.top;
new_view_geo->height = view->h; new_view_geo->height = vgeom.height;
} }
} else if (server->resize_edges & WLR_EDGE_BOTTOM) { } else if (server->resize_edges & WLR_EDGE_BOTTOM) {
if (flags.bottom == 1) { if (flags.bottom == 1) {

View file

@ -40,10 +40,10 @@ ssd_max_extents(struct view *view)
assert(view); assert(view);
struct border border = ssd_thickness(view); struct border border = ssd_thickness(view);
return (struct wlr_box){ return (struct wlr_box){
.x = view->x - border.left, .x = view->current.x - border.left,
.y = view->y - border.top, .y = view->current.y - border.top,
.width = view->w + border.left + border.right, .width = view->current.width + border.left + border.right,
.height = view->h + border.top + border.bottom, .height = view->current.height + border.top + border.bottom,
}; };
} }
@ -163,11 +163,7 @@ ssd_create(struct view *view, bool active)
ssd_titlebar_create(ssd); ssd_titlebar_create(ssd);
ssd->margin = ssd_thickness(view); ssd->margin = ssd_thickness(view);
ssd_set_active(ssd, active); ssd_set_active(ssd, active);
ssd->state.geometry = view->current;
ssd->state.width = view->w;
ssd->state.height = view->h;
ssd->state.x = view->x;
ssd->state.y = view->y;
return ssd; return ssd;
} }
@ -185,24 +181,20 @@ ssd_update_geometry(struct ssd *ssd)
return; return;
} }
struct view *view = ssd->view; struct wlr_box cached = ssd->state.geometry;
if (view->w == ssd->state.width && view->h == ssd->state.height) { struct wlr_box current = ssd->view->current;
if (view->x != ssd->state.x || view->y != ssd->state.y) { if (current.width == cached.width && current.height == cached.height) {
if (current.x != cached.x || current.y != cached.y) {
/* Dynamically resize extents based on position and usable_area */ /* Dynamically resize extents based on position and usable_area */
ssd_extents_update(ssd); ssd_extents_update(ssd);
ssd->state.x = view->x; ssd->state.geometry = current;
ssd->state.y = view->y;
} }
return; return;
} }
ssd_extents_update(ssd); ssd_extents_update(ssd);
ssd_border_update(ssd); ssd_border_update(ssd);
ssd_titlebar_update(ssd); ssd_titlebar_update(ssd);
ssd->state.geometry = current;
ssd->state.width = view->w;
ssd->state.height = view->h;
ssd->state.x = view->x;
ssd->state.y = view->y;
} }
void void

View file

@ -15,8 +15,8 @@ ssd_border_create(struct ssd *ssd)
{ {
struct view *view = ssd->view; struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->current.width;
int height = view->h; int height = view->current.height;
int full_width = width + 2 * theme->border_width; int full_width = width + 2 * theme->border_width;
float *color; float *color;
@ -54,8 +54,8 @@ ssd_border_update(struct ssd *ssd)
struct view *view = ssd->view; struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->current.width;
int height = view->h; int height = view->current.height;
int full_width = width + 2 * theme->border_width; int full_width = width + 2 * theme->border_width;
struct ssd_part *part; struct ssd_part *part;

View file

@ -113,8 +113,8 @@ ssd_extents_update(struct ssd *ssd)
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->current.width;
int height = view->h; int height = view->current.height;
int full_height = height + theme->border_width * 2 + theme->title_height; int full_height = height + theme->border_width * 2 + theme->title_height;
int full_width = width + 2 * theme->border_width; int full_width = width + 2 * theme->border_width;
int extended_area = SSD_EXTENDED_AREA; int extended_area = SSD_EXTENDED_AREA;

View file

@ -22,7 +22,7 @@ ssd_titlebar_create(struct ssd *ssd)
{ {
struct view *view = ssd->view; struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->current.width;
float *color; float *color;
struct wlr_scene_tree *parent; struct wlr_scene_tree *parent;
@ -91,8 +91,8 @@ void
ssd_titlebar_update(struct ssd *ssd) ssd_titlebar_update(struct ssd *ssd)
{ {
struct view *view = ssd->view; struct view *view = ssd->view;
int width = view->w; int width = view->current.width;
if (width == ssd->state.width) { if (width == ssd->state.geometry.width) {
return; return;
} }
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
@ -171,7 +171,7 @@ ssd_update_title_positions(struct ssd *ssd)
{ {
struct view *view = ssd->view; struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->current.width;
int title_bg_width = width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT; int title_bg_width = width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT;
int x, y; int x, y;
@ -239,7 +239,8 @@ ssd_update_title(struct ssd *ssd)
struct ssd_part *part; struct ssd_part *part;
struct ssd_sub_tree *subtree; struct ssd_sub_tree *subtree;
struct ssd_state_title_width *dstate; struct ssd_state_title_width *dstate;
int title_bg_width = view->w - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT; int title_bg_width = view->current.width
- SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT;
FOR_EACH_STATE(ssd, subtree) { FOR_EACH_STATE(ssd, subtree) {
if (subtree == &ssd->titlebar.active) { if (subtree == &ssd->titlebar.active) {

View file

@ -152,7 +152,8 @@ void
view_moved(struct view *view) view_moved(struct view *view)
{ {
assert(view); assert(view);
wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); wlr_scene_node_set_position(&view->scene_tree->node,
view->current.x, view->current.y);
view_discover_output(view); view_discover_output(view);
ssd_update_geometry(view->ssd); ssd_update_geometry(view->ssd);
cursor_update_focus(view->server); cursor_update_focus(view->server);
@ -227,8 +228,9 @@ view_wlr_output(struct view *view)
double closest_x, closest_y; double closest_x, closest_y;
struct wlr_output *wlr_output = NULL; struct wlr_output *wlr_output = NULL;
wlr_output_layout_closest_point(view->server->output_layout, wlr_output, wlr_output_layout_closest_point(view->server->output_layout, wlr_output,
view->x + view->w / 2, view->y + view->h / 2, &closest_x, view->current.x + view->current.width / 2,
&closest_y); view->current.y + view->current.height / 2,
&closest_x, &closest_y);
wlr_output = wlr_output_layout_output_at(view->server->output_layout, wlr_output = wlr_output_layout_output_at(view->server->output_layout,
closest_x, closest_y); closest_x, closest_y);
return wlr_output; return wlr_output;
@ -308,13 +310,10 @@ view_store_natural_geometry(struct view *view)
* natural_geometry width/height may still be zero in which case we set * natural_geometry width/height may still be zero in which case we set
* some fallback values. This is the case with foot and Qt applications. * some fallback values. This is the case with foot and Qt applications.
*/ */
if (!view->w || !view->h) { if (wlr_box_empty(&view->current)) {
set_fallback_geometry(view); set_fallback_geometry(view);
} else { } else {
view->natural_geometry.x = view->x; view->natural_geometry = view->current;
view->natural_geometry.y = view->y;
view->natural_geometry.width = view->w;
view->natural_geometry.height = view->h;
} }
} }
@ -323,7 +322,8 @@ view_center(struct view *view)
{ {
assert(view); assert(view);
int x, y; int x, y;
if (view_compute_centered_position(view, view->w, view->h, &x, &y)) { if (view_compute_centered_position(view, view->current.width,
view->current.height, &x, &y)) {
view_move(view, x, y); view_move(view, x, y);
} }
} }
@ -417,7 +417,8 @@ view_apply_region_geometry(struct view *view)
geo.width -= margin.left + margin.right; geo.width -= margin.left + margin.right;
geo.height -= margin.top + margin.bottom; geo.height -= margin.top + margin.bottom;
if (view->w == geo.width && view->h == geo.height) { if (view->current.width == geo.width
&& view->current.height == geo.height) {
/* move horizontally/vertically without changing size */ /* move horizontally/vertically without changing size */
view_move(view, geo.x, geo.y); view_move(view, geo.x, geo.y);
} else { } else {
@ -438,7 +439,8 @@ view_apply_tiled_geometry(struct view *view, struct output *output)
} }
struct wlr_box dst = view_get_edge_snap_box(view, output, view->tiled); struct wlr_box dst = view_get_edge_snap_box(view, output, view->tiled);
if (view->w == dst.width && view->h == dst.height) { if (view->current.width == dst.width
&& view->current.height == dst.height) {
/* move horizontally/vertically without changing size */ /* move horizontally/vertically without changing size */
view_move(view, dst.x, dst.y); view_move(view, dst.x, dst.y);
} else { } else {
@ -752,8 +754,8 @@ view_adjust_for_layout_change(struct view *view)
} }
} else if (!view_apply_special_geometry(view)) { } else if (!view_apply_special_geometry(view)) {
/* reposition view if it's offscreen */ /* reposition view if it's offscreen */
struct wlr_box box = { view->x, view->y, view->w, view->h }; if (!wlr_output_layout_intersects(layout, NULL,
if (!wlr_output_layout_intersects(layout, NULL, &box)) { &view->current)) {
view_center(view); view_center(view);
} }
} }
@ -809,18 +811,18 @@ view_move_to_edge(struct view *view, const char *direction)
int x = 0, y = 0; int x = 0, y = 0;
if (!strcasecmp(direction, "left")) { if (!strcasecmp(direction, "left")) {
x = usable.x + margin.left + rc.gap; x = usable.x + margin.left + rc.gap;
y = view->y; y = view->current.y;
} else if (!strcasecmp(direction, "up")) { } else if (!strcasecmp(direction, "up")) {
x = view->x; x = view->current.x;
y = usable.y + margin.top + rc.gap; y = usable.y + margin.top + rc.gap;
} else if (!strcasecmp(direction, "right")) { } else if (!strcasecmp(direction, "right")) {
x = usable.x + usable.width - view->w - margin.right x = usable.x + usable.width - view->current.width
- rc.gap; - margin.right - rc.gap;
y = view->y; y = view->current.y;
} else if (!strcasecmp(direction, "down")) { } else if (!strcasecmp(direction, "down")) {
x = view->x; x = view->current.x;
y = usable.y + usable.height - view->h - margin.bottom y = usable.y + usable.height - view->current.height
- rc.gap; - margin.bottom - rc.gap;
} else { } else {
wlr_log(WLR_ERROR, "invalid edge"); wlr_log(WLR_ERROR, "invalid edge");
return; return;

View file

@ -27,14 +27,15 @@ popup_unconstrain(struct view *view, struct wlr_xdg_popup *popup)
struct wlr_box *popup_box = &popup->current.geometry; struct wlr_box *popup_box = &popup->current.geometry;
struct wlr_output_layout *output_layout = server->output_layout; struct wlr_output_layout *output_layout = server->output_layout;
struct wlr_output *wlr_output = wlr_output_layout_output_at( struct wlr_output *wlr_output = wlr_output_layout_output_at(
output_layout, view->x + popup_box->x, view->y + popup_box->y); output_layout, view->current.x + popup_box->x,
view->current.y + popup_box->y);
struct wlr_box output_box; struct wlr_box output_box;
wlr_output_layout_get_box(output_layout, wlr_output, &output_box); wlr_output_layout_get_box(output_layout, wlr_output, &output_box);
struct wlr_box output_toplevel_box = { struct wlr_box output_toplevel_box = {
.x = output_box.x - view->x, .x = output_box.x - view->current.x,
.y = output_box.y - view->y, .y = output_box.y - view->current.y,
.width = output_box.width, .width = output_box.width,
.height = output_box.height, .height = output_box.height,
}; };

View file

@ -66,28 +66,28 @@ handle_commit(struct wl_listener *listener, void *data)
struct wlr_box size; struct wlr_box size;
wlr_xdg_surface_get_geometry(xdg_surface, &size); wlr_xdg_surface_get_geometry(xdg_surface, &size);
struct wlr_box *current = &view->current;
struct wlr_box *pending = &view->pending;
bool update_required = false; bool update_required = false;
if (view->w != size.width || view->h != size.height) { if (current->width != size.width || current->height != size.height) {
update_required = true; update_required = true;
view->w = size.width; current->width = size.width;
view->h = size.height; current->height = size.height;
} }
uint32_t serial = view->pending_move_resize.configure_serial; uint32_t serial = view->pending_configure_serial;
if (serial > 0 && serial >= xdg_surface->current.configure_serial) { if (serial > 0 && serial >= xdg_surface->current.configure_serial) {
if (view->x != view->pending_move_resize.x) { if (current->x != pending->x) {
update_required = true; update_required = true;
view->x = view->pending_move_resize.x + current->x = pending->x + pending->width - size.width;
view->pending_move_resize.width - size.width;
} }
if (view->y != view->pending_move_resize.y) { if (current->y != pending->y) {
update_required = true; update_required = true;
view->y = view->pending_move_resize.y + current->y = pending->y + pending->height - size.height;
view->pending_move_resize.height - size.height;
} }
if (serial == xdg_surface->current.configure_serial) { if (serial == xdg_surface->current.configure_serial) {
view->pending_move_resize.configure_serial = 0; view->pending_configure_serial = 0;
} }
} }
if (update_required) { if (update_required) {
@ -204,20 +204,16 @@ static void
xdg_toplevel_view_configure(struct view *view, struct wlr_box geo) xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
{ {
view_adjust_size(view, &geo.width, &geo.height); view_adjust_size(view, &geo.width, &geo.height);
view->pending = geo;
view->pending_move_resize.x = geo.x;
view->pending_move_resize.y = geo.y;
view->pending_move_resize.width = geo.width;
view->pending_move_resize.height = geo.height;
struct wlr_xdg_toplevel *xdg_toplevel = xdg_toplevel_from_view(view); struct wlr_xdg_toplevel *xdg_toplevel = xdg_toplevel_from_view(view);
uint32_t serial = wlr_xdg_toplevel_set_size(xdg_toplevel, uint32_t serial = wlr_xdg_toplevel_set_size(xdg_toplevel,
(uint32_t)geo.width, (uint32_t)geo.height); (uint32_t)geo.width, (uint32_t)geo.height);
if (serial > 0) { if (serial > 0) {
view->pending_move_resize.configure_serial = serial; view->pending_configure_serial = serial;
} else if (view->pending_move_resize.configure_serial == 0) { } else if (view->pending_configure_serial == 0) {
view->x = geo.x; view->current.x = geo.x;
view->y = geo.y; view->current.y = geo.y;
view_moved(view); view_moved(view);
} }
} }
@ -225,12 +221,12 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
static void static void
xdg_toplevel_view_move(struct view *view, int x, int y) xdg_toplevel_view_move(struct view *view, int x, int y)
{ {
view->x = x; view->current.x = x;
view->y = y; view->current.y = y;
/* override any previous pending move */ /* override any previous pending move */
view->pending_move_resize.x = x; view->pending.x = x;
view->pending_move_resize.y = y; view->pending.y = y;
view_moved(view); view_moved(view);
} }
@ -286,8 +282,8 @@ position_xdg_toplevel_view(struct view *view)
if (!parent_xdg_toplevel) { if (!parent_xdg_toplevel) {
struct wlr_box box = struct wlr_box box =
output_usable_area_from_cursor_coords(view->server); output_usable_area_from_cursor_coords(view->server);
view->x = box.x; view->current.x = box.x;
view->y = box.y; view->current.y = box.y;
/* Center the view without touching its w and h fields. This means we /* Center the view without touching its w and h fields. This means we
* can't simply set w/h and call view_center(). w and h fields should * can't simply set w/h and call view_center(). w and h fields should
@ -310,15 +306,17 @@ position_xdg_toplevel_view(struct view *view)
struct view *parent = lookup_view_by_xdg_toplevel( struct view *parent = lookup_view_by_xdg_toplevel(
view->server, parent_xdg_toplevel); view->server, parent_xdg_toplevel);
assert(parent); assert(parent);
int center_x = parent->x + parent->w / 2; int center_x = parent->current.x + parent->current.width / 2;
int center_y = parent->y + parent->h / 2; int center_y = parent->current.y + parent->current.height / 2;
view->x = center_x - xdg_surface->current.geometry.width / 2; view->current.x = center_x
view->y = center_y - xdg_surface->current.geometry.height / 2; - xdg_surface->current.geometry.width / 2;
view->current.y = center_y
- xdg_surface->current.geometry.height / 2;
} }
struct border margin = ssd_get_margin(view->ssd); struct border margin = ssd_get_margin(view->ssd);
view->x += margin.left; view->current.x += margin.left;
view->y += margin.top; view->current.y += margin.top;
} }
static const char * static const char *

View file

@ -109,24 +109,19 @@ xwayland_surface_from_view(struct view *view)
static void static void
ensure_initial_geometry(struct view *view) ensure_initial_geometry(struct view *view)
{ {
if (!view->w || !view->h) { if (wlr_box_empty(&view->current)) {
struct wlr_xwayland_surface *xwayland_surface = struct wlr_xwayland_surface *xwayland_surface =
xwayland_surface_from_view(view); xwayland_surface_from_view(view);
view->x = xwayland_surface->x; view->current.x = xwayland_surface->x;
view->y = xwayland_surface->y; view->current.y = xwayland_surface->y;
view->w = xwayland_surface->width; view->current.width = xwayland_surface->width;
view->h = xwayland_surface->height; view->current.height = xwayland_surface->height;
/* /*
* If there is no pending move/resize yet, then set * If there is no pending move/resize yet, then set
* current values (used in map()). * current values (used in map()).
*/ */
struct view_pending_move_resize *pending = if (wlr_box_empty(&view->pending)) {
&view->pending_move_resize; view->pending = view->current;
if (!pending->width || !pending->height) {
pending->x = view->x;
pending->y = view->y;
pending->width = view->w;
pending->height = view->h;
} }
} }
} }
@ -146,22 +141,23 @@ handle_commit(struct wl_listener *listener, void *data)
/* Must receive commit signal before accessing surface->current* */ /* Must receive commit signal before accessing surface->current* */
struct wlr_surface_state *state = &view->surface->current; struct wlr_surface_state *state = &view->surface->current;
struct view_pending_move_resize *pending = &view->pending_move_resize; struct wlr_box *current = &view->current;
struct wlr_box *pending = &view->pending;
if (view->w == state->width && view->h == state->height) { if (current->width == state->width && current->height == state->height) {
return; return;
} }
view->w = state->width; current->width = state->width;
view->h = state->height; current->height = state->height;
if (view->x != pending->x) { if (current->x != pending->x) {
/* Adjust x for queued up configure events */ /* Adjust x for queued up configure events */
view->x = pending->x + pending->width - view->w; current->x = pending->x + pending->width - current->width;
} }
if (view->y != pending->y) { if (current->y != pending->y) {
/* Adjust y for queued up configure events */ /* Adjust y for queued up configure events */
view->y = pending->y + pending->height - view->h; current->y = pending->y + pending->height - current->height;
} }
view_moved(view); view_moved(view);
} }
@ -284,18 +280,15 @@ handle_destroy(struct wl_listener *listener, void *data)
static void static void
configure(struct view *view, struct wlr_box geo) configure(struct view *view, struct wlr_box geo)
{ {
view->pending_move_resize.x = geo.x; view->pending = geo;
view->pending_move_resize.y = geo.y;
view->pending_move_resize.width = geo.width;
view->pending_move_resize.height = geo.height;
wlr_xwayland_surface_configure(xwayland_surface_from_view(view), wlr_xwayland_surface_configure(xwayland_surface_from_view(view),
geo.x, geo.y, geo.width, geo.height); geo.x, geo.y, geo.width, geo.height);
/* If not resizing, process the move immediately */ /* If not resizing, process the move immediately */
if (view->w == geo.width && view->h == geo.height) { if (view->current.width == geo.width
view->x = geo.x; && view->current.height == geo.height) {
view->y = geo.y; view->current.x = geo.x;
view->current.y = geo.y;
view_moved(view); view_moved(view);
} }
} }
@ -396,12 +389,12 @@ handle_set_class(struct wl_listener *listener, void *data)
static void static void
move(struct view *view, int x, int y) move(struct view *view, int x, int y)
{ {
view->x = x; view->current.x = x;
view->y = y; view->current.y = y;
/* override any previous pending move */ /* override any previous pending move */
view->pending_move_resize.x = x; view->pending.x = x;
view->pending_move_resize.y = y; view->pending.y = y;
struct wlr_xwayland_surface *s = xwayland_surface_from_view(view); struct wlr_xwayland_surface *s = xwayland_surface_from_view(view);
wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y, wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y,
@ -479,8 +472,8 @@ set_initial_position(struct view *view,
} else { } else {
struct wlr_box box = struct wlr_box box =
output_usable_area_from_cursor_coords(view->server); output_usable_area_from_cursor_coords(view->server);
view->x = box.x; view->current.x = box.x;
view->y = box.y; view->current.y = box.y;
view_center(view); view_center(view);
} }
} }
@ -490,15 +483,12 @@ top_left_edge_boundary_check(struct view *view)
{ {
struct wlr_box deco = ssd_max_extents(view); struct wlr_box deco = ssd_max_extents(view);
if (deco.x < 0) { if (deco.x < 0) {
view->x -= deco.x; view->current.x -= deco.x;
} }
if (deco.y < 0) { if (deco.y < 0) {
view->y -= deco.y; view->current.y -= deco.y;
} }
struct wlr_box box = { view->impl->configure(view, view->current);
.x = view->x, .y = view->y, .width = view->w, .height = view->h
};
view->impl->configure(view, box);
} }
static void static void
@ -554,10 +544,7 @@ map(struct view *view)
* the final intended position/size rather than waiting * the final intended position/size rather than waiting
* for handle_commit(). * for handle_commit().
*/ */
view->x = view->pending_move_resize.x; view->current = view->pending;
view->y = view->pending_move_resize.y;
view->w = view->pending_move_resize.width;
view->h = view->pending_move_resize.height;
view_moved(view); view_moved(view);
view->been_mapped = true; view->been_mapped = true;
} }