From 956c6338a6df9d11a5289a8fddaa58b68e8f3358 Mon Sep 17 00:00:00 2001 From: chenyc Date: Sun, 6 Apr 2025 15:18:10 +0800 Subject: [PATCH] feat: support windowrule offsetx & offsety --- config.conf | 2 ++ maomao.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- parse_config.h | 8 ++++++++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/config.conf b/config.conf index 1651b5a..19fd311 100644 --- a/config.conf +++ b/config.conf @@ -106,6 +106,8 @@ tags=id:9,layout_name:tile # animation_type_close : type-string(zoom,slide) # isnoborder : type-num(0 or 1) # monitor : type-num(0-99999) +# offsetx : type-num(-100-100) -- Offset relative to the center, 0 is center, -100 is left, 100 is right (unit %) +# offsety : type-num(-100-100) -- Offset relative to the center , 0 is center, -100 is top, 100 is bottom (unit %) # width : type-num(0-9999) # height : type-num(0-9999) # isterm : type-num (0 or 1) -- when new window open, will replace it, and will restore after the sub window exit diff --git a/maomao.c b/maomao.c index 4009c04..33f9b0d 100644 --- a/maomao.c +++ b/maomao.c @@ -569,7 +569,7 @@ static void handle_foreign_close_request(struct wl_listener *listener, void *data); static void handle_foreign_destroy(struct wl_listener *listener, void *data); -static struct wlr_box setclient_coordinate_center(struct wlr_box geom); +static struct wlr_box setclient_coordinate_center(struct wlr_box geom, int offsetx, int offsety); static unsigned int get_tags_first_tag(unsigned int tags); void client_commit(Client *c); @@ -1250,7 +1250,7 @@ void show_scratchpad(Client *c) { c->geom.width = c->mon->w.width * 0.7; c->geom.height = c->mon->w.height * 0.8; // 重新计算居中的坐标 - c->geom = setclient_coordinate_center(c->geom); + c->geom = setclient_coordinate_center(c->geom, 0, 0); resize(c, c->geom, 0); } c->oldtags = selmon->tagset[selmon->seltags]; @@ -1431,16 +1431,47 @@ void toggle_hotarea(int x_root, int y_root) { } struct wlr_box // 计算客户端居中坐标 -setclient_coordinate_center(struct wlr_box geom) { +setclient_coordinate_center(struct wlr_box geom, int offsetx, int offsety) { struct wlr_box tempbox; + int offset = 0; + int len = 0; + tempbox.x = selmon->w.x + (selmon->w.width - geom.width) / 2; tempbox.y = selmon->w.y + (selmon->w.height - geom.height) / 2; tempbox.width = geom.width; tempbox.height = geom.height; + + if (offsetx != 0) { + len = (selmon->w.width - geom.width) / 2 - gappoh; + offset = len * (offsetx / 100.0); + tempbox.x += offset; + + // 限制窗口在屏幕内 + if (tempbox.x < selmon->m.x) { + tempbox.x = selmon->m.x; + } + if (tempbox.x + tempbox.width > selmon->m.x + selmon->m.width) { + tempbox.x = selmon->m.x + selmon->m.width - tempbox.width; + } + } + if (offsety != 0) { + len = (selmon->w.height - geom.height) / 2 - gappov; + offset = len * (offsety / 100.0); + tempbox.y += offset; + + // 限制窗口在屏幕内 + if (tempbox.y < selmon->m.y) { + tempbox.y = selmon->m.y; + } + if (tempbox.y + tempbox.height > selmon->m.y + selmon->m.height) { + tempbox.y = selmon->m.y + selmon->m.height - tempbox.height; + } + } + return tempbox; } - /* function implementations */ + void logtofile(const char *fmt, ...) { char buf[256]; char cmd[256]; @@ -1483,8 +1514,8 @@ applyrulesgeom(Client *c) { c->geom.width = r->width > 0 ? r->width : c->geom.width; c->geom.height = r->height > 0 ? r->height : c->geom.height; // 重新计算居中的坐标 - c->geom = setclient_coordinate_center(c->geom); - hit = r->height > 0 || r->width > 0 ? 1 : 0; + c->geom = setclient_coordinate_center(c->geom, r->offsetx, r->offsety); + hit = r->height > 0 || r->width > 0 || r->offsetx != 0 || r->offsety != 0 ? 1 : 0; } } return hit; @@ -1535,7 +1566,7 @@ applyrules(Client *c) { c->geom.width = r->width > 0 ? r->width : c->geom.width; c->geom.height = r->height > 0 ? r->height : c->geom.height; // 重新计算居中的坐标 - c->geom = setclient_coordinate_center(c->geom); + c->geom = setclient_coordinate_center(c->geom, r->offsetx, r->offsety); } } } @@ -4906,7 +4937,7 @@ setfloating(Client *c, int floating) { target_box.width = target_box.width * 0.8; } // 重新计算居中的坐标 - target_box = setclient_coordinate_center(target_box); + target_box = setclient_coordinate_center(target_box, 0, 0); backup_box = c->geom; hit = applyrulesgeom(c); target_box = hit == 1 ? c->geom : target_box; @@ -5694,7 +5725,7 @@ void tagmon(const Arg *arg) { c->geom.height = (int)(c->geom.height * c->mon->w.height / selmon->w.height); selmon = c->mon; - c->geom = setclient_coordinate_center(c->geom); + c->geom = setclient_coordinate_center(c->geom, 0, 0); focusclient(c, 1); resize(c, c->geom, 1); } else { diff --git a/parse_config.h b/parse_config.h index a045973..85512a7 100644 --- a/parse_config.h +++ b/parse_config.h @@ -26,6 +26,8 @@ typedef struct { int isnoborder; int isopensilent; int monitor; + int offsetx; + int offsety; int width; int height; int isterm; @@ -818,6 +820,8 @@ void parse_config_line(Config *config, const char *line) { rule->isterm = -1; rule->noswallow = -1; rule->monitor = -1; + rule->offsetx = 0; + rule->offsety = 0; rule->width = -1; rule->height = -1; rule->animation_type_open = NULL; @@ -850,6 +854,10 @@ void parse_config_line(Config *config, const char *line) { rule->tags = 1 << (atoi(val) - 1); } else if (strcmp(key, "monitor") == 0) { rule->monitor = atoi(val); + } else if (strcmp(key, "offsetx") == 0) { + rule->offsetx = atoi(val); + } else if (strcmp(key, "offsety") == 0) { + rule->offsety = atoi(val); } else if (strcmp(key, "width") == 0) { rule->width = atoi(val); } else if (strcmp(key, "height") == 0) {