Merge branch 'fractional-scale'

This commit is contained in:
Mars-Wave
2026-09-11 22:20:13 +02:00
3 changed files with 53 additions and 37 deletions
+40 -36
View File
@@ -109,6 +109,32 @@ static void update_scroll_size(struct wd_state *state) {
gtk_adjustment_set_value(scroll_y_adj, MIN(y, scroll_y_upper));
}
#define SWAP(_type, _a, _b) { _type _tmp = (_a); (_a) = (_b); (_b) = _tmp; }
static void get_logical_size(WdHeadForm *form, const WdHeadDimensions *dim,
double *w, double *h) {
const struct wd_head *head = g_object_get_data(G_OBJECT(form), "head");
const struct wd_mode *mode = head->mode;
int32_t mode_w = mode != NULL ? mode->width : head->custom_mode.width;
int32_t mode_h = mode != NULL ? mode->height : head->custom_mode.height;
if (head->logical_width > 0 && dim->w == mode_w && dim->h == mode_h
&& round(dim->scale * 100.) == round(head->scale * 100.)
&& (dim->rotation_id & 1) == (head->transform & 1)) {
*w = head->logical_width;
*h = head->logical_height;
return;
}
double scale = dim->scale > 0. ? dim->scale : 1.;
scale = wl_fixed_to_double(wl_fixed_from_double(scale));
/* as sway does: snap to 1/120, divide in float, truncate */
float wlr_scale = round(scale * 120.) / 120.;
*w = (int) ((float) dim->w / wlr_scale);
*h = (int) ((float) dim->h / wlr_scale);
if (dim->rotation_id & 1) {
SWAP(double, *w, *h);
}
}
/*
* Recalculates the desired canvas size, accounting for zoom + margins.
*/
@@ -124,12 +150,9 @@ static void update_canvas_size(struct wd_state *state) {
if (wd_head_form_get_enabled(form)) {
WdHeadDimensions dim;
wd_head_form_get_dimensions(form, &dim);
int h = dim.h;
int w = dim.w;
if (dim.scale > 0.) {
w /= dim.scale;
h /= dim.scale;
}
double w;
double h;
get_logical_size(form, &dim, &w, &h);
int x2 = dim.x + w;
int y2 = dim.y + h;
xmin = MIN(xmin, dim.x);
@@ -253,8 +276,6 @@ static inline void color_to_float_array(GtkStyleContext *ctx,
out[3] = color.alpha;
}
#define SWAP(_type, _a, _b) { _type _tmp = (_a); (_a) = (_b); (_b) = _tmp; }
static void queue_canvas_draw(struct wd_state *state) {
GtkStyleContext *style_ctx = gtk_widget_get_style_context(state->canvas);
color_to_float_array(style_ctx,
@@ -274,11 +295,9 @@ static void queue_canvas_draw(struct wd_state *state) {
if (wd_head_form_get_enabled(form)) {
WdHeadDimensions dim;
wd_head_form_get_dimensions(form, &dim);
double w = dim.w;
double h = dim.h;
double scale = dim.scale;
if (scale <= 0.)
scale = 1.;
double w;
double h;
get_logical_size(form, &dim, &w, &h);
struct wd_head *head = g_object_get_data(G_OBJECT(form_iter->data), "head");
if (head->render == NULL) {
@@ -287,14 +306,11 @@ static void queue_canvas_draw(struct wd_state *state) {
}
struct wd_render_head_data *render = head->render;
render->queued.rotation = dim.rotation_id;
if (render->queued.rotation & 1) {
SWAP(int, w, h);
}
render->queued.x_invert = dim.flipped;
render->x1 = floor(dim.x * state->zoom - state->render.scroll_x - state->render.x_origin);
render->y1 = floor(dim.y * state->zoom - state->render.scroll_y - state->render.y_origin);
render->x2 = floor(render->x1 + w * state->zoom / scale);
render->y2 = floor(render->y1 + h * state->zoom / scale);
render->x2 = floor(render->x1 + w * state->zoom);
render->y2 = floor(render->y1 + h * state->zoom);
}
}
gtk_gl_area_queue_render(GTK_GL_AREA(state->canvas));
@@ -697,14 +713,8 @@ static void canvas_drag1_update(GtkGestureDrag *drag,
return;
WdHeadDimensions dim;
wd_head_form_get_dimensions(form, &dim);
struct wd_point size = { .x = dim.w, .y = dim.h };
if (dim.scale > 0.) {
size.x /= dim.scale;
size.y /= dim.scale;
}
if (dim.rotation_id & 1) {
SWAP(int, size.x, size.y);
}
struct wd_point size;
get_logical_size(form, &dim, &size.x, &size.y);
struct wd_point tl = { /* top left */
.x = (state->drag_start.x + delta_x - state->head_drag_start.x * size.x * state->zoom) / state->zoom,
.y = (state->drag_start.y + delta_y - state->head_drag_start.y * size.y * state->zoom) / state->zoom
@@ -729,15 +739,9 @@ static void canvas_drag1_update(GtkGestureDrag *drag,
wd_head_form_get_dimensions(other_form, &other_dim);
double x1 = other_dim.x;
double y1 = other_dim.y;
double w = other_dim.w;
double h = other_dim.h;
if (other_dim.scale > 0.) {
w /= other_dim.scale;
h /= other_dim.scale;
}
if (other_dim.rotation_id & 1) {
SWAP(int, w, h);
}
double w;
double h;
get_logical_size(other_form, &other_dim, &w, &h);
double x2 = x1 + w;
double y2 = y1 + h;
if (fabs(br.x) <= snap)
@@ -767,7 +771,7 @@ static void canvas_drag1_update(GtkGestureDrag *drag,
new_pos.y = y2;
}
}
wd_head_form_set_position(form, new_pos.x, new_pos.y);
wd_head_form_set_position(form, round(new_pos.x), round(new_pos.y));
}
static void canvas_drag1_end(GtkGestureDrag *drag,
+12 -1
View File
@@ -596,6 +596,17 @@ static void output_logical_position(void *data, struct zxdg_output_v1 *zxdg_outp
}
}
static void output_logical_size(void *data, struct zxdg_output_v1 *zxdg_output_v1,
int32_t width, int32_t height) {
struct wd_output *output = data;
struct wd_head *head = wd_find_head(output->state, output);
if (head != NULL) {
head->logical_width = width;
head->logical_height = height;
wd_ui_reset_head(head, 0);
}
}
static void output_name(void *data, struct zxdg_output_v1 *zxdg_output_v1,
const char *name) {
struct wd_output *output = data;
@@ -611,7 +622,7 @@ static void output_name(void *data, struct zxdg_output_v1 *zxdg_output_v1,
static const struct zxdg_output_v1_listener output_listener = {
.logical_position = output_logical_position,
.logical_size = (void (*)(void *, struct zxdg_output_v1 *, int32_t, int32_t))noop,
.logical_size = output_logical_size,
.done = (void (*)(void *, struct zxdg_output_v1 *))noop,
.name = output_name,
.description = (void (*)(void *, struct zxdg_output_v1 *, const char *))noop
+1
View File
@@ -117,6 +117,7 @@ struct wd_head {
int32_t x, y;
enum wl_output_transform transform;
double scale;
int32_t logical_width, logical_height;
};
struct wd_gl_data;