mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-06-17 14:33:18 -04:00
opt: Reduce unnecessary text drawing
This commit is contained in:
parent
83e5fafd65
commit
1f4f2dd5f0
10 changed files with 282 additions and 169 deletions
|
|
@ -898,7 +898,7 @@ void fadeout_client_animation_next_tick(Client *c) {
|
||||||
double percent = config.fadeout_begin_opacity -
|
double percent = config.fadeout_begin_opacity -
|
||||||
(opacity_eased_progress * config.fadeout_begin_opacity);
|
(opacity_eased_progress * config.fadeout_begin_opacity);
|
||||||
|
|
||||||
double opacity = MAX(percent, 0);
|
double opacity = MANGO_MAX(percent, 0);
|
||||||
|
|
||||||
if (config.animation_fade_out && !c->nofadeout)
|
if (config.animation_fade_out && !c->nofadeout)
|
||||||
wlr_scene_node_for_each_buffer(&c->scene->node,
|
wlr_scene_node_for_each_buffer(&c->scene->node,
|
||||||
|
|
@ -1177,8 +1177,8 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
|
|
||||||
if (is_scroller_layout(c->mon) && (!c->isfloating || c == grabc)) {
|
if (is_scroller_layout(c->mon) && (!c->isfloating || c == grabc)) {
|
||||||
c->geom = geo;
|
c->geom = geo;
|
||||||
c->geom.width = MAX(1 + 2 * (int32_t)c->bw, c->geom.width);
|
c->geom.width = MANGO_MAX(1 + 2 * (int32_t)c->bw, c->geom.width);
|
||||||
c->geom.height = MAX(1 + 2 * (int32_t)c->bw, c->geom.height);
|
c->geom.height = MANGO_MAX(1 + 2 * (int32_t)c->bw, c->geom.height);
|
||||||
} else { // 这里会限制不允许窗口划出屏幕
|
} else { // 这里会限制不允许窗口划出屏幕
|
||||||
c->geom = geo;
|
c->geom = geo;
|
||||||
applybounds(
|
applybounds(
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
|
||||||
double percent = config.fadeout_begin_opacity -
|
double percent = config.fadeout_begin_opacity -
|
||||||
(opacity_eased_progress * config.fadeout_begin_opacity);
|
(opacity_eased_progress * config.fadeout_begin_opacity);
|
||||||
|
|
||||||
double opacity = MAX(percent, 0.0f);
|
double opacity = MANGO_MAX(percent, 0.0f);
|
||||||
|
|
||||||
if (config.animation_fade_out)
|
if (config.animation_fade_out)
|
||||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||||
|
|
@ -278,7 +278,7 @@ void layer_animation_next_tick(LayerSurface *l) {
|
||||||
find_animation_curve_at(animation_passed, OPAFADEIN);
|
find_animation_curve_at(animation_passed, OPAFADEIN);
|
||||||
|
|
||||||
double opacity =
|
double opacity =
|
||||||
MIN(config.fadein_begin_opacity +
|
MANGO_MIN(config.fadein_begin_opacity +
|
||||||
opacity_eased_progress * (1.0 - config.fadein_begin_opacity),
|
opacity_eased_progress * (1.0 - config.fadein_begin_opacity),
|
||||||
1.0f);
|
1.0f);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@ void set_tagin_animation(Monitor *m, Client *c) {
|
||||||
|
|
||||||
c->animainit_geom.x = config.tag_animation_direction == VERTICAL
|
c->animainit_geom.x = config.tag_animation_direction == VERTICAL
|
||||||
? c->animation.current.x
|
? c->animation.current.x
|
||||||
: MAX(c->mon->m.x + c->mon->m.width,
|
: MANGO_MAX(c->mon->m.x + c->mon->m.width,
|
||||||
c->geom.x + c->mon->m.width);
|
c->geom.x + c->mon->m.width);
|
||||||
c->animainit_geom.y = config.tag_animation_direction == VERTICAL
|
c->animainit_geom.y = config.tag_animation_direction == VERTICAL
|
||||||
? MAX(c->mon->m.y + c->mon->m.height,
|
? MANGO_MAX(c->mon->m.y + c->mon->m.height,
|
||||||
c->geom.y + c->mon->m.height)
|
c->geom.y + c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: c->animation.current.y;
|
||||||
|
|
||||||
|
|
@ -35,10 +35,10 @@ void set_tagin_animation(Monitor *m, Client *c) {
|
||||||
c->animainit_geom.x =
|
c->animainit_geom.x =
|
||||||
config.tag_animation_direction == VERTICAL
|
config.tag_animation_direction == VERTICAL
|
||||||
? c->animation.current.x
|
? c->animation.current.x
|
||||||
: MIN(m->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
: MANGO_MIN(m->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
||||||
c->animainit_geom.y =
|
c->animainit_geom.y =
|
||||||
config.tag_animation_direction == VERTICAL
|
config.tag_animation_direction == VERTICAL
|
||||||
? MIN(m->m.y - c->geom.height, c->geom.y - c->mon->m.height)
|
? MANGO_MIN(m->m.y - c->geom.height, c->geom.y - c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: c->animation.current.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -87,9 +87,9 @@ void set_tagout_animation(Monitor *m, Client *c) {
|
||||||
c->pending.x =
|
c->pending.x =
|
||||||
config.tag_animation_direction == VERTICAL
|
config.tag_animation_direction == VERTICAL
|
||||||
? c->animation.current.x
|
? c->animation.current.x
|
||||||
: MIN(c->mon->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
: MANGO_MIN(c->mon->m.x - c->geom.width, c->geom.x - c->mon->m.width);
|
||||||
c->pending.y = config.tag_animation_direction == VERTICAL
|
c->pending.y = config.tag_animation_direction == VERTICAL
|
||||||
? MIN(c->mon->m.y - c->geom.height,
|
? MANGO_MIN(c->mon->m.y - c->geom.height,
|
||||||
c->geom.y - c->mon->m.height)
|
c->geom.y - c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: c->animation.current.y;
|
||||||
|
|
||||||
|
|
@ -98,10 +98,10 @@ void set_tagout_animation(Monitor *m, Client *c) {
|
||||||
c->pending = c->geom;
|
c->pending = c->geom;
|
||||||
c->pending.x = config.tag_animation_direction == VERTICAL
|
c->pending.x = config.tag_animation_direction == VERTICAL
|
||||||
? c->animation.current.x
|
? c->animation.current.x
|
||||||
: MAX(c->mon->m.x + c->mon->m.width,
|
: MANGO_MAX(c->mon->m.x + c->mon->m.width,
|
||||||
c->geom.x + c->mon->m.width);
|
c->geom.x + c->mon->m.width);
|
||||||
c->pending.y = config.tag_animation_direction == VERTICAL
|
c->pending.y = config.tag_animation_direction == VERTICAL
|
||||||
? MAX(c->mon->m.y + c->mon->m.height,
|
? MANGO_MAX(c->mon->m.y + c->mon->m.height,
|
||||||
c->geom.y + c->mon->m.height)
|
c->geom.y + c->mon->m.height)
|
||||||
: c->animation.current.y;
|
: c->animation.current.y;
|
||||||
resize(c, c->geom, 0);
|
resize(c, c->geom, 0);
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ int32_t incnmaster(const Arg *arg) {
|
||||||
if (!arg || !selmon)
|
if (!arg || !selmon)
|
||||||
return 0;
|
return 0;
|
||||||
selmon->pertag->nmasters[selmon->pertag->curtag] =
|
selmon->pertag->nmasters[selmon->pertag->curtag] =
|
||||||
MAX(selmon->pertag->nmasters[selmon->pertag->curtag] + arg->i, 0);
|
MANGO_MAX(selmon->pertag->nmasters[selmon->pertag->curtag] + arg->i, 0);
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -737,12 +737,12 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
continue;
|
continue;
|
||||||
buttom = tc->geom.y + tc->geom.height + config.gappiv;
|
buttom = tc->geom.y + tc->geom.height + config.gappiv;
|
||||||
if (top > buttom && ny < buttom) {
|
if (top > buttom && ny < buttom) {
|
||||||
tar = MAX(tar, buttom);
|
tar = MANGO_MAX(tar, buttom);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ny = tar == -99999 ? ny : tar;
|
ny = tar == -99999 ? ny : tar;
|
||||||
ny = MAX(ny, c->mon->w.y + c->mon->gappov);
|
ny = MANGO_MAX(ny, c->mon->w.y + c->mon->gappov);
|
||||||
break;
|
break;
|
||||||
case DOWN:
|
case DOWN:
|
||||||
tar = 99999;
|
tar = 99999;
|
||||||
|
|
@ -757,11 +757,11 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
continue;
|
continue;
|
||||||
top = tc->geom.y - config.gappiv;
|
top = tc->geom.y - config.gappiv;
|
||||||
if (buttom < top && (ny + c->geom.height) > top) {
|
if (buttom < top && (ny + c->geom.height) > top) {
|
||||||
tar = MIN(tar, top - c->geom.height);
|
tar = MANGO_MIN(tar, top - c->geom.height);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ny = tar == 99999 ? ny : tar;
|
ny = tar == 99999 ? ny : tar;
|
||||||
ny = MIN(ny, c->mon->w.y + c->mon->w.height - c->geom.height -
|
ny = MANGO_MIN(ny, c->mon->w.y + c->mon->w.height - c->geom.height -
|
||||||
c->mon->gappov);
|
c->mon->gappov);
|
||||||
break;
|
break;
|
||||||
case LEFT:
|
case LEFT:
|
||||||
|
|
@ -777,12 +777,12 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
continue;
|
continue;
|
||||||
right = tc->geom.x + tc->geom.width + config.gappih;
|
right = tc->geom.x + tc->geom.width + config.gappih;
|
||||||
if (left > right && nx < right) {
|
if (left > right && nx < right) {
|
||||||
tar = MAX(tar, right);
|
tar = MANGO_MAX(tar, right);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
nx = tar == -99999 ? nx : tar;
|
nx = tar == -99999 ? nx : tar;
|
||||||
nx = MAX(nx, c->mon->w.x + c->mon->gappoh);
|
nx = MANGO_MAX(nx, c->mon->w.x + c->mon->gappoh);
|
||||||
break;
|
break;
|
||||||
case RIGHT:
|
case RIGHT:
|
||||||
tar = 99999;
|
tar = 99999;
|
||||||
|
|
@ -796,11 +796,11 @@ int32_t smartmovewin(const Arg *arg) {
|
||||||
continue;
|
continue;
|
||||||
left = tc->geom.x - config.gappih;
|
left = tc->geom.x - config.gappih;
|
||||||
if (right < left && (nx + c->geom.width) > left) {
|
if (right < left && (nx + c->geom.width) > left) {
|
||||||
tar = MIN(tar, left - c->geom.width);
|
tar = MANGO_MIN(tar, left - c->geom.width);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
nx = tar == 99999 ? nx : tar;
|
nx = tar == 99999 ? nx : tar;
|
||||||
nx = MIN(nx, c->mon->w.x + c->mon->w.width - c->geom.width -
|
nx = MANGO_MIN(nx, c->mon->w.x + c->mon->w.width - c->geom.width -
|
||||||
c->mon->gappoh);
|
c->mon->gappoh);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -829,7 +829,7 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
switch (arg->i) {
|
switch (arg->i) {
|
||||||
case UP:
|
case UP:
|
||||||
nh -= selmon->w.height / 8;
|
nh -= selmon->w.height / 8;
|
||||||
nh = MAX(nh, selmon->w.height / 10);
|
nh = MANGO_MAX(nh, selmon->w.height / 10);
|
||||||
break;
|
break;
|
||||||
case DOWN:
|
case DOWN:
|
||||||
tar = -99999;
|
tar = -99999;
|
||||||
|
|
@ -844,7 +844,7 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
continue;
|
continue;
|
||||||
top = tc->geom.y - config.gappiv;
|
top = tc->geom.y - config.gappiv;
|
||||||
if (buttom < top && (nh + c->geom.y) > top) {
|
if (buttom < top && (nh + c->geom.y) > top) {
|
||||||
tar = MAX(tar, top - c->geom.y);
|
tar = MANGO_MAX(tar, top - c->geom.y);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
nh = tar == -99999 ? nh : tar;
|
nh = tar == -99999 ? nh : tar;
|
||||||
|
|
@ -853,7 +853,7 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
break;
|
break;
|
||||||
case LEFT:
|
case LEFT:
|
||||||
nw -= selmon->w.width / 16;
|
nw -= selmon->w.width / 16;
|
||||||
nw = MAX(nw, selmon->w.width / 10);
|
nw = MANGO_MAX(nw, selmon->w.width / 10);
|
||||||
break;
|
break;
|
||||||
case RIGHT:
|
case RIGHT:
|
||||||
tar = 99999;
|
tar = 99999;
|
||||||
|
|
@ -867,7 +867,7 @@ int32_t smartresizewin(const Arg *arg) {
|
||||||
continue;
|
continue;
|
||||||
left = tc->geom.x - config.gappih;
|
left = tc->geom.x - config.gappih;
|
||||||
if (right < left && (nw + c->geom.x) > left) {
|
if (right < left && (nw + c->geom.x) > left) {
|
||||||
tar = MIN(tar, left - c->geom.x);
|
tar = MANGO_MIN(tar, left - c->geom.x);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1064,7 +1064,7 @@ int32_t switch_layout(const Arg *arg) {
|
||||||
if (config.circle_layout_count != 0) {
|
if (config.circle_layout_count != 0) {
|
||||||
for (jk = 0; jk < config.circle_layout_count; jk++) {
|
for (jk = 0; jk < config.circle_layout_count; jk++) {
|
||||||
|
|
||||||
len = MAX(
|
len = MANGO_MAX(
|
||||||
strlen(config.circle_layout[jk]),
|
strlen(config.circle_layout[jk]),
|
||||||
strlen(selmon->pertag->ltidxs[selmon->pertag->curtag]->name));
|
strlen(selmon->pertag->ltidxs[selmon->pertag->curtag]->name));
|
||||||
|
|
||||||
|
|
@ -1083,7 +1083,7 @@ int32_t switch_layout(const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ji = 0; ji < LENGTH(layouts); ji++) {
|
for (ji = 0; ji < LENGTH(layouts); ji++) {
|
||||||
len = MAX(strlen(layouts[ji].name), strlen(target_layout_name));
|
len = MANGO_MAX(strlen(layouts[ji].name), strlen(target_layout_name));
|
||||||
if (strncmp(layouts[ji].name, target_layout_name, len) == 0) {
|
if (strncmp(layouts[ji].name, target_layout_name, len) == 0) {
|
||||||
selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[ji];
|
selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[ji];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,14 @@
|
||||||
#include "text-node.h"
|
#include "text-node.h"
|
||||||
|
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/interfaces/wlr_buffer.h>
|
#include <wlr/interfaces/wlr_buffer.h>
|
||||||
|
|
||||||
// 自定义 wlr_buffer,用于将 Cairo Surface 包装并注入 wlr_scene
|
|
||||||
struct mango_text_buffer {
|
|
||||||
struct wlr_buffer base;
|
|
||||||
cairo_surface_t *surface;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 全局字体描述缓存
|
|
||||||
static GHashTable *font_desc_cache = NULL;
|
static GHashTable *font_desc_cache = NULL;
|
||||||
|
|
||||||
static PangoFontDescription *get_cached_font_desc(const char *font_desc) {
|
static PangoFontDescription *get_cached_font_desc(const char *font_desc) {
|
||||||
|
|
@ -39,10 +34,8 @@ void mango_text_global_finish(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// wlr_buffer 实现
|
|
||||||
static void text_buffer_destroy(struct wlr_buffer *wlr_buffer) {
|
static void text_buffer_destroy(struct wlr_buffer *wlr_buffer) {
|
||||||
struct mango_text_buffer *buf = wl_container_of(wlr_buffer, buf, base);
|
struct mango_text_buffer *buf = wl_container_of(wlr_buffer, buf, base);
|
||||||
cairo_surface_destroy(buf->surface);
|
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,23 +71,26 @@ struct mango_text_node *mango_text_node_create(struct wlr_scene_tree *parent,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
node->fg_color[0] = data.fg_color[0];
|
memcpy(node->fg_color, data.fg_color, sizeof(node->fg_color));
|
||||||
node->fg_color[1] = data.fg_color[1];
|
memcpy(node->bg_color, data.bg_color, sizeof(node->bg_color));
|
||||||
node->fg_color[2] = data.fg_color[2];
|
memcpy(node->border_color, data.border_color, sizeof(node->border_color));
|
||||||
node->fg_color[3] = data.fg_color[3];
|
|
||||||
node->bg_color[0] = data.bg_color[0];
|
|
||||||
node->bg_color[1] = data.bg_color[1];
|
|
||||||
node->bg_color[2] = data.bg_color[2];
|
|
||||||
node->bg_color[3] = data.bg_color[3];
|
|
||||||
node->border_color[0] = data.border_color[0];
|
|
||||||
node->border_color[1] = data.border_color[1];
|
|
||||||
node->border_color[2] = data.border_color[2];
|
|
||||||
node->border_color[3] = data.border_color[3];
|
|
||||||
node->border_width = data.border_width;
|
node->border_width = data.border_width;
|
||||||
node->corner_radius = data.corner_radius;
|
node->corner_radius = data.corner_radius;
|
||||||
node->padding_x = data.padding_x;
|
node->padding_x = data.padding_x;
|
||||||
node->padding_y = data.padding_y;
|
node->padding_y = data.padding_y;
|
||||||
node->font_desc = data.font_desc ? data.font_desc : "monospace Bold 24";
|
node->font_desc =
|
||||||
|
g_strdup(data.font_desc ? data.font_desc : "monospace Bold 24");
|
||||||
|
|
||||||
|
node->cached_text = NULL;
|
||||||
|
node->cached_scale = -1.0f;
|
||||||
|
node->cached_font_desc = NULL;
|
||||||
|
|
||||||
|
node->measure_surface =
|
||||||
|
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
|
||||||
|
node->measure_cr = cairo_create(node->measure_surface);
|
||||||
|
node->measure_context = pango_cairo_create_context(node->measure_cr);
|
||||||
|
node->measure_layout = pango_layout_new(node->measure_context);
|
||||||
|
node->measure_scale = 1.0f;
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
@ -103,7 +99,31 @@ void mango_text_node_destroy(struct mango_text_node *node) {
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (node->buffer) {
|
||||||
|
wlr_buffer_drop(&node->buffer->base);
|
||||||
|
node->buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->surface) {
|
||||||
|
cairo_surface_destroy(node->surface);
|
||||||
|
node->surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->measure_layout)
|
||||||
|
g_object_unref(node->measure_layout);
|
||||||
|
if (node->measure_context)
|
||||||
|
g_object_unref(node->measure_context);
|
||||||
|
if (node->measure_cr)
|
||||||
|
cairo_destroy(node->measure_cr);
|
||||||
|
if (node->measure_surface)
|
||||||
|
cairo_surface_destroy(node->measure_surface);
|
||||||
|
|
||||||
wlr_scene_node_destroy(&node->scene_buffer->node);
|
wlr_scene_node_destroy(&node->scene_buffer->node);
|
||||||
|
|
||||||
|
g_free(node->font_desc);
|
||||||
|
g_free(node->cached_text);
|
||||||
|
g_free(node->cached_font_desc);
|
||||||
|
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,28 +138,42 @@ void mango_text_node_set_background(struct mango_text_node *node, float r,
|
||||||
}
|
}
|
||||||
|
|
||||||
void mango_text_node_set_border(struct mango_text_node *node, float r, float g,
|
void mango_text_node_set_border(struct mango_text_node *node, float r, float g,
|
||||||
float b, float a, float width, float radius) {
|
float b, float a, int32_t width,
|
||||||
|
int32_t radius) {
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
node->border_color[0] = r;
|
node->border_color[0] = r;
|
||||||
node->border_color[1] = g;
|
node->border_color[1] = g;
|
||||||
node->border_color[2] = b;
|
node->border_color[2] = b;
|
||||||
node->border_color[3] = a;
|
node->border_color[3] = a;
|
||||||
node->border_width = width > 0.0f ? width : 0.0f;
|
node->border_width = width > 0 ? width : 0;
|
||||||
node->corner_radius = radius >= 0.0f ? radius : 0.0f;
|
node->corner_radius = radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mango_text_node_set_padding(struct mango_text_node *node, float pad_x,
|
void mango_text_node_set_padding(struct mango_text_node *node, int32_t pad_x,
|
||||||
float pad_y) {
|
int32_t pad_y) {
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
node->padding_x = pad_x >= 0.0f ? pad_x : 0.0f;
|
node->padding_x = pad_x >= 0 ? pad_x : 0;
|
||||||
node->padding_y = pad_y >= 0.0f ? pad_y : 0.0f;
|
node->padding_y = pad_y >= 0 ? pad_y : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_text_pixel_size(struct mango_text_node *node, const char *text,
|
||||||
|
float scale, int32_t *out_w, int32_t *out_h) {
|
||||||
|
if (node->measure_scale != scale) {
|
||||||
|
pango_cairo_context_set_resolution(node->measure_context, 96.0 * scale);
|
||||||
|
node->measure_scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
PangoFontDescription *desc = get_cached_font_desc(node->font_desc);
|
||||||
|
pango_layout_set_font_description(node->measure_layout, desc);
|
||||||
|
pango_layout_set_text(node->measure_layout, text, -1);
|
||||||
|
|
||||||
|
pango_layout_get_pixel_size(node->measure_layout, out_w, out_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_rounded_rect(cairo_t *cr, double x, double y, double w,
|
static void draw_rounded_rect(cairo_t *cr, double x, double y, double w,
|
||||||
double h, double r) {
|
double h, double r) {
|
||||||
// 使用 Cairo 的标准圆角矩形路径
|
|
||||||
double degrees = G_PI / 180.0;
|
double degrees = G_PI / 180.0;
|
||||||
cairo_new_sub_path(cr);
|
cairo_new_sub_path(cr);
|
||||||
cairo_arc(cr, x + w - r, y + r, r, -90 * degrees, 0 * degrees);
|
cairo_arc(cr, x + w - r, y + r, r, -90 * degrees, 0 * degrees);
|
||||||
|
|
@ -150,86 +184,133 @@ static void draw_rounded_rect(cairo_t *cr, double x, double y, double w,
|
||||||
}
|
}
|
||||||
|
|
||||||
void mango_text_node_update(struct mango_text_node *node, const char *text,
|
void mango_text_node_update(struct mango_text_node *node, const char *text,
|
||||||
|
|
||||||
float scale) {
|
float scale) {
|
||||||
if (!node || !text)
|
if (!node || !text)
|
||||||
return;
|
return;
|
||||||
if (scale <= 0.0f)
|
if (scale <= 0.0f)
|
||||||
scale = 1.0f;
|
scale = 1.0f;
|
||||||
|
|
||||||
const char *font_desc = node->font_desc;
|
/* 脏检查 */
|
||||||
PangoFontDescription *desc = get_cached_font_desc(font_desc);
|
if (node->cached_scale == scale && node->cached_font_desc &&
|
||||||
|
strcmp(node->cached_font_desc, node->font_desc) == 0 &&
|
||||||
// 测量文字像素尺寸(无缩放的实际像素)
|
node->cached_text && strcmp(node->cached_text, text) == 0 &&
|
||||||
cairo_surface_t *dummy_surface =
|
memcmp(node->cached_fg_color, node->fg_color, sizeof(node->fg_color)) ==
|
||||||
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
|
0 &&
|
||||||
cairo_t *dummy_cr = cairo_create(dummy_surface);
|
memcmp(node->cached_bg_color, node->bg_color, sizeof(node->bg_color)) ==
|
||||||
PangoContext *dummy_ctx = pango_cairo_create_context(dummy_cr);
|
0 &&
|
||||||
pango_cairo_context_set_resolution(dummy_ctx, 96.0 * scale);
|
memcmp(node->cached_border_color, node->border_color,
|
||||||
PangoLayout *dummy_layout = pango_layout_new(dummy_ctx);
|
sizeof(node->border_color)) == 0 &&
|
||||||
pango_layout_set_font_description(dummy_layout, desc);
|
node->cached_border_width == node->border_width &&
|
||||||
pango_layout_set_text(dummy_layout, text, -1);
|
node->cached_corner_radius == node->corner_radius &&
|
||||||
|
node->cached_padding_x == node->padding_x &&
|
||||||
int text_pixel_w, text_pixel_h;
|
node->cached_padding_y == node->padding_y) {
|
||||||
pango_layout_get_pixel_size(dummy_layout, &text_pixel_w, &text_pixel_h);
|
|
||||||
|
|
||||||
g_object_unref(dummy_layout);
|
|
||||||
g_object_unref(dummy_ctx);
|
|
||||||
cairo_destroy(dummy_cr);
|
|
||||||
cairo_surface_destroy(dummy_surface);
|
|
||||||
|
|
||||||
if (text_pixel_w <= 0 || text_pixel_h <= 0) {
|
|
||||||
wlr_scene_buffer_set_buffer(node->scene_buffer, NULL);
|
|
||||||
node->logical_width = 0;
|
|
||||||
node->logical_height = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float logical_text_w = text_pixel_w / scale;
|
/* 更新缓存 */
|
||||||
float logical_text_h = text_pixel_h / scale;
|
g_free(node->cached_text);
|
||||||
|
node->cached_text = g_strdup(text);
|
||||||
|
g_free(node->cached_font_desc);
|
||||||
|
node->cached_font_desc = g_strdup(node->font_desc);
|
||||||
|
node->cached_scale = scale;
|
||||||
|
memcpy(node->cached_fg_color, node->fg_color, sizeof(node->fg_color));
|
||||||
|
memcpy(node->cached_bg_color, node->bg_color, sizeof(node->bg_color));
|
||||||
|
memcpy(node->cached_border_color, node->border_color,
|
||||||
|
sizeof(node->border_color));
|
||||||
|
node->cached_border_width = node->border_width;
|
||||||
|
node->cached_corner_radius = node->corner_radius;
|
||||||
|
node->cached_padding_x = node->padding_x;
|
||||||
|
node->cached_padding_y = node->padding_y;
|
||||||
|
|
||||||
float pad_x = node->padding_x;
|
int32_t text_pixel_w, text_pixel_h;
|
||||||
float pad_y = node->padding_y;
|
get_text_pixel_size(node, text, scale, &text_pixel_w, &text_pixel_h);
|
||||||
float box_logical_w = logical_text_w + 2.0f * pad_x;
|
|
||||||
float box_logical_h = logical_text_h + 2.0f * pad_y;
|
|
||||||
|
|
||||||
float border = node->border_width;
|
if (text_pixel_w <= 0 || text_pixel_h <= 0) {
|
||||||
bool draw_border = (border > 0.0f) && (node->border_color[3] > 0.0f);
|
wlr_scene_buffer_set_buffer(node->scene_buffer, NULL);
|
||||||
bool draw_bg = (node->bg_color[3] > 0.0f);
|
if (node->buffer) {
|
||||||
|
wlr_buffer_drop(&node->buffer->base);
|
||||||
|
node->buffer = NULL;
|
||||||
|
}
|
||||||
|
if (node->surface) {
|
||||||
|
cairo_surface_destroy(node->surface);
|
||||||
|
node->surface = NULL;
|
||||||
|
}
|
||||||
|
node->logical_width = 0;
|
||||||
|
node->logical_height = 0;
|
||||||
|
wlr_scene_buffer_set_dest_size(node->scene_buffer, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int surface_pixel_w = (int)((box_logical_w + 2.0f * border) * scale + 0.5f);
|
/* 逻辑尺寸:文本 + 内边距 + 边框(整数计算) */
|
||||||
int surface_pixel_h = (int)((box_logical_h + 2.0f * border) * scale + 0.5f);
|
int32_t logical_text_w = (int32_t)(text_pixel_w / scale + 0.5f);
|
||||||
|
int32_t logical_text_h = (int32_t)(text_pixel_h / scale + 0.5f);
|
||||||
|
int32_t box_logical_w = logical_text_w + 2 * node->padding_x;
|
||||||
|
int32_t box_logical_h = logical_text_h + 2 * node->padding_y;
|
||||||
|
|
||||||
if (surface_pixel_w < 1)
|
/* 加上边框后,乘以 scale 得到物理像素(表面尺寸),向上取整 */
|
||||||
surface_pixel_w = 1;
|
int32_t required_pixel_w =
|
||||||
if (surface_pixel_h < 1)
|
(int32_t)((box_logical_w + 2 * node->border_width) * scale + 0.5f);
|
||||||
surface_pixel_h = 1;
|
int32_t required_pixel_h =
|
||||||
|
(int32_t)((box_logical_h + 2 * node->border_width) * scale + 0.5f);
|
||||||
|
if (required_pixel_w < 1)
|
||||||
|
required_pixel_w = 1;
|
||||||
|
if (required_pixel_h < 1)
|
||||||
|
required_pixel_h = 1;
|
||||||
|
|
||||||
cairo_surface_t *surface = cairo_image_surface_create(
|
bool surface_size_changed = (!node->surface) ||
|
||||||
CAIRO_FORMAT_ARGB32, surface_pixel_w, surface_pixel_h);
|
(node->surface_pixel_w != required_pixel_w) ||
|
||||||
cairo_t *cr = cairo_create(surface);
|
(node->surface_pixel_h != required_pixel_h);
|
||||||
|
|
||||||
// 清空为全透明
|
if (surface_size_changed) {
|
||||||
|
if (node->buffer) {
|
||||||
|
wlr_buffer_drop(&node->buffer->base);
|
||||||
|
node->buffer = NULL;
|
||||||
|
}
|
||||||
|
if (node->surface) {
|
||||||
|
cairo_surface_destroy(node->surface);
|
||||||
|
node->surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->surface = cairo_image_surface_create(
|
||||||
|
CAIRO_FORMAT_ARGB32, required_pixel_w, required_pixel_h);
|
||||||
|
node->surface_pixel_w = required_pixel_w;
|
||||||
|
node->surface_pixel_h = required_pixel_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_t *cr = cairo_create(node->surface);
|
||||||
|
|
||||||
|
/* 清空为透明 */
|
||||||
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
|
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||||
|
|
||||||
double bg_x = border * scale;
|
/* 计算背景矩形(物理像素) */
|
||||||
double bg_y = border * scale;
|
double border = node->border_width * scale;
|
||||||
|
double bg_x = border;
|
||||||
|
double bg_y = border;
|
||||||
double bg_w = box_logical_w * scale;
|
double bg_w = box_logical_w * scale;
|
||||||
double bg_h = box_logical_h * scale;
|
double bg_h = box_logical_h * scale;
|
||||||
|
|
||||||
double radius = node->corner_radius * scale;
|
/* 圆角半径(物理像素) */
|
||||||
|
double radius;
|
||||||
if (radius < 0) {
|
if (node->corner_radius < 0) {
|
||||||
|
/* 负数表示自动取半宽/半高作为圆角 */
|
||||||
radius = (bg_w < bg_h ? bg_w : bg_h) / 2.0;
|
radius = (bg_w < bg_h ? bg_w : bg_h) / 2.0;
|
||||||
|
} else {
|
||||||
|
radius = node->corner_radius * scale;
|
||||||
}
|
}
|
||||||
|
/* 限制最大圆角 */
|
||||||
if (radius > bg_w / 2.0)
|
if (radius > bg_w / 2.0)
|
||||||
radius = bg_w / 2.0;
|
radius = bg_w / 2.0;
|
||||||
if (radius > bg_h / 2.0)
|
if (radius > bg_h / 2.0)
|
||||||
radius = bg_h / 2.0;
|
radius = bg_h / 2.0;
|
||||||
|
|
||||||
|
bool draw_bg = (node->bg_color[3] > 0.0f);
|
||||||
|
bool draw_border =
|
||||||
|
(node->border_width > 0) && (node->border_color[3] > 0.0f);
|
||||||
|
|
||||||
|
/* 绘制背景 */
|
||||||
if (draw_bg) {
|
if (draw_bg) {
|
||||||
cairo_set_source_rgba(cr, node->bg_color[0], node->bg_color[1],
|
cairo_set_source_rgba(cr, node->bg_color[0], node->bg_color[1],
|
||||||
node->bg_color[2], node->bg_color[3]);
|
node->bg_color[2], node->bg_color[3]);
|
||||||
|
|
@ -242,12 +323,16 @@ void mango_text_node_update(struct mango_text_node *node, const char *text,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 绘制文本 */
|
||||||
cairo_save(cr);
|
cairo_save(cr);
|
||||||
cairo_translate(cr, (border + pad_x) * scale, (border + pad_y) * scale);
|
double text_x = (node->border_width + node->padding_x) * scale;
|
||||||
|
double text_y = (node->border_width + node->padding_y) * scale;
|
||||||
|
cairo_translate(cr, text_x, text_y);
|
||||||
|
|
||||||
PangoContext *ctx = pango_cairo_create_context(cr);
|
PangoContext *ctx = pango_cairo_create_context(cr);
|
||||||
pango_cairo_context_set_resolution(ctx, 96.0 * scale);
|
pango_cairo_context_set_resolution(ctx, 96.0 * scale);
|
||||||
PangoLayout *layout = pango_layout_new(ctx);
|
PangoLayout *layout = pango_layout_new(ctx);
|
||||||
|
PangoFontDescription *desc = get_cached_font_desc(node->font_desc);
|
||||||
pango_layout_set_font_description(layout, desc);
|
pango_layout_set_font_description(layout, desc);
|
||||||
pango_layout_set_text(layout, text, -1);
|
pango_layout_set_text(layout, text, -1);
|
||||||
|
|
||||||
|
|
@ -259,50 +344,51 @@ void mango_text_node_update(struct mango_text_node *node, const char *text,
|
||||||
g_object_unref(ctx);
|
g_object_unref(ctx);
|
||||||
cairo_restore(cr);
|
cairo_restore(cr);
|
||||||
|
|
||||||
|
/* 绘制边框 */
|
||||||
if (draw_border) {
|
if (draw_border) {
|
||||||
cairo_set_source_rgba(cr, node->border_color[0], node->border_color[1],
|
cairo_set_source_rgba(cr, node->border_color[0], node->border_color[1],
|
||||||
node->border_color[2], node->border_color[3]);
|
node->border_color[2], node->border_color[3]);
|
||||||
cairo_set_line_width(cr, border * scale);
|
cairo_set_line_width(cr, border);
|
||||||
|
|
||||||
double half_lw = border * scale * 0.5;
|
double half_lw = border * 0.5;
|
||||||
double bx = bg_x - half_lw;
|
double bx = bg_x - half_lw;
|
||||||
double by = bg_y - half_lw;
|
double by = bg_y - half_lw;
|
||||||
double bw = bg_w + border * scale;
|
double bw = bg_w + border;
|
||||||
double bh = bg_h + border * scale;
|
double bh = bg_h + border;
|
||||||
|
|
||||||
if (radius > 0.0) {
|
if (radius > 0.0) {
|
||||||
double outer_radius = radius + half_lw;
|
double outer_radius = radius + half_lw;
|
||||||
if (outer_radius < 0.0)
|
if (outer_radius < 0.0)
|
||||||
outer_radius = 0.0;
|
outer_radius = 0.0;
|
||||||
draw_rounded_rect(cr, bx, by, bw, bh, outer_radius);
|
draw_rounded_rect(cr, bx, by, bw, bh, outer_radius);
|
||||||
cairo_stroke(cr);
|
|
||||||
} else {
|
} else {
|
||||||
cairo_rectangle(cr, bx, by, bw, bh);
|
cairo_rectangle(cr, bx, by, bw, bh);
|
||||||
cairo_stroke(cr);
|
|
||||||
}
|
}
|
||||||
|
cairo_stroke(cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_flush(surface);
|
cairo_surface_flush(node->surface);
|
||||||
|
cairo_destroy(cr);
|
||||||
|
|
||||||
|
/* 更新 wlr_buffer */
|
||||||
|
if (node->buffer) {
|
||||||
|
wlr_buffer_drop(&node->buffer->base);
|
||||||
|
node->buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// 包装成 wlr_buffer
|
|
||||||
struct mango_text_buffer *buf = calloc(1, sizeof(*buf));
|
struct mango_text_buffer *buf = calloc(1, sizeof(*buf));
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
cairo_surface_destroy(surface);
|
|
||||||
cairo_destroy(cr);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wlr_buffer_init(&buf->base, &text_buffer_impl, surface_pixel_w,
|
wlr_buffer_init(&buf->base, &text_buffer_impl, node->surface_pixel_w,
|
||||||
surface_pixel_h);
|
node->surface_pixel_h);
|
||||||
buf->surface = surface;
|
buf->surface = node->surface;
|
||||||
|
node->buffer = buf;
|
||||||
|
|
||||||
wlr_scene_buffer_set_buffer(node->scene_buffer, &buf->base);
|
wlr_scene_buffer_set_buffer(node->scene_buffer, &buf->base);
|
||||||
wlr_buffer_drop(&buf->base);
|
|
||||||
|
|
||||||
// 最终逻辑大小 = 背景框逻辑尺寸 + 边框逻辑尺寸
|
node->logical_width = box_logical_w + 2 * node->border_width;
|
||||||
node->logical_width = (int)(box_logical_w + 2.0f * border);
|
node->logical_height = box_logical_h + 2 * node->border_width;
|
||||||
node->logical_height = (int)(box_logical_h + 2.0f * border);
|
|
||||||
wlr_scene_buffer_set_dest_size(node->scene_buffer, node->logical_width,
|
wlr_scene_buffer_set_dest_size(node->scene_buffer, node->logical_width,
|
||||||
node->logical_height);
|
node->logical_height);
|
||||||
|
|
||||||
cairo_destroy(cr);
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,24 +1,50 @@
|
||||||
#ifndef MANGO_TEXT_NODE_H
|
#ifndef MANGO_TEXT_NODE_H
|
||||||
#define MANGO_TEXT_NODE_H
|
#define MANGO_TEXT_NODE_H
|
||||||
|
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <pango/pangocairo.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
|
||||||
|
// 自定义 wlr_buffer,仅用于包装 cairo surface,不负责 surface 的销毁
|
||||||
|
struct mango_text_buffer {
|
||||||
|
struct wlr_buffer base;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
};
|
||||||
|
|
||||||
struct mango_text_node {
|
struct mango_text_node {
|
||||||
struct wlr_scene_buffer *scene_buffer;
|
struct wlr_scene_buffer *scene_buffer;
|
||||||
int logical_width;
|
|
||||||
int logical_height;
|
|
||||||
const char *font_desc;
|
|
||||||
|
|
||||||
// 外观属性
|
float fg_color[4];
|
||||||
float fg_color[4]; // 文本颜色 RGBA,默认白色
|
float bg_color[4];
|
||||||
float bg_color[4]; // 背景色 RGBA,默认透明
|
float border_color[4];
|
||||||
float border_color[4]; // 边框色 RGBA,默认透明
|
int32_t border_width;
|
||||||
int32_t border_width; // 边框宽度(逻辑像素),<=0 则不绘制
|
int32_t corner_radius;
|
||||||
int32_t corner_radius; // 圆角半径(逻辑像素),<0 时自动取
|
int32_t padding_x, padding_y;
|
||||||
// min(width,height)/2 形成胶囊
|
char *font_desc;
|
||||||
int32_t padding_x; // 文本左右内边距(逻辑像素)
|
|
||||||
int32_t padding_y; // 文本上下内边距(逻辑像素)
|
char *cached_text;
|
||||||
|
float cached_scale;
|
||||||
|
float cached_fg_color[4];
|
||||||
|
float cached_bg_color[4];
|
||||||
|
float cached_border_color[4];
|
||||||
|
float cached_border_width;
|
||||||
|
float cached_corner_radius;
|
||||||
|
float cached_padding_x, cached_padding_y;
|
||||||
|
char *cached_font_desc;
|
||||||
|
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
struct mango_text_buffer *buffer;
|
||||||
|
int32_t surface_pixel_w, surface_pixel_h;
|
||||||
|
|
||||||
|
cairo_surface_t *measure_surface;
|
||||||
|
cairo_t *measure_cr;
|
||||||
|
PangoContext *measure_context;
|
||||||
|
PangoLayout *measure_layout;
|
||||||
|
float measure_scale;
|
||||||
|
|
||||||
|
int32_t logical_width;
|
||||||
|
int32_t logical_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -38,15 +64,15 @@ void mango_text_node_destroy(struct mango_text_node *node);
|
||||||
void mango_text_node_update(struct mango_text_node *node, const char *text,
|
void mango_text_node_update(struct mango_text_node *node, const char *text,
|
||||||
float scale);
|
float scale);
|
||||||
|
|
||||||
// 外观设置接口
|
|
||||||
void mango_text_node_set_background(struct mango_text_node *node, float r,
|
void mango_text_node_set_background(struct mango_text_node *node, float r,
|
||||||
float g, float b, float a);
|
float g, float b, float a);
|
||||||
void mango_text_node_set_border(struct mango_text_node *node, float r, float g,
|
void mango_text_node_set_border(struct mango_text_node *node, float r, float g,
|
||||||
float b, float a, float width, float radius);
|
float b, float a, int32_t width,
|
||||||
void mango_text_node_set_padding(struct mango_text_node *node, float pad_x,
|
int32_t radius);
|
||||||
float pad_y);
|
|
||||||
|
void mango_text_node_set_padding(struct mango_text_node *node, int32_t pad_x,
|
||||||
|
int32_t pad_y);
|
||||||
|
|
||||||
void mango_text_node_destroy(struct mango_text_node *node);
|
|
||||||
void mango_text_global_finish(void);
|
void mango_text_global_finish(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -259,7 +259,8 @@ static void dwindle_assign(DwindleNode *node, int32_t ax, int32_t ay,
|
||||||
if (node->client) {
|
if (node->client) {
|
||||||
if (!node->client->isfullscreen &&
|
if (!node->client->isfullscreen &&
|
||||||
!node->client->ismaximizescreen) {
|
!node->client->ismaximizescreen) {
|
||||||
struct wlr_box box = {ax, ay, MAX(1, aw), MAX(1, ah)};
|
struct wlr_box box = {ax, ay, MANGO_MAX(1, aw),
|
||||||
|
MANGO_MAX(1, ah)};
|
||||||
resize(node->client, box, 0);
|
resize(node->client, box, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -273,12 +274,12 @@ static void dwindle_assign(DwindleNode *node, int32_t ax, int32_t ay,
|
||||||
node->container_w = aw;
|
node->container_w = aw;
|
||||||
node->container_h = ah;
|
node->container_h = ah;
|
||||||
if (node->split_h) {
|
if (node->split_h) {
|
||||||
int32_t w1 = MAX(1, (int32_t)(aw * node->ratio) - gap_h / 2);
|
int32_t w1 = MANGO_MAX(1, (int32_t)(aw * node->ratio) - gap_h / 2);
|
||||||
dwindle_assign(node->first, ax, ay, w1, ah, gap_h, gap_v);
|
dwindle_assign(node->first, ax, ay, w1, ah, gap_h, gap_v);
|
||||||
dwindle_assign(node->second, ax + w1 + gap_h, ay, aw - w1 - gap_h, ah,
|
dwindle_assign(node->second, ax + w1 + gap_h, ay, aw - w1 - gap_h, ah,
|
||||||
gap_h, gap_v);
|
gap_h, gap_v);
|
||||||
} else {
|
} else {
|
||||||
int32_t h1 = MAX(1, (int32_t)(ah * node->ratio) - gap_v / 2);
|
int32_t h1 = MANGO_MAX(1, (int32_t)(ah * node->ratio) - gap_v / 2);
|
||||||
dwindle_assign(node->first, ax, ay, aw, h1, gap_h, gap_v);
|
dwindle_assign(node->first, ax, ay, aw, h1, gap_h, gap_v);
|
||||||
dwindle_assign(node->second, ax, ay + h1 + gap_v, aw, ah - h1 - gap_v,
|
dwindle_assign(node->second, ax, ay + h1 + gap_v, aw, ah - h1 - gap_v,
|
||||||
gap_h, gap_v);
|
gap_h, gap_v);
|
||||||
|
|
@ -357,7 +358,7 @@ static void dwindle_resize_client(Monitor *m, Client *c) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dwindle_locked_h_node) {
|
if (dwindle_locked_h_node) {
|
||||||
float cw = (float)MAX(1, dwindle_locked_h_node->container_w);
|
float cw = (float)MANGO_MAX(1, dwindle_locked_h_node->container_w);
|
||||||
float ox = (float)(cursor->x - drag_begin_cursorx);
|
float ox = (float)(cursor->x - drag_begin_cursorx);
|
||||||
if (config.dwindle_smart_resize) {
|
if (config.dwindle_smart_resize) {
|
||||||
/* Move the boundary toward the cursor: invert direction when
|
/* Move the boundary toward the cursor: invert direction when
|
||||||
|
|
@ -374,7 +375,7 @@ static void dwindle_resize_client(Monitor *m, Client *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwindle_locked_v_node) {
|
if (dwindle_locked_v_node) {
|
||||||
float ch = (float)MAX(1, dwindle_locked_v_node->container_h);
|
float ch = (float)MANGO_MAX(1, dwindle_locked_v_node->container_h);
|
||||||
float oy = (float)(cursor->y - drag_begin_cursory);
|
float oy = (float)(cursor->y - drag_begin_cursory);
|
||||||
if (config.dwindle_smart_resize) {
|
if (config.dwindle_smart_resize) {
|
||||||
/* Same logic for the vertical split line. */
|
/* Same logic for the vertical split line. */
|
||||||
|
|
@ -427,13 +428,13 @@ static void dwindle_resize_client_step(Monitor *m, Client *c, int32_t dx,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (h_node && dx) {
|
if (h_node && dx) {
|
||||||
float cw = (float)MAX(1, h_node->container_w);
|
float cw = (float)MANGO_MAX(1, h_node->container_w);
|
||||||
float delta = (float)dx / cw;
|
float delta = (float)dx / cw;
|
||||||
h_node->ratio = CLAMP_FLOAT(h_node->ratio + delta, 0.05f, 0.95f);
|
h_node->ratio = CLAMP_FLOAT(h_node->ratio + delta, 0.05f, 0.95f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v_node && dy) {
|
if (v_node && dy) {
|
||||||
float ch = (float)MAX(1, v_node->container_h);
|
float ch = (float)MANGO_MAX(1, v_node->container_h);
|
||||||
float delta = (float)dy / ch;
|
float delta = (float)dy / ch;
|
||||||
v_node->ratio = CLAMP_FLOAT(v_node->ratio + delta, 0.05f, 0.95f);
|
v_node->ratio = CLAMP_FLOAT(v_node->ratio + delta, 0.05f, 0.95f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ void tile(Monitor *m) {
|
||||||
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
||||||
continue;
|
continue;
|
||||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||||
r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
r = MANGO_MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
||||||
if (c->master_inner_per > 0.0f) {
|
if (c->master_inner_per > 0.0f) {
|
||||||
h = master_surplus_height * c->master_inner_per /
|
h = master_surplus_height * c->master_inner_per /
|
||||||
master_surplus_ratio;
|
master_surplus_ratio;
|
||||||
|
|
@ -179,7 +179,7 @@ void right_tile(Monitor *m) {
|
||||||
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
||||||
continue;
|
continue;
|
||||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||||
r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
r = MANGO_MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
||||||
if (c->master_inner_per > 0.0f) {
|
if (c->master_inner_per > 0.0f) {
|
||||||
h = master_surplus_height * c->master_inner_per /
|
h = master_surplus_height * c->master_inner_per /
|
||||||
master_surplus_ratio;
|
master_surplus_ratio;
|
||||||
|
|
@ -345,7 +345,7 @@ void center_tile(Monitor *m) {
|
||||||
|
|
||||||
if (i < nmasters) {
|
if (i < nmasters) {
|
||||||
// 主区域窗口
|
// 主区域窗口
|
||||||
r = MIN(n, nmasters) - i;
|
r = MANGO_MIN(n, nmasters) - i;
|
||||||
if (c->master_inner_per > 0.0f) {
|
if (c->master_inner_per > 0.0f) {
|
||||||
h = master_surplus_height * c->master_inner_per /
|
h = master_surplus_height * c->master_inner_per /
|
||||||
master_surplus_ratio;
|
master_surplus_ratio;
|
||||||
|
|
@ -518,8 +518,8 @@ void deck(Monitor *m) {
|
||||||
continue;
|
continue;
|
||||||
if (i < nmasters) {
|
if (i < nmasters) {
|
||||||
c->master_mfact_per = mfact;
|
c->master_mfact_per = mfact;
|
||||||
int32_t h =
|
int32_t h = (m->w.height - 2 * cur_gappov - my) /
|
||||||
(m->w.height - 2 * cur_gappov - my) / (MIN(n, nmasters) - i);
|
(MANGO_MIN(n, nmasters) - i);
|
||||||
client_tile_resize(c,
|
client_tile_resize(c,
|
||||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||||
.y = m->w.y + cur_gappov + my,
|
.y = m->w.y + cur_gappov + my,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ void vertical_tile(Monitor *m) {
|
||||||
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
||||||
continue;
|
continue;
|
||||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||||
r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
r = MANGO_MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
||||||
if (c->master_inner_per > 0.0f) {
|
if (c->master_inner_per > 0.0f) {
|
||||||
w = master_surplus_width * c->master_inner_per /
|
w = master_surplus_width * c->master_inner_per /
|
||||||
master_surplus_ratio;
|
master_surplus_ratio;
|
||||||
|
|
@ -155,8 +155,8 @@ void vertical_deck(Monitor *m) {
|
||||||
continue;
|
continue;
|
||||||
if (i < nmasters) {
|
if (i < nmasters) {
|
||||||
c->master_mfact_per = mfact;
|
c->master_mfact_per = mfact;
|
||||||
int32_t w =
|
int32_t w = (m->w.width - 2 * cur_gappoh - mx) /
|
||||||
(m->w.width - 2 * cur_gappoh - mx) / (MIN(n, nmasters) - i);
|
(MANGO_MIN(n, nmasters) - i);
|
||||||
client_tile_resize(c,
|
client_tile_resize(c,
|
||||||
(struct wlr_box){.x = m->w.x + cur_gappoh + mx,
|
(struct wlr_box){.x = m->w.x + cur_gappoh + mx,
|
||||||
.y = m->w.y + cur_gappov,
|
.y = m->w.y + cur_gappov,
|
||||||
|
|
|
||||||
18
src/mango.c
18
src/mango.c
|
|
@ -97,8 +97,8 @@
|
||||||
#include "draw/text-node.h"
|
#include "draw/text-node.h"
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MANGO_MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
#define MANGO_MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
#define GEZERO(A) ((A) >= 0 ? (A) : 0)
|
#define GEZERO(A) ((A) >= 0 ? (A) : 0)
|
||||||
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
|
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
|
||||||
#define INSIDEMON(A) \
|
#define INSIDEMON(A) \
|
||||||
|
|
@ -1151,8 +1151,8 @@ void client_change_mon(Client *c, Monitor *m) {
|
||||||
|
|
||||||
void applybounds(Client *c, struct wlr_box *bbox) {
|
void applybounds(Client *c, struct wlr_box *bbox) {
|
||||||
/* set minimum possible */
|
/* set minimum possible */
|
||||||
c->geom.width = MAX(1 + 2 * (int32_t)c->bw, c->geom.width);
|
c->geom.width = MANGO_MAX(1 + 2 * (int32_t)c->bw, c->geom.width);
|
||||||
c->geom.height = MAX(1 + 2 * (int32_t)c->bw, c->geom.height);
|
c->geom.height = MANGO_MAX(1 + 2 * (int32_t)c->bw, c->geom.height);
|
||||||
|
|
||||||
if (c->geom.x >= bbox->x + bbox->width)
|
if (c->geom.x >= bbox->x + bbox->width)
|
||||||
c->geom.x = bbox->x + bbox->width - c->geom.width;
|
c->geom.x = bbox->x + bbox->width - c->geom.width;
|
||||||
|
|
@ -1575,7 +1575,7 @@ void set_float_malposition(Client *tc) {
|
||||||
y = tc->geom.y;
|
y = tc->geom.y;
|
||||||
xreverse = 1;
|
xreverse = 1;
|
||||||
yreverse = 1;
|
yreverse = 1;
|
||||||
offset = MIN(tc->mon->w.width / 20, tc->mon->w.height / 20);
|
offset = MANGO_MIN(tc->mon->w.width / 20, tc->mon->w.height / 20);
|
||||||
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c->isfloating && c != tc && VISIBLEON(c, tc->mon) &&
|
if (c->isfloating && c != tc && VISIBLEON(c, tc->mon) &&
|
||||||
|
|
@ -5613,10 +5613,10 @@ void setfullscreen(Client *c, int32_t fullscreen,
|
||||||
}
|
}
|
||||||
|
|
||||||
void setgaps(int32_t oh, int32_t ov, int32_t ih, int32_t iv) {
|
void setgaps(int32_t oh, int32_t ov, int32_t ih, int32_t iv) {
|
||||||
selmon->gappoh = MAX(oh, 0);
|
selmon->gappoh = MANGO_MAX(oh, 0);
|
||||||
selmon->gappov = MAX(ov, 0);
|
selmon->gappov = MANGO_MAX(ov, 0);
|
||||||
selmon->gappih = MAX(ih, 0);
|
selmon->gappih = MANGO_MAX(ih, 0);
|
||||||
selmon->gappiv = MAX(iv, 0);
|
selmon->gappiv = MANGO_MAX(iv, 0);
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue