mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-10-29 05:40:21 -04:00
feat: support resize tile window
This commit is contained in:
parent
aec8c29210
commit
ca48f95997
13 changed files with 1060 additions and 677 deletions
15
README.md
15
README.md
|
|
@ -16,7 +16,7 @@ This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
|
|||
- Base tags not workspaces (supports separate window layouts for each tag)
|
||||
- Smooth and customizable complete animations (window open/move/close, tag enter/leave,layer open/close/move)
|
||||
- Excellent input method support (text input v2/v3)
|
||||
- Flexible window layouts with easy switching (scroller, master, monocle, spiral, etc.)
|
||||
- Flexible window layouts with easy switching (scroller, master-stack, monocle,center-master, etc.)
|
||||
- Rich window states (swallow, minimize, maximize, unglobal, global, fakefullscreen, overlay, etc.)
|
||||
- Simple yet powerful external configuration(support shortcuts hot-reload)
|
||||
- Sway-like scratchpad and named scratchpad
|
||||
|
|
@ -24,10 +24,6 @@ This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
|
|||
- Hycov-like overview
|
||||
- Window effects from scenefx (blur, shadow, corner radius, opacity)
|
||||
|
||||
3. **Some disadvantages**
|
||||
- Since it uses the fully automatic layout like dwm style, it does not allow you to manually adjust the window size when the window is in tiled state. It only allows you to use dispatch like `setmfact` or `increase_proportion` bind to adjust the tiled window ratio.
|
||||
|
||||
|
||||
Master-Stack Layout
|
||||
|
||||
https://github.com/user-attachments/assets/a9d4776e-b50b-48fb-94ce-651d8a749b8a
|
||||
|
|
@ -43,23 +39,14 @@ https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
|
|||
|
||||
# Supported layouts
|
||||
|
||||
## Horizontal Layouts
|
||||
- tile
|
||||
- scroller
|
||||
- monocle
|
||||
- grid
|
||||
- dwindle
|
||||
- spiral
|
||||
- deck
|
||||
- center_tile
|
||||
|
||||
## Vertical Layouts
|
||||
- vertical_tile
|
||||
- vertical_scroller
|
||||
- vertical_monocle
|
||||
- vertical_grid
|
||||
- vertical_dwindle
|
||||
- vertical_spiral
|
||||
|
||||
# Installation
|
||||
|
||||
|
|
|
|||
16
config.conf
16
config.conf
|
|
@ -56,7 +56,7 @@ edge_scroller_pointer_focus=1
|
|||
scroller_default_proportion_single=1.0
|
||||
scroller_proportion_preset=0.5,0.8,1.0
|
||||
|
||||
# Master-Stack Layout Setting (tile,spiral,dwindle)
|
||||
# Master-Stack Layout Setting
|
||||
new_is_master=1
|
||||
default_mfact=0.55
|
||||
default_nmaster=1
|
||||
|
|
@ -123,8 +123,7 @@ globalcolor=0xb153a7ff
|
|||
overlaycolor=0x14a57cff
|
||||
|
||||
# layout support:
|
||||
# horizontal:tile,scroller,grid,monocle,spiral,dwindle,center_tile
|
||||
# vertical:vertical_tile,vertical_scroller,vertical_grid,vertical_spiral,vertical_dwindle
|
||||
# tile,scroller,grid,deck,monocle,center_tile,vertical_tile,vertical_scroller
|
||||
tagrule=id:1,layout_name:tile
|
||||
tagrule=id:2,layout_name:tile
|
||||
tagrule=id:3,layout_name:tile
|
||||
|
|
@ -224,17 +223,6 @@ bind=ALT+SHIFT,X,incgaps,1
|
|||
bind=ALT+SHIFT,Z,incgaps,-1
|
||||
bind=ALT+SHIFT,R,togglegaps
|
||||
|
||||
# adjust tile window size
|
||||
# change master fact for tile,spiral,deck,dwindle
|
||||
bind=ALT+SUPER,h,setmfact,-0.05
|
||||
bind=ALT+SUPER,l,setmfact,+0.05
|
||||
# change sub master fact for dwindle,spiral
|
||||
bind=ALT+SUPER,k,setsmfact,-0.05
|
||||
bind=ALT+SUPER,j,setsmfact,+0.05
|
||||
# change scroller proportion
|
||||
bind=ctrl+super,j,increase_proportion,0.1
|
||||
bind=ctrl+super,k,increase_proportion,-0.1
|
||||
|
||||
# movewin
|
||||
bind=CTRL+SHIFT,Up,movewin,+0,-50
|
||||
bind=CTRL+SHIFT,Down,movewin,+0,+50
|
||||
|
|
|
|||
|
|
@ -31,10 +31,8 @@ enum corner_location set_client_corner_location(Client *c) {
|
|||
bool is_horizontal_stack_layout(Monitor *m) {
|
||||
|
||||
if (m->pertag->curtag &&
|
||||
(strcmp(m->pertag->ltidxs[m->pertag->curtag]->name, "tile") == 0 ||
|
||||
strcmp(m->pertag->ltidxs[m->pertag->curtag]->name, "spiral") == 0 ||
|
||||
strcmp(m->pertag->ltidxs[m->pertag->curtag]->name, "dwindle") == 0 ||
|
||||
strcmp(m->pertag->ltidxs[m->pertag->curtag]->name, "deck") == 0))
|
||||
(m->pertag->ltidxs[m->pertag->curtag]->id == TILE ||
|
||||
m->pertag->ltidxs[m->pertag->curtag]->id == DECK))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -897,6 +895,11 @@ void client_set_pending_state(Client *c) {
|
|||
c->istagswitching = 0;
|
||||
}
|
||||
|
||||
if (start_drag_window) {
|
||||
c->animation.should_animate = false;
|
||||
c->animation.duration = 0;
|
||||
}
|
||||
|
||||
// 开始动画
|
||||
client_commit(c);
|
||||
c->dirty = true;
|
||||
|
|
|
|||
|
|
@ -202,10 +202,9 @@ typedef struct {
|
|||
|
||||
unsigned int new_is_master;
|
||||
float default_mfact;
|
||||
float default_smfact;
|
||||
unsigned int default_nmaster;
|
||||
int center_master_overspread;
|
||||
int center_when_single_slave;
|
||||
int center_when_single_stack;
|
||||
|
||||
unsigned int hotarea_size;
|
||||
unsigned int enable_hotarea;
|
||||
|
|
@ -727,9 +726,6 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
|
|||
} else if (strcmp(func_name, "setmfact") == 0) {
|
||||
func = setmfact;
|
||||
(*arg).f = atof(arg_value);
|
||||
} else if (strcmp(func_name, "setsmfact") == 0) {
|
||||
func = setsmfact;
|
||||
(*arg).f = atof(arg_value);
|
||||
} else if (strcmp(func_name, "zoom") == 0) {
|
||||
func = zoom;
|
||||
} else if (strcmp(func_name, "exchange_client") == 0) {
|
||||
|
|
@ -1262,14 +1258,12 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
config->new_is_master = atoi(value);
|
||||
} else if (strcmp(key, "default_mfact") == 0) {
|
||||
config->default_mfact = atof(value);
|
||||
} else if (strcmp(key, "default_smfact") == 0) {
|
||||
config->default_smfact = atof(value);
|
||||
} else if (strcmp(key, "default_nmaster") == 0) {
|
||||
config->default_nmaster = atoi(value);
|
||||
} else if (strcmp(key, "center_master_overspread") == 0) {
|
||||
config->center_master_overspread = atoi(value);
|
||||
} else if (strcmp(key, "center_when_single_slave") == 0) {
|
||||
config->center_when_single_slave = atoi(value);
|
||||
} else if (strcmp(key, "center_when_single_stack") == 0) {
|
||||
config->center_when_single_stack = atoi(value);
|
||||
} else if (strcmp(key, "hotarea_size") == 0) {
|
||||
config->hotarea_size = atoi(value);
|
||||
} else if (strcmp(key, "enable_hotarea") == 0) {
|
||||
|
|
@ -2478,10 +2472,9 @@ void override_config(void) {
|
|||
|
||||
// 主从布局设置
|
||||
default_mfact = CLAMP_FLOAT(config.default_mfact, 0.1f, 0.9f);
|
||||
default_smfact = CLAMP_FLOAT(config.default_smfact, 0.1f, 0.9f);
|
||||
default_nmaster = CLAMP_INT(config.default_nmaster, 1, 1000);
|
||||
center_master_overspread = CLAMP_INT(config.center_master_overspread, 0, 1);
|
||||
center_when_single_slave = CLAMP_INT(config.center_when_single_slave, 0, 1);
|
||||
center_when_single_stack = CLAMP_INT(config.center_when_single_stack, 0, 1);
|
||||
new_is_master = CLAMP_INT(config.new_is_master, 0, 1);
|
||||
|
||||
// 概述模式设置
|
||||
|
|
@ -2624,15 +2617,14 @@ void set_value_default() {
|
|||
config.axis_bind_apply_timeout =
|
||||
axis_bind_apply_timeout; // 滚轮绑定动作的触发的时间间隔
|
||||
config.focus_on_activate =
|
||||
focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦
|
||||
config.new_is_master = new_is_master; // 新窗口是否插在头部
|
||||
config.default_mfact = default_mfact; // master 窗口比例
|
||||
config.default_smfact = default_smfact; // 第一个stack比例
|
||||
focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦
|
||||
config.new_is_master = new_is_master; // 新窗口是否插在头部
|
||||
config.default_mfact = default_mfact; // master 窗口比例
|
||||
config.default_nmaster = default_nmaster; // 默认master数量
|
||||
config.center_master_overspread =
|
||||
center_master_overspread; // 中心master时是否铺满
|
||||
config.center_when_single_slave =
|
||||
center_when_single_slave; // 单个slave时是否居中
|
||||
config.center_when_single_stack =
|
||||
center_when_single_stack; // 单个stack时是否居中
|
||||
|
||||
config.numlockon = numlockon; // 是否打开右边小键盘
|
||||
|
||||
|
|
@ -2983,7 +2975,6 @@ void reapply_master(void) {
|
|||
}
|
||||
m->pertag->nmasters[i] = default_nmaster;
|
||||
m->pertag->mfacts[i] = default_mfact;
|
||||
m->pertag->smfacts[i] = default_smfact;
|
||||
m->gappih = gappih;
|
||||
m->gappiv = gappiv;
|
||||
m->gappoh = gappoh;
|
||||
|
|
|
|||
|
|
@ -35,10 +35,9 @@ unsigned int axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时
|
|||
unsigned int focus_on_activate = 1; // 收到窗口激活请求是否自动跳转聚焦
|
||||
unsigned int new_is_master = 1; // 新窗口是否插在头部
|
||||
double default_mfact = 0.55f; // master 窗口比例
|
||||
double default_smfact = 0.5f; // 第一个stack窗口比例
|
||||
unsigned int default_nmaster = 1; // 默认master数量
|
||||
int center_master_overspread = 0; // 中心master时是否铺满
|
||||
int center_when_single_slave = 1; // 单个slave时是否居中
|
||||
int center_when_single_stack = 1; // 单个stack时是否居中
|
||||
/* logging */
|
||||
int log_level = WLR_ERROR;
|
||||
unsigned int numlockon = 1; // 是否打开右边小键盘
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ void setlayout(const Arg *arg);
|
|||
void switch_layout(const Arg *arg);
|
||||
void switch_keyboard_layout(const Arg *arg);
|
||||
void setmfact(const Arg *arg);
|
||||
void setsmfact(const Arg *arg);
|
||||
void quit(const Arg *arg);
|
||||
void moveresize(const Arg *arg);
|
||||
void exchange_client(const Arg *arg);
|
||||
|
|
|
|||
|
|
@ -263,20 +263,6 @@ void increase_proportion(const Arg *arg) {
|
|||
}
|
||||
}
|
||||
|
||||
void setsmfact(const Arg *arg) {
|
||||
float f;
|
||||
|
||||
if (!arg || !selmon ||
|
||||
!selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange)
|
||||
return;
|
||||
f = arg->f < 1.0 ? arg->f + selmon->pertag->smfacts[selmon->pertag->curtag]
|
||||
: arg->f - 1.0;
|
||||
if (f < 0.1 || f > 0.9)
|
||||
return;
|
||||
// selmon->mfact = f;
|
||||
selmon->pertag->smfacts[selmon->pertag->curtag] = f;
|
||||
arrange(selmon, false);
|
||||
}
|
||||
/* arg > 1.0 will set mfact absolutely */
|
||||
void // 17
|
||||
setmfact(const Arg *arg) {
|
||||
|
|
@ -309,15 +295,15 @@ moveresize(const Arg *arg) {
|
|||
xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL);
|
||||
if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen)
|
||||
return;
|
||||
|
||||
/* Float the window and tell motionnotify to grab it */
|
||||
if (grabc->isfloating == 0) {
|
||||
if (grabc->isfloating == 0 && arg->ui == CurMove) {
|
||||
grabc->drag_to_tile = true;
|
||||
setfloating(grabc, 1);
|
||||
}
|
||||
|
||||
switch (cursor_mode = arg->ui) {
|
||||
case CurMove:
|
||||
|
||||
grabcx = cursor->x - grabc->geom.x;
|
||||
grabcy = cursor->y - grabc->geom.y;
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "grab");
|
||||
|
|
@ -325,9 +311,14 @@ moveresize(const Arg *arg) {
|
|||
case CurResize:
|
||||
/* Doesn't work for X11 output - the next absolute motion event
|
||||
* returns the cursor to where it started */
|
||||
wlr_cursor_warp_closest(cursor, NULL, grabc->geom.x + grabc->geom.width,
|
||||
grabc->geom.y + grabc->geom.height);
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "bottom_right_corner");
|
||||
if (grabc->isfloating) {
|
||||
wlr_cursor_warp_closest(cursor, NULL,
|
||||
grabc->geom.x + grabc->geom.width,
|
||||
grabc->geom.y + grabc->geom.height);
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "bottom_right_corner");
|
||||
} else {
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "grab");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -377,10 +368,38 @@ quit(const Arg *arg) {
|
|||
void resizewin(const Arg *arg) {
|
||||
Client *c = NULL;
|
||||
c = selmon->sel;
|
||||
if (!c || c->isfullscreen)
|
||||
int offsetx = 0, offsety = 0;
|
||||
|
||||
if (!c || c->isfullscreen || c->ismaxmizescreen)
|
||||
return;
|
||||
if (!c->isfloating)
|
||||
togglefloating(NULL);
|
||||
|
||||
if (ISTILED(c)) {
|
||||
switch (arg->ui) {
|
||||
case NUM_TYPE_MINUS:
|
||||
offsetx = -arg->i;
|
||||
break;
|
||||
case NUM_TYPE_PLUS:
|
||||
offsetx = arg->i;
|
||||
break;
|
||||
default:
|
||||
offsetx = arg->i;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (arg->ui2) {
|
||||
case NUM_TYPE_MINUS:
|
||||
offsety = -arg->i2;
|
||||
break;
|
||||
case NUM_TYPE_PLUS:
|
||||
offsety = arg->i2;
|
||||
break;
|
||||
default:
|
||||
offsety = arg->i2;
|
||||
break;
|
||||
}
|
||||
resize_tile_client(c, false, offsetx, offsety, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (arg->ui) {
|
||||
case NUM_TYPE_MINUS:
|
||||
|
|
|
|||
|
|
@ -17,11 +17,10 @@ Monitor *dirtomon(enum wlr_direction dir) {
|
|||
|
||||
bool is_scroller_layout(Monitor *m) {
|
||||
|
||||
if (strcmp(m->pertag->ltidxs[m->pertag->curtag]->name, "scroller") == 0)
|
||||
if (m->pertag->ltidxs[m->pertag->curtag]->id == SCROLLER)
|
||||
return true;
|
||||
|
||||
if (strcmp(m->pertag->ltidxs[m->pertag->curtag]->name,
|
||||
"vertical_scroller") == 0)
|
||||
if (m->pertag->ltidxs[m->pertag->curtag]->id == VERTICAL_SCROLLER)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
|||
657
src/layout/arrange.h
Normal file
657
src/layout/arrange.h
Normal file
|
|
@ -0,0 +1,657 @@
|
|||
void set_size_per(Monitor *m, Client *c) {
|
||||
Client *fc = NULL;
|
||||
bool found = false;
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
||||
c->master_mfact_per = fc->master_mfact_per;
|
||||
c->master_inner_per = fc->master_inner_per;
|
||||
c->stack_innder_per = fc->stack_innder_per;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
c->master_mfact_per = default_mfact;
|
||||
c->master_inner_per = 1.0f;
|
||||
c->stack_innder_per = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
|
||||
int offsety, unsigned int time, int type) {
|
||||
Client *tc = NULL;
|
||||
float delta_x, delta_y;
|
||||
Client *next = NULL;
|
||||
Client *prev = NULL;
|
||||
Client *nextnext = NULL;
|
||||
Client *prevprev = NULL;
|
||||
double refresh_interval = 1000000.0 / grabc->mon->wlr_output->refresh;
|
||||
struct wl_list *node;
|
||||
bool begin_find_nextnext = false;
|
||||
bool begin_find_prevprev = false;
|
||||
|
||||
// 从当前节点的下一个开始遍历
|
||||
for (node = grabc->link.next; node != &clients; node = node->next) {
|
||||
tc = wl_container_of(node, tc, link);
|
||||
if (begin_find_nextnext && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||
nextnext = tc;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!begin_find_nextnext && VISIBLEON(tc, grabc->mon) &&
|
||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
||||
next = tc;
|
||||
begin_find_nextnext = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 从当前节点的上一个开始遍历
|
||||
for (node = grabc->link.prev; node != &clients; node = node->prev) {
|
||||
tc = wl_container_of(node, tc, link);
|
||||
|
||||
if (begin_find_prevprev && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||
prevprev = tc;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!begin_find_prevprev && VISIBLEON(tc, grabc->mon) &&
|
||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
||||
prev = tc;
|
||||
begin_find_prevprev = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!start_drag_window && isdrag) {
|
||||
drag_begin_cursorx = cursor->x;
|
||||
drag_begin_cursory = cursor->y;
|
||||
start_drag_window = true;
|
||||
// 记录初始状态
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_per;
|
||||
grabc->old_master_inner_per = grabc->master_inner_per;
|
||||
grabc->old_stack_innder_per = grabc->stack_innder_per;
|
||||
grabc->cursor_in_upper_half =
|
||||
cursor->y < grabc->geom.y + grabc->geom.height / 2;
|
||||
grabc->cursor_in_left_half =
|
||||
cursor->x < grabc->geom.x + grabc->geom.width / 2;
|
||||
// 记录初始几何信息
|
||||
grabc->drag_begin_geom = grabc->geom;
|
||||
} else {
|
||||
// 计算相对于屏幕尺寸的比例变化
|
||||
if (isdrag) {
|
||||
|
||||
offsetx = cursor->x - drag_begin_cursorx;
|
||||
offsety = cursor->y - drag_begin_cursory;
|
||||
} else {
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_per;
|
||||
grabc->old_master_inner_per = grabc->master_inner_per;
|
||||
grabc->old_stack_innder_per = grabc->stack_innder_per;
|
||||
grabc->drag_begin_geom = grabc->geom;
|
||||
grabc->cursor_in_upper_half = true;
|
||||
grabc->cursor_in_left_half = false;
|
||||
}
|
||||
|
||||
if (grabc->ismaster) {
|
||||
delta_x = (float)(offsetx) * (grabc->old_master_mfact_per) /
|
||||
grabc->drag_begin_geom.width;
|
||||
delta_y = (float)(offsety) * (grabc->old_master_inner_per) /
|
||||
grabc->drag_begin_geom.height;
|
||||
} else {
|
||||
delta_x = (float)(offsetx) * (1 - grabc->old_master_mfact_per) /
|
||||
grabc->drag_begin_geom.width;
|
||||
delta_y = (float)(offsety) * (grabc->old_stack_innder_per) /
|
||||
grabc->drag_begin_geom.height;
|
||||
}
|
||||
bool moving_up;
|
||||
bool moving_down;
|
||||
|
||||
if (!isdrag) {
|
||||
moving_up = offsety < 0 ? true : false;
|
||||
moving_down = offsety > 0 ? true : false;
|
||||
} else {
|
||||
moving_up = cursor->y < drag_begin_cursory;
|
||||
moving_down = cursor->y > drag_begin_cursory;
|
||||
}
|
||||
|
||||
if (grabc->ismaster && !prev) {
|
||||
if (moving_up) {
|
||||
delta_y = -fabsf(delta_y);
|
||||
} else {
|
||||
delta_y = fabsf(delta_y);
|
||||
}
|
||||
} else if (grabc->ismaster && next && !next->ismaster) {
|
||||
if (moving_up) {
|
||||
delta_y = fabsf(delta_y);
|
||||
} else {
|
||||
delta_y = -fabsf(delta_y);
|
||||
}
|
||||
} else if (!grabc->ismaster && prev && prev->ismaster) {
|
||||
if (moving_up) {
|
||||
delta_y = -fabsf(delta_y);
|
||||
} else {
|
||||
delta_y = fabsf(delta_y);
|
||||
}
|
||||
} else if (!grabc->ismaster && !next) {
|
||||
if (moving_up) {
|
||||
delta_y = fabsf(delta_y);
|
||||
} else {
|
||||
delta_y = -fabsf(delta_y);
|
||||
}
|
||||
} else if (type == CENTER_TILE && !grabc->ismaster && !nextnext) {
|
||||
if (moving_up) {
|
||||
delta_y = fabsf(delta_y);
|
||||
} else {
|
||||
delta_y = -fabsf(delta_y);
|
||||
}
|
||||
} else if (type == CENTER_TILE && !grabc->ismaster && prevprev &&
|
||||
prevprev->ismaster) {
|
||||
if (moving_up) {
|
||||
delta_y = -fabsf(delta_y);
|
||||
} else {
|
||||
delta_y = fabsf(delta_y);
|
||||
}
|
||||
} else if ((grabc->cursor_in_upper_half && moving_up) ||
|
||||
(!grabc->cursor_in_upper_half && moving_down)) {
|
||||
// 光标在窗口上方且向上移动,或在窗口下方且向下移动 → 增加高度
|
||||
delta_y = fabsf(delta_y);
|
||||
delta_y = delta_y * 2;
|
||||
} else {
|
||||
// 其他情况 → 减小高度
|
||||
delta_y = -fabsf(delta_y);
|
||||
delta_y = delta_y * 2;
|
||||
}
|
||||
|
||||
if (!grabc->ismaster && grabc->isleftstack && type == CENTER_TILE) {
|
||||
delta_x = delta_x * -1.0f;
|
||||
}
|
||||
|
||||
if (grabc->ismaster && type == CENTER_TILE &&
|
||||
grabc->cursor_in_left_half) {
|
||||
delta_x = delta_x * -1.0f;
|
||||
}
|
||||
|
||||
if (grabc->ismaster && type == CENTER_TILE) {
|
||||
delta_x = delta_x * 2;
|
||||
}
|
||||
|
||||
// 直接设置新的比例,基于初始值 + 变化量
|
||||
float new_master_mfact_per = grabc->old_master_mfact_per + delta_x;
|
||||
float new_master_inner_per = grabc->old_master_inner_per + delta_y;
|
||||
float new_stack_innder_per = grabc->old_stack_innder_per + delta_y;
|
||||
|
||||
// 应用限制,确保比例在合理范围内
|
||||
new_master_mfact_per = fmaxf(0.1f, fminf(0.9f, new_master_mfact_per));
|
||||
new_master_inner_per = fmaxf(0.1f, fminf(0.9f, new_master_inner_per));
|
||||
new_stack_innder_per = fmaxf(0.1f, fminf(0.9f, new_stack_innder_per));
|
||||
|
||||
// 应用到所有平铺窗口
|
||||
wl_list_for_each(tc, &clients, link) {
|
||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||
tc->master_mfact_per = new_master_mfact_per;
|
||||
}
|
||||
}
|
||||
|
||||
grabc->master_inner_per = new_master_inner_per;
|
||||
grabc->stack_innder_per = new_stack_innder_per;
|
||||
|
||||
if (!isdrag) {
|
||||
arrange(grabc->mon, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (last_apply_drap_time == 0 ||
|
||||
time - last_apply_drap_time > refresh_interval) {
|
||||
arrange(grabc->mon, false);
|
||||
last_apply_drap_time = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
|
||||
int offsety, unsigned int time, int type) {
|
||||
Client *tc = NULL;
|
||||
float delta_x, delta_y;
|
||||
Client *next = NULL;
|
||||
Client *prev = NULL;
|
||||
double refresh_interval = 1000000.0 / grabc->mon->wlr_output->refresh;
|
||||
struct wl_list *node;
|
||||
|
||||
// 从当前节点的下一个开始遍历
|
||||
for (node = grabc->link.next; node != &clients; node = node->next) {
|
||||
tc = wl_container_of(node, tc, link);
|
||||
|
||||
if (VISIBLEON(tc, grabc->mon) &&
|
||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
||||
next = tc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 从当前节点的上一个开始遍历
|
||||
for (node = grabc->link.prev; node != &clients; node = node->prev) {
|
||||
tc = wl_container_of(node, tc, link);
|
||||
|
||||
if (VISIBLEON(tc, grabc->mon) &&
|
||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
||||
prev = tc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!start_drag_window && isdrag) {
|
||||
drag_begin_cursorx = cursor->x;
|
||||
drag_begin_cursory = cursor->y;
|
||||
start_drag_window = true;
|
||||
|
||||
// 记录初始状态
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_per;
|
||||
grabc->old_master_inner_per = grabc->master_inner_per;
|
||||
grabc->old_stack_innder_per = grabc->stack_innder_per;
|
||||
grabc->cursor_in_upper_half =
|
||||
cursor->y < grabc->geom.y + grabc->geom.height / 2;
|
||||
grabc->cursor_in_left_half =
|
||||
cursor->x < grabc->geom.x + grabc->geom.width / 2;
|
||||
// 记录初始几何信息
|
||||
grabc->drag_begin_geom = grabc->geom;
|
||||
} else {
|
||||
// 计算相对于屏幕尺寸的比例变化
|
||||
// 计算相对于屏幕尺寸的比例变化
|
||||
if (isdrag) {
|
||||
|
||||
offsetx = cursor->x - drag_begin_cursorx;
|
||||
offsety = cursor->y - drag_begin_cursory;
|
||||
} else {
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_per;
|
||||
grabc->old_master_inner_per = grabc->master_inner_per;
|
||||
grabc->old_stack_innder_per = grabc->stack_innder_per;
|
||||
grabc->drag_begin_geom = grabc->geom;
|
||||
grabc->cursor_in_upper_half = true;
|
||||
grabc->cursor_in_left_half = false;
|
||||
}
|
||||
|
||||
if (grabc->ismaster) {
|
||||
// 垂直版本:左右移动调整高度比例,上下移动调整宽度比例
|
||||
delta_x = (float)(offsetx) * (grabc->old_master_inner_per) /
|
||||
grabc->drag_begin_geom.width;
|
||||
delta_y = (float)(offsety) * (grabc->old_master_mfact_per) /
|
||||
grabc->drag_begin_geom.height;
|
||||
} else {
|
||||
delta_x = (float)(offsetx) * (grabc->old_stack_innder_per) /
|
||||
grabc->drag_begin_geom.width;
|
||||
delta_y = (float)(offsety) * (1 - grabc->old_master_mfact_per) /
|
||||
grabc->drag_begin_geom.height;
|
||||
}
|
||||
|
||||
bool moving_left;
|
||||
bool moving_right;
|
||||
|
||||
if (!isdrag) {
|
||||
moving_left = offsetx < 0 ? true : false;
|
||||
moving_right = offsetx > 0 ? true : false;
|
||||
} else {
|
||||
moving_left = cursor->x < drag_begin_cursorx;
|
||||
moving_right = cursor->x > drag_begin_cursorx;
|
||||
}
|
||||
|
||||
// 调整主区域和栈区域的高度比例(垂直分割)
|
||||
if (grabc->ismaster && !prev) {
|
||||
if (moving_left) {
|
||||
delta_x = -fabsf(delta_x); // 向上移动减少主区域高度
|
||||
} else {
|
||||
delta_x = fabsf(delta_x); // 向下移动增加主区域高度
|
||||
}
|
||||
} else if (grabc->ismaster && next && !next->ismaster) {
|
||||
if (moving_left) {
|
||||
delta_x = fabsf(delta_x); // 向上移动增加主区域高度
|
||||
} else {
|
||||
delta_x = -fabsf(delta_x); // 向下移动减少主区域高度
|
||||
}
|
||||
} else if (!grabc->ismaster && prev && prev->ismaster) {
|
||||
if (moving_left) {
|
||||
delta_x = -fabsf(delta_x); // 向上移动减少栈区域高度
|
||||
} else {
|
||||
delta_x = fabsf(delta_x); // 向下移动增加栈区域高度
|
||||
}
|
||||
} else if (!grabc->ismaster && !next) {
|
||||
if (moving_left) {
|
||||
delta_x = fabsf(delta_x); // 向上移动增加栈区域高度
|
||||
} else {
|
||||
delta_x = -fabsf(delta_x); // 向下移动减少栈区域高度
|
||||
}
|
||||
} else if ((grabc->cursor_in_left_half && moving_left) ||
|
||||
(!grabc->cursor_in_left_half && moving_right)) {
|
||||
// 光标在窗口左侧且向左移动,或在窗口右侧且向右移动 → 增加宽度
|
||||
delta_x = fabsf(delta_x);
|
||||
delta_x = delta_x * 2;
|
||||
} else {
|
||||
// 其他情况 → 减小宽度
|
||||
delta_x = -fabsf(delta_x);
|
||||
delta_x = delta_x * 2;
|
||||
}
|
||||
|
||||
// 直接设置新的比例,基于初始值 + 变化量
|
||||
float new_master_mfact_per = grabc->old_master_mfact_per +
|
||||
delta_y; // 垂直:delta_y调整主区域高度
|
||||
float new_master_inner_per = grabc->old_master_inner_per +
|
||||
delta_x; // 垂直:delta_x调整主区域内部宽度
|
||||
float new_stack_innder_per = grabc->old_stack_innder_per +
|
||||
delta_x; // 垂直:delta_x调整栈区域内部宽度
|
||||
|
||||
// 应用限制,确保比例在合理范围内
|
||||
new_master_mfact_per = fmaxf(0.1f, fminf(0.9f, new_master_mfact_per));
|
||||
new_master_inner_per = fmaxf(0.1f, fminf(0.9f, new_master_inner_per));
|
||||
new_stack_innder_per = fmaxf(0.1f, fminf(0.9f, new_stack_innder_per));
|
||||
|
||||
// 应用到所有平铺窗口
|
||||
wl_list_for_each(tc, &clients, link) {
|
||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||
tc->master_mfact_per = new_master_mfact_per;
|
||||
}
|
||||
}
|
||||
|
||||
grabc->master_inner_per = new_master_inner_per;
|
||||
grabc->stack_innder_per = new_stack_innder_per;
|
||||
|
||||
if (!isdrag) {
|
||||
arrange(grabc->mon, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (last_apply_drap_time == 0 ||
|
||||
time - last_apply_drap_time > refresh_interval) {
|
||||
arrange(grabc->mon, false);
|
||||
last_apply_drap_time = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resize_tile_scroller(Client *grabc, bool isdrag, int offsetx, int offsety,
|
||||
unsigned int time, bool isvertical) {
|
||||
float delta_x, delta_y;
|
||||
float new_scroller_proportion;
|
||||
double refresh_interval = 1000000.0 / grabc->mon->wlr_output->refresh;
|
||||
|
||||
if (!start_drag_window && isdrag) {
|
||||
drag_begin_cursorx = cursor->x;
|
||||
drag_begin_cursory = cursor->y;
|
||||
start_drag_window = true;
|
||||
|
||||
// 记录初始状态
|
||||
grabc->old_scroller_pproportion = grabc->scroller_proportion;
|
||||
|
||||
grabc->cursor_in_left_half =
|
||||
cursor->x < grabc->geom.x + grabc->geom.width / 2;
|
||||
grabc->cursor_in_upper_half =
|
||||
cursor->y < grabc->geom.y + grabc->geom.height / 2;
|
||||
// 记录初始几何信息
|
||||
grabc->drag_begin_geom = grabc->geom;
|
||||
} else {
|
||||
// 计算相对于屏幕尺寸的比例变化
|
||||
// 计算相对于屏幕尺寸的比例变化
|
||||
if (isdrag) {
|
||||
|
||||
offsetx = cursor->x - drag_begin_cursorx;
|
||||
offsety = cursor->y - drag_begin_cursory;
|
||||
} else {
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_per;
|
||||
grabc->old_master_inner_per = grabc->master_inner_per;
|
||||
grabc->old_stack_innder_per = grabc->stack_innder_per;
|
||||
grabc->drag_begin_geom = grabc->geom;
|
||||
grabc->old_scroller_pproportion = grabc->scroller_proportion;
|
||||
grabc->cursor_in_upper_half = false;
|
||||
grabc->cursor_in_left_half = false;
|
||||
}
|
||||
|
||||
delta_x = (float)(offsetx) * (grabc->old_scroller_pproportion) /
|
||||
grabc->drag_begin_geom.width;
|
||||
delta_y = (float)(offsety) * (grabc->old_scroller_pproportion) /
|
||||
grabc->drag_begin_geom.height;
|
||||
|
||||
bool moving_up;
|
||||
bool moving_down;
|
||||
bool moving_left;
|
||||
bool moving_right;
|
||||
|
||||
if (!isdrag) {
|
||||
moving_up = offsety < 0 ? true : false;
|
||||
moving_down = offsety > 0 ? true : false;
|
||||
moving_left = offsetx < 0 ? true : false;
|
||||
moving_right = offsetx > 0 ? true : false;
|
||||
} else {
|
||||
moving_up = cursor->y < drag_begin_cursory;
|
||||
moving_down = cursor->y > drag_begin_cursory;
|
||||
moving_left = cursor->x < drag_begin_cursorx;
|
||||
moving_right = cursor->x > drag_begin_cursorx;
|
||||
}
|
||||
|
||||
if ((grabc->cursor_in_upper_half && moving_up) ||
|
||||
(!grabc->cursor_in_upper_half && moving_down)) {
|
||||
// 光标在窗口上方且向上移动,或在窗口下方且向下移动 → 增加高度
|
||||
delta_y = fabsf(delta_y);
|
||||
} else {
|
||||
// 其他情况 → 减小高度
|
||||
delta_y = -fabsf(delta_y);
|
||||
}
|
||||
|
||||
if ((grabc->cursor_in_left_half && moving_left) ||
|
||||
(!grabc->cursor_in_left_half && moving_right)) {
|
||||
delta_x = fabsf(delta_x);
|
||||
} else {
|
||||
delta_x = -fabsf(delta_x);
|
||||
}
|
||||
|
||||
// 直接设置新的比例,基于初始值 + 变化量
|
||||
if (isvertical) {
|
||||
new_scroller_proportion = grabc->old_scroller_pproportion + delta_y;
|
||||
} else {
|
||||
new_scroller_proportion = grabc->old_scroller_pproportion + delta_x;
|
||||
}
|
||||
|
||||
// 应用限制,确保比例在合理范围内
|
||||
new_scroller_proportion =
|
||||
fmaxf(0.1f, fminf(0.9f, new_scroller_proportion));
|
||||
|
||||
grabc->scroller_proportion = new_scroller_proportion;
|
||||
|
||||
if (!isdrag) {
|
||||
arrange(grabc->mon, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (last_apply_drap_time == 0 ||
|
||||
time - last_apply_drap_time > refresh_interval) {
|
||||
arrange(grabc->mon, false);
|
||||
last_apply_drap_time = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resize_tile_client(Client *grabc, bool isdrag, int offsetx, int offsety,
|
||||
unsigned int time) {
|
||||
const Layout *current_layout =
|
||||
grabc->mon->pertag->ltidxs[grabc->mon->pertag->curtag];
|
||||
if (current_layout->id == TILE || current_layout->id == DECK ||
|
||||
current_layout->id == CENTER_TILE
|
||||
|
||||
) {
|
||||
resize_tile_master_horizontal(grabc, isdrag, offsetx, offsety, time,
|
||||
current_layout->id);
|
||||
} else if (current_layout->id == VERTICAL_TILE) {
|
||||
resize_tile_master_vertical(grabc, isdrag, offsetx, offsety, time,
|
||||
current_layout->id);
|
||||
} else if (current_layout->id == SCROLLER) {
|
||||
resize_tile_scroller(grabc, isdrag, offsetx, offsety, time, false);
|
||||
} else if (current_layout->id == VERTICAL_SCROLLER) {
|
||||
resize_tile_scroller(grabc, isdrag, offsetx, offsety, time, true);
|
||||
}
|
||||
}
|
||||
|
||||
void reset_size_per_mon(Monitor *m, int tile_cilent_num,
|
||||
double total_left_stack_hight_percent,
|
||||
double total_right_stack_hight_percent,
|
||||
double total_stack_hight_percent,
|
||||
double total_master_inner_percent, int master_num,
|
||||
int stack_num) {
|
||||
Client *c = NULL;
|
||||
int i = 0;
|
||||
unsigned int stack_index;
|
||||
unsigned int nmasters = m->pertag->nmasters[m->pertag->curtag];
|
||||
|
||||
if (m->pertag->ltidxs[m->pertag->curtag]->id != CENTER_TILE) {
|
||||
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||
|
||||
if (total_master_inner_percent <= 0.0)
|
||||
return;
|
||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||
c->ismaster = true;
|
||||
c->stack_innder_per = stack_num ? 1.0f / stack_num : 1.0f;
|
||||
c->master_inner_per =
|
||||
c->master_inner_per / total_master_inner_percent;
|
||||
} else {
|
||||
c->ismaster = false;
|
||||
c->master_inner_per = 1.0f / master_num;
|
||||
c->stack_innder_per =
|
||||
total_stack_hight_percent
|
||||
? c->stack_innder_per / total_stack_hight_percent
|
||||
: 1.0f;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||
|
||||
if (total_master_inner_percent <= 0.0)
|
||||
return;
|
||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||
c->ismaster = true;
|
||||
c->stack_innder_per =
|
||||
stack_num > 1 ? 2.0f / stack_num : 1.0f;
|
||||
c->master_inner_per =
|
||||
c->master_inner_per / total_master_inner_percent;
|
||||
} else {
|
||||
stack_index = i - nmasters;
|
||||
|
||||
c->ismaster = false;
|
||||
c->master_inner_per = 1.0f / master_num;
|
||||
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
||||
c->stack_innder_per =
|
||||
total_right_stack_hight_percent
|
||||
? c->stack_innder_per /
|
||||
total_right_stack_hight_percent
|
||||
: 1.0f;
|
||||
} else {
|
||||
c->stack_innder_per =
|
||||
total_left_stack_hight_percent
|
||||
? c->stack_innder_per /
|
||||
total_left_stack_hight_percent
|
||||
: 1.0f;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void // 17
|
||||
arrange(Monitor *m, bool want_animation) {
|
||||
Client *c = NULL;
|
||||
double total_stack_innder_percent = 0;
|
||||
double total_master_inner_percent = 0;
|
||||
double total_right_stack_hight_percent = 0;
|
||||
double total_left_stack_hight_percent = 0;
|
||||
int i = 0;
|
||||
int nmasters = 0;
|
||||
int stack_index = 0;
|
||||
int master_num = 0;
|
||||
int stack_num = 0;
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
if (!m->wlr_output->enabled)
|
||||
return;
|
||||
m->visible_clients = 0;
|
||||
m->visible_tiling_clients = 0;
|
||||
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (VISIBLEON(c, m)) {
|
||||
m->visible_clients++;
|
||||
if (ISTILED(c)) {
|
||||
m->visible_tiling_clients++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nmasters = m->pertag->nmasters[m->pertag->curtag];
|
||||
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->iskilling)
|
||||
continue;
|
||||
|
||||
if (c->mon == m && (c->isglobal || c->isunglobal)) {
|
||||
c->tags = m->tagset[m->seltags];
|
||||
if (c->mon->sel == NULL)
|
||||
focusclient(c, 0);
|
||||
}
|
||||
|
||||
if (c->mon == m) {
|
||||
if (VISIBLEON(c, m)) {
|
||||
if (ISTILED(c)) {
|
||||
|
||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||
master_num++;
|
||||
total_master_inner_percent += c->master_inner_per;
|
||||
} else {
|
||||
stack_num++;
|
||||
total_stack_innder_percent += c->stack_innder_per;
|
||||
stack_index = i - nmasters;
|
||||
if ((stack_index % 2) ^
|
||||
(m->visible_tiling_clients % 2 == 0)) {
|
||||
c->isleftstack = false;
|
||||
total_right_stack_hight_percent +=
|
||||
c->stack_innder_per;
|
||||
} else {
|
||||
c->isleftstack = true;
|
||||
total_left_stack_hight_percent +=
|
||||
c->stack_innder_per;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
set_arrange_visible(m, c, want_animation);
|
||||
} else {
|
||||
set_arrange_hidden(m, c, want_animation);
|
||||
}
|
||||
}
|
||||
|
||||
if (c->mon == m && c->ismaxmizescreen && !c->animation.tagouted &&
|
||||
!c->animation.tagouting && VISIBLEON(c, m)) {
|
||||
reset_maxmizescreen_size(c);
|
||||
}
|
||||
}
|
||||
|
||||
reset_size_per_mon(
|
||||
m, m->visible_tiling_clients, total_left_stack_hight_percent,
|
||||
total_right_stack_hight_percent, total_stack_innder_percent,
|
||||
total_master_inner_percent, master_num, stack_num);
|
||||
|
||||
if (m->isoverview) {
|
||||
overviewlayout.arrange(m);
|
||||
} else {
|
||||
m->pertag->ltidxs[m->pertag->curtag]->arrange(m);
|
||||
}
|
||||
|
||||
if (!start_drag_window) {
|
||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||
checkidleinhibitor(NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,128 +1,3 @@
|
|||
void fibonacci(Monitor *mon, int s) {
|
||||
unsigned int i = 0, n = 0, nx, ny, nw, nh;
|
||||
Client *c = NULL;
|
||||
unsigned int cur_gappih = enablegaps ? mon->gappih : 0;
|
||||
unsigned int cur_gappiv = enablegaps ? mon->gappiv : 0;
|
||||
unsigned int cur_gappoh = enablegaps ? mon->gappoh : 0;
|
||||
unsigned int cur_gappov = enablegaps ? mon->gappov : 0;
|
||||
|
||||
cur_gappih = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappiv = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappoh = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
// Count visible clients
|
||||
n = mon->visible_tiling_clients;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
// Initial dimensions including outer gaps
|
||||
nx = mon->w.x + cur_gappoh;
|
||||
ny = mon->w.y + cur_gappov;
|
||||
nw = mon->w.width - 2 * cur_gappoh;
|
||||
nh = mon->w.height - 2 * cur_gappov;
|
||||
|
||||
// First pass: calculate client geometries
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, mon) || !ISTILED(c))
|
||||
continue;
|
||||
|
||||
c->bw = mon->visible_tiling_clients == 1 && no_border_when_single &&
|
||||
smartgaps
|
||||
? 0
|
||||
: borderpx;
|
||||
if ((i % 2 && nh / 2 > 2 * c->bw) || (!(i % 2) && nw / 2 > 2 * c->bw)) {
|
||||
if (i < n - 1) {
|
||||
if (i % 2) {
|
||||
if (i == 1) {
|
||||
nh = nh * mon->pertag->smfacts[mon->pertag->curtag];
|
||||
} else {
|
||||
nh = (nh - cur_gappiv) / 2;
|
||||
}
|
||||
} else {
|
||||
nw = (nw - cur_gappih) / 2;
|
||||
}
|
||||
|
||||
if ((i % 4) == 2 && !s)
|
||||
nx += nw + cur_gappih;
|
||||
else if ((i % 4) == 3 && !s)
|
||||
ny += nh + cur_gappiv;
|
||||
}
|
||||
|
||||
if ((i % 4) == 0) {
|
||||
if (s)
|
||||
ny += nh + cur_gappiv;
|
||||
else
|
||||
ny -= nh + cur_gappiv;
|
||||
} else if ((i % 4) == 1)
|
||||
nx += nw + cur_gappih;
|
||||
else if ((i % 4) == 2)
|
||||
ny += nh + cur_gappiv;
|
||||
else if ((i % 4) == 3) {
|
||||
if (s)
|
||||
nx += nw + cur_gappih;
|
||||
else
|
||||
nx -= nw + cur_gappih;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (n != 1)
|
||||
nw = (mon->w.width - 2 * cur_gappoh) *
|
||||
mon->pertag->mfacts[mon->pertag->curtag];
|
||||
ny = mon->w.y + cur_gappov;
|
||||
} else if (i == 1) {
|
||||
nw = mon->w.width - 2 * cur_gappoh - nw - cur_gappih;
|
||||
} else if (i == 2) {
|
||||
nh = mon->w.height - 2 * cur_gappov - nh - cur_gappiv;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
c->geom = (struct wlr_box){.x = nx, .y = ny, .width = nw, .height = nh};
|
||||
}
|
||||
|
||||
// Second pass: apply gaps between clients
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, mon) || !ISTILED(c))
|
||||
continue;
|
||||
|
||||
unsigned int right_gap = 0;
|
||||
unsigned int bottom_gap = 0;
|
||||
Client *nc = NULL;
|
||||
|
||||
wl_list_for_each(nc, &clients, link) {
|
||||
if (!VISIBLEON(nc, mon) || !ISTILED(nc))
|
||||
continue;
|
||||
|
||||
if (c == nc)
|
||||
continue;
|
||||
|
||||
// Check for right neighbor
|
||||
if (c->geom.y == nc->geom.y &&
|
||||
c->geom.x + c->geom.width == nc->geom.x) {
|
||||
right_gap = cur_gappih;
|
||||
}
|
||||
|
||||
// Check for bottom neighbor
|
||||
if (c->geom.x == nc->geom.x &&
|
||||
c->geom.y + c->geom.height == nc->geom.y) {
|
||||
bottom_gap = cur_gappiv;
|
||||
}
|
||||
}
|
||||
|
||||
resize(c,
|
||||
(struct wlr_box){.x = c->geom.x,
|
||||
.y = c->geom.y,
|
||||
.width = c->geom.width - right_gap,
|
||||
.height = c->geom.height - bottom_gap},
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
void dwindle(Monitor *mon) { fibonacci(mon, 1); }
|
||||
|
||||
void spiral(Monitor *mon) { fibonacci(mon, 0); }
|
||||
|
||||
// 网格布局窗口大小和位置计算
|
||||
void grid(Monitor *m) {
|
||||
unsigned int i, n;
|
||||
|
|
@ -247,6 +122,9 @@ void deck(Monitor *m) {
|
|||
unsigned int mw, my;
|
||||
int i, n = 0;
|
||||
Client *c = NULL;
|
||||
Client *fc = NULL;
|
||||
float mfact;
|
||||
|
||||
unsigned int cur_gappih = enablegaps ? m->gappih : 0;
|
||||
unsigned int cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
unsigned int cur_gappov = enablegaps ? m->gappov : 0;
|
||||
|
|
@ -260,8 +138,15 @@ void deck(Monitor *m) {
|
|||
if (n == 0)
|
||||
return;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc))
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate master width using mfact from pertag
|
||||
float mfact = m->pertag ? m->pertag->mfacts[m->pertag->curtag] : m->mfact;
|
||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||
: m->pertag->mfacts[m->pertag->curtag];
|
||||
|
||||
// Calculate master width including outer gaps
|
||||
if (n > m->nmaster)
|
||||
|
|
@ -274,6 +159,7 @@ void deck(Monitor *m) {
|
|||
if (!VISIBLEON(c, m) || !ISTILED(c))
|
||||
continue;
|
||||
if (i < m->nmaster) {
|
||||
c->master_mfact_per = mfact;
|
||||
// Master area clients
|
||||
resize(
|
||||
c,
|
||||
|
|
@ -286,6 +172,7 @@ void deck(Monitor *m) {
|
|||
my += c->geom.height;
|
||||
} else {
|
||||
// Stack area clients
|
||||
c->master_mfact_per = mfact;
|
||||
resize(c,
|
||||
(struct wlr_box){.x = m->w.x + mw + cur_gappoh + cur_gappih,
|
||||
.y = m->w.y + cur_gappov,
|
||||
|
|
@ -385,6 +272,9 @@ void scroller(Monitor *m) {
|
|||
}
|
||||
}
|
||||
|
||||
if (start_drag_window)
|
||||
need_scroller = false;
|
||||
|
||||
target_geom.height = m->w.height - 2 * cur_gappov;
|
||||
target_geom.width = max_client_width * c->scroller_proportion;
|
||||
target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2;
|
||||
|
|
@ -433,31 +323,46 @@ void scroller(Monitor *m) {
|
|||
}
|
||||
|
||||
void center_tile(Monitor *m) {
|
||||
unsigned int i, n = 0, h, mw, mx, my, oty, ety, tw;
|
||||
unsigned int i, n = 0, h, r, ie = enablegaps, mw, mx, my, oty, ety, tw;
|
||||
Client *c = NULL;
|
||||
Client *fc = NULL;
|
||||
double mfact = 0;
|
||||
int master_num = 0;
|
||||
int stack_num = 0;
|
||||
|
||||
n = m->visible_tiling_clients;
|
||||
master_num = m->pertag->nmasters[m->pertag->curtag];
|
||||
stack_num = n - master_num;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
// 间隙参数处理
|
||||
unsigned int gappiv = enablegaps ? m->gappiv : 0; // 内部垂直间隙
|
||||
unsigned int gappih = enablegaps ? m->gappih : 0; // 内部水平间隙
|
||||
unsigned int gappov = enablegaps ? m->gappov : 0; // 外部垂直间隙
|
||||
unsigned int gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙
|
||||
|
||||
// 智能间隙处理
|
||||
if (smartgaps && n == 1) {
|
||||
gappiv = gappih = gappov = gappoh = 0;
|
||||
// 获取第一个可见的平铺客户端用于主区域宽度百分比
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc))
|
||||
break;
|
||||
}
|
||||
|
||||
// 间隙参数处理
|
||||
unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; // 内部垂直间隙
|
||||
unsigned int cur_gappih = enablegaps ? m->gappih : 0; // 内部水平间隙
|
||||
unsigned int cur_gappov = enablegaps ? m->gappov : 0; // 外部垂直间隙
|
||||
unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙
|
||||
|
||||
// 智能间隙处理
|
||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
|
||||
unsigned int nmasters = m->pertag->nmasters[m->pertag->curtag];
|
||||
float mfact = m->pertag->mfacts[m->pertag->curtag];
|
||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||
: m->pertag->mfacts[m->pertag->curtag];
|
||||
|
||||
// 初始化区域
|
||||
mw = m->w.width;
|
||||
mx = gappoh;
|
||||
my = gappov;
|
||||
mx = cur_gappoh;
|
||||
my = cur_gappov;
|
||||
tw = mw;
|
||||
|
||||
// 判断是否需要主区域铺满
|
||||
|
|
@ -465,37 +370,38 @@ void center_tile(Monitor *m) {
|
|||
|
||||
if (n > nmasters || !should_overspread) {
|
||||
// 计算主区域宽度(居中模式)
|
||||
mw = nmasters ? (m->w.width - 2 * gappoh - gappih) * mfact : 0;
|
||||
mw = nmasters ? (m->w.width - 2 * cur_gappoh - cur_gappih * ie) * mfact
|
||||
: 0;
|
||||
|
||||
if (n - nmasters > 1) {
|
||||
// 多个堆叠窗口:主区域居中,左右两侧各有一个堆叠区域
|
||||
tw = (m->w.width - mw) / 2 - gappoh - gappih;
|
||||
mx = gappoh + tw + gappih;
|
||||
tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
|
||||
mx = cur_gappoh + tw + cur_gappih * ie;
|
||||
} else if (n - nmasters == 1) {
|
||||
// 单个堆叠窗口的处理
|
||||
if (center_when_single_slave) {
|
||||
// 修改:slave在右边,master居中,左边空着
|
||||
tw = (m->w.width - mw) / 2 - gappoh - gappih;
|
||||
mx = gappoh + tw + gappih; // master居中
|
||||
if (center_when_single_stack) {
|
||||
// stack在右边,master居中,左边空着
|
||||
tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
|
||||
mx = cur_gappoh + tw + cur_gappih * ie; // master居中
|
||||
} else {
|
||||
// slave在右边,master在左边
|
||||
tw = m->w.width - mw - 2 * gappoh - gappih;
|
||||
mx = gappoh; // master在左边
|
||||
// stack在右边,master在左边
|
||||
tw = m->w.width - mw - 2 * cur_gappoh - cur_gappih * ie;
|
||||
mx = cur_gappoh; // master在左边
|
||||
}
|
||||
} else {
|
||||
// 只有主区域窗口:居中显示
|
||||
tw = (m->w.width - mw) / 2 - gappoh - gappih;
|
||||
mx = gappoh + tw + gappih;
|
||||
tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
|
||||
mx = cur_gappoh + tw + cur_gappih * ie;
|
||||
}
|
||||
} else {
|
||||
// 主区域铺满模式(只有主区域窗口时)
|
||||
mw = m->w.width - 2 * gappoh;
|
||||
mx = gappoh;
|
||||
mw = m->w.width - 2 * cur_gappoh;
|
||||
mx = cur_gappoh;
|
||||
tw = 0; // 堆叠区域宽度为0
|
||||
}
|
||||
|
||||
oty = gappov;
|
||||
ety = gappov;
|
||||
oty = cur_gappov;
|
||||
ety = cur_gappov;
|
||||
|
||||
i = 0;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
|
|
@ -504,68 +410,119 @@ void center_tile(Monitor *m) {
|
|||
|
||||
if (i < nmasters) {
|
||||
// 主区域窗口
|
||||
unsigned int r = MIN(n, nmasters) - i;
|
||||
h = (m->w.height - my - gappov - gappiv * (r - 1)) / r;
|
||||
r = MIN(n, nmasters) - i;
|
||||
if (c->master_inner_per > 0.0f) {
|
||||
h = (m->w.height - 2 * cur_gappov -
|
||||
cur_gappiv * ie * (master_num - 1)) *
|
||||
c->master_inner_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
h = (m->w.height - my - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->master_inner_per = h / (m->w.height - my - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
resize(c,
|
||||
(struct wlr_box){.x = m->w.x + mx,
|
||||
.y = m->w.y + my,
|
||||
.width = mw,
|
||||
.width = mw - cur_gappih * ie,
|
||||
.height = h},
|
||||
0);
|
||||
my += c->geom.height + gappiv;
|
||||
my += c->geom.height + cur_gappiv * ie;
|
||||
} else {
|
||||
// 堆叠区域窗口
|
||||
unsigned int stack_index = i - nmasters;
|
||||
|
||||
if (n - nmasters == 1) {
|
||||
// 单个堆叠窗口
|
||||
unsigned int r = n - i;
|
||||
h = (m->w.height - ety - gappov - gappiv * (r - 1)) / r;
|
||||
r = n - i;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = (m->w.height - 2 * cur_gappov -
|
||||
cur_gappiv * ie * (stack_num - 1)) *
|
||||
c->stack_innder_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
h = (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per = h / (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
int stack_x;
|
||||
if (center_when_single_slave) {
|
||||
// 修改:放在右侧(master居中时,slave在右边)
|
||||
stack_x = m->w.x + mx + mw + gappih;
|
||||
if (center_when_single_stack) {
|
||||
// 放在右侧(master居中时,stack在右边)
|
||||
stack_x = m->w.x + mx + mw + cur_gappih * ie;
|
||||
} else {
|
||||
// 放在右侧(master在左边时,slave在右边)
|
||||
stack_x = m->w.x + mx + mw + gappih;
|
||||
// 放在右侧(master在左边时,stack在右边)
|
||||
stack_x = m->w.x + mx + mw + cur_gappih * ie;
|
||||
}
|
||||
|
||||
resize(c,
|
||||
(struct wlr_box){.x = stack_x,
|
||||
.y = m->w.y + ety,
|
||||
.width = tw,
|
||||
.width = tw - cur_gappih * ie,
|
||||
.height = h},
|
||||
0);
|
||||
ety += c->geom.height + gappiv;
|
||||
ety += c->geom.height + cur_gappiv * ie;
|
||||
} else {
|
||||
// 多个堆叠窗口:交替放在左右两侧
|
||||
unsigned int r = (n - i + 1) / 2;
|
||||
r = (n - i + 1) / 2;
|
||||
|
||||
// 当n为偶数时翻转判断逻辑
|
||||
if ((stack_index % 2) ^ (n % 2 == 0)) {
|
||||
// 右侧堆叠窗口
|
||||
h = (m->w.height - ety - gappov - gappiv * (r - 1)) / r;
|
||||
int stack_x = m->w.x + mx + mw + gappih;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = (m->w.height - 2 * cur_gappov -
|
||||
cur_gappiv * ie * (stack_num / 2 - 1)) *
|
||||
c->stack_innder_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
h = (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per =
|
||||
h / (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
int stack_x = m->w.x + mx + mw + cur_gappih * ie;
|
||||
resize(c,
|
||||
(struct wlr_box){.x = stack_x,
|
||||
.y = m->w.y + ety,
|
||||
.width = tw,
|
||||
.width = tw - cur_gappih * ie,
|
||||
.height = h},
|
||||
0);
|
||||
ety += c->geom.height + gappiv;
|
||||
ety += c->geom.height + cur_gappiv * ie;
|
||||
} else {
|
||||
// 左侧堆叠窗口
|
||||
h = (m->w.height - oty - gappov - gappiv * (r - 1)) / r;
|
||||
int stack_x = m->w.x + gappoh;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = (m->w.height - 2 * cur_gappov -
|
||||
cur_gappiv * ie * (stack_num / 2 - 1)) *
|
||||
c->stack_innder_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
h = (m->w.height - oty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per =
|
||||
h / (m->w.height - oty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
int stack_x = m->w.x + cur_gappoh;
|
||||
resize(c,
|
||||
(struct wlr_box){.x = stack_x,
|
||||
.y = m->w.y + oty,
|
||||
.width = tw,
|
||||
.width = tw - cur_gappih * ie,
|
||||
.height = h},
|
||||
0);
|
||||
oty += c->geom.height + gappiv;
|
||||
oty += c->geom.height + cur_gappiv * ie;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -576,8 +533,14 @@ void center_tile(Monitor *m) {
|
|||
void tile(Monitor *m) {
|
||||
unsigned int i, n = 0, h, r, ie = enablegaps, mw, my, ty;
|
||||
Client *c = NULL;
|
||||
Client *fc = NULL;
|
||||
double mfact = 0;
|
||||
int master_num = 0;
|
||||
int stack_num = 0;
|
||||
|
||||
n = m->visible_tiling_clients;
|
||||
master_num = m->pertag->nmasters[m->pertag->curtag];
|
||||
stack_num = n - master_num;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
|
@ -592,10 +555,18 @@ void tile(Monitor *m) {
|
|||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc))
|
||||
break;
|
||||
}
|
||||
|
||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||
: m->pertag->mfacts[m->pertag->curtag];
|
||||
|
||||
if (n > m->pertag->nmasters[m->pertag->curtag])
|
||||
mw = m->pertag->nmasters[m->pertag->curtag]
|
||||
? (m->w.width + cur_gappih * ie) *
|
||||
m->pertag->mfacts[m->pertag->curtag]
|
||||
? (m->w.width + cur_gappih * ie) * mfact
|
||||
: 0;
|
||||
else
|
||||
mw = m->w.width - 2 * cur_gappoh + cur_gappih * ie;
|
||||
|
|
@ -606,7 +577,19 @@ void tile(Monitor *m) {
|
|||
continue;
|
||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||
r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
||||
h = (m->w.height - my - cur_gappov - cur_gappiv * ie * (r - 1)) / r;
|
||||
if (c->master_inner_per > 0.0f) {
|
||||
h = (m->w.height - 2 * cur_gappov -
|
||||
cur_gappiv * ie * (master_num - 1)) *
|
||||
c->master_inner_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
h = (m->w.height - my - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->master_inner_per = h / (m->w.height - my - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
resize(c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||
.y = m->w.y + my,
|
||||
|
|
@ -616,7 +599,22 @@ void tile(Monitor *m) {
|
|||
my += c->geom.height + cur_gappiv * ie;
|
||||
} else {
|
||||
r = n - i;
|
||||
h = (m->w.height - ty - cur_gappov - cur_gappiv * ie * (r - 1)) / r;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = (m->w.height - 2 * cur_gappov -
|
||||
cur_gappiv * ie * (stack_num - 1)) *
|
||||
c->stack_innder_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
h = (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per = h / (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
// wlr_log(WLR_ERROR, "stack_innder_per: %f", c->stack_innder_per);
|
||||
|
||||
resize(c,
|
||||
(struct wlr_box){.x = m->w.x + mw + cur_gappoh,
|
||||
.y = m->w.y + ty,
|
||||
|
|
|
|||
|
|
@ -4,35 +4,37 @@ static void overview(Monitor *m);
|
|||
static void grid(Monitor *m);
|
||||
static void scroller(Monitor *m);
|
||||
static void deck(Monitor *mon);
|
||||
static void dwindle(Monitor *mon);
|
||||
static void spiral(Monitor *mon);
|
||||
static void monocle(Monitor *m);
|
||||
static void vertical_tile(Monitor *m);
|
||||
static void vertical_overview(Monitor *m);
|
||||
static void vertical_grid(Monitor *m);
|
||||
static void vertical_scroller(Monitor *m);
|
||||
static void vertical_deck(Monitor *mon);
|
||||
static void vertical_dwindle(Monitor *mon);
|
||||
static void vertical_spiral(Monitor *mon);
|
||||
|
||||
/* layout(s) */
|
||||
Layout overviewlayout = {"", overview, "overview"};
|
||||
|
||||
enum {
|
||||
SCROLLER,
|
||||
TILE,
|
||||
GRID,
|
||||
MONOCLE,
|
||||
DECK,
|
||||
CENTER_TILE,
|
||||
VERTICAL_SCROLLER,
|
||||
VERTICAL_TILE,
|
||||
};
|
||||
|
||||
Layout layouts[] = {
|
||||
// 最少两个,不能删除少于两个
|
||||
/* symbol arrange function name */
|
||||
{"S", scroller, "scroller"}, // 滚动布局
|
||||
{"T", tile, "tile"}, // 堆栈布局
|
||||
{"G", grid, "grid"},
|
||||
{"M", monocle, "monocle"},
|
||||
{"D", dwindle, "dwindle"},
|
||||
{"P", spiral, "spiral"},
|
||||
{"K", deck, "deck"},
|
||||
{"CT", center_tile, "center_tile"},
|
||||
{"VS", vertical_scroller, "vertical_scroller"},
|
||||
{"VT", vertical_tile, "vertical_tile"},
|
||||
{"VD", vertical_dwindle, "vertical_dwindle"},
|
||||
{"VP", vertical_spiral, "vertical_spiral"},
|
||||
{"VG", vertical_grid, "vertical_grid"},
|
||||
{"VK", vertical_deck, "vertical_deck"},
|
||||
{"S", scroller, "scroller", SCROLLER}, // 滚动布局
|
||||
{"T", tile, "tile", TILE}, // 平铺布局
|
||||
{"G", grid, "grid", GRID}, // 格子布局
|
||||
{"M", monocle, "monocle", MONOCLE}, // 单屏布局
|
||||
{"K", deck, "deck", DECK}, // 卡片布局
|
||||
{"CT", center_tile, "center_tile", CENTER_TILE}, // 居中布局
|
||||
{"VS", vertical_scroller, "vertical_scroller",
|
||||
VERTICAL_SCROLLER}, // 垂直滚动布局
|
||||
{"VT", vertical_tile, "vertical_tile", VERTICAL_TILE}, // 垂直平铺布局
|
||||
};
|
||||
|
|
@ -1,292 +1,91 @@
|
|||
void vertical_fibonacci(Monitor *mon, int s) {
|
||||
unsigned int i = 0, n = 0, nx, ny, nw, nh;
|
||||
void vertical_tile(Monitor *m) {
|
||||
unsigned int i, n = 0, w, r, ie = enablegaps, mh, mx, tx;
|
||||
Client *c = NULL;
|
||||
unsigned int cur_gappih = enablegaps ? mon->gappih : 0;
|
||||
unsigned int cur_gappiv = enablegaps ? mon->gappiv : 0;
|
||||
unsigned int cur_gappoh = enablegaps ? mon->gappoh : 0;
|
||||
unsigned int cur_gappov = enablegaps ? mon->gappov : 0;
|
||||
|
||||
cur_gappih = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappiv = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappoh = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov = smartgaps && mon->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
|
||||
n = mon->visible_tiling_clients;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
// Initial dimensions including outer gaps
|
||||
nx = mon->w.x + cur_gappoh;
|
||||
ny = mon->w.y + cur_gappov;
|
||||
nw = mon->w.width - 2 * cur_gappoh;
|
||||
nh = mon->w.height - 2 * cur_gappov;
|
||||
|
||||
// First pass: calculate client geometries
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, mon) || !ISTILED(c))
|
||||
continue;
|
||||
|
||||
c->bw = mon->visible_tiling_clients == 1 && no_border_when_single &&
|
||||
smartgaps
|
||||
? 0
|
||||
: borderpx;
|
||||
if ((i % 2 && nw / 2 > 2 * c->bw) || (!(i % 2) && nh / 2 > 2 * c->bw)) {
|
||||
if (i < n - 1) {
|
||||
if (i % 2) {
|
||||
if (i == 1) {
|
||||
nw = nw * mon->pertag->smfacts[mon->pertag->curtag];
|
||||
} else {
|
||||
nw = (nw - cur_gappih) / 2;
|
||||
}
|
||||
} else {
|
||||
nh = (nh - cur_gappiv) / 2;
|
||||
}
|
||||
|
||||
if ((i % 4) == 2 && !s)
|
||||
ny += nh + cur_gappiv;
|
||||
else if ((i % 4) == 3 && !s)
|
||||
nx += nw + cur_gappih;
|
||||
}
|
||||
|
||||
if ((i % 4) == 0) {
|
||||
if (s)
|
||||
nx += nw + cur_gappih;
|
||||
else
|
||||
nx -= nw + cur_gappih;
|
||||
} else if ((i % 4) == 1)
|
||||
ny += nh + cur_gappiv;
|
||||
else if ((i % 4) == 2)
|
||||
nx += nw + cur_gappih;
|
||||
else if ((i % 4) == 3) {
|
||||
if (s)
|
||||
ny += nh + cur_gappiv;
|
||||
else
|
||||
ny -= nh + cur_gappiv;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
if (n != 1)
|
||||
nh = (mon->w.height - 2 * cur_gappov) *
|
||||
mon->pertag->mfacts[mon->pertag->curtag];
|
||||
nx = mon->w.x + cur_gappoh;
|
||||
} else if (i == 1) {
|
||||
nh = mon->w.height - 2 * cur_gappov - nh - cur_gappiv;
|
||||
} else if (i == 2) {
|
||||
nw = mon->w.width - 2 * cur_gappoh - nw - cur_gappih;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
c->geom = (struct wlr_box){.x = nx, .y = ny, .width = nw, .height = nh};
|
||||
}
|
||||
|
||||
// Second pass: apply gaps between clients
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, mon) || !ISTILED(c))
|
||||
continue;
|
||||
|
||||
unsigned int right_gap = 0;
|
||||
unsigned int bottom_gap = 0;
|
||||
Client *nc = NULL;
|
||||
|
||||
wl_list_for_each(nc, &clients, link) {
|
||||
if (!VISIBLEON(nc, mon) || !ISTILED(nc))
|
||||
continue;
|
||||
|
||||
if (c == nc)
|
||||
continue;
|
||||
|
||||
// Check for right neighbor
|
||||
if (c->geom.y == nc->geom.y &&
|
||||
c->geom.x + c->geom.width == nc->geom.x) {
|
||||
right_gap = cur_gappih;
|
||||
}
|
||||
|
||||
// Check for bottom neighbor
|
||||
if (c->geom.x == nc->geom.x &&
|
||||
c->geom.y + c->geom.height == nc->geom.y) {
|
||||
bottom_gap = cur_gappiv;
|
||||
}
|
||||
}
|
||||
|
||||
resize(c,
|
||||
(struct wlr_box){.x = c->geom.x,
|
||||
.y = c->geom.y,
|
||||
.width = c->geom.width - right_gap,
|
||||
.height = c->geom.height - bottom_gap},
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
void vertical_dwindle(Monitor *mon) { vertical_fibonacci(mon, 1); }
|
||||
|
||||
void vertical_spiral(Monitor *mon) { vertical_fibonacci(mon, 0); }
|
||||
|
||||
void vertical_grid(Monitor *m) {
|
||||
unsigned int i, n;
|
||||
unsigned int cx, cy, cw, ch;
|
||||
unsigned int dy;
|
||||
unsigned int rows, cols, overrows;
|
||||
Client *c = NULL;
|
||||
|
||||
n = m->isoverview ? m->visible_clients : m->visible_tiling_clients;
|
||||
|
||||
if (n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (n == 1) {
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
|
||||
if (c->mon != m)
|
||||
continue;
|
||||
|
||||
c->bw = m->visible_tiling_clients == 1 && no_border_when_single &&
|
||||
smartgaps
|
||||
? 0
|
||||
: borderpx;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_should_ignore_focus(c)) ||
|
||||
ISTILED(c))) {
|
||||
ch = (m->w.height - 2 * overviewgappo) * 0.7;
|
||||
cw = (m->w.width - 2 * overviewgappo) * 0.8;
|
||||
c->geom.x = m->w.x + (m->w.width - cw) / 2;
|
||||
c->geom.y = m->w.y + (m->w.height - ch) / 2;
|
||||
c->geom.width = cw - 2 * c->bw;
|
||||
c->geom.height = ch - 2 * c->bw;
|
||||
resize(c, c->geom, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 2) {
|
||||
ch = (m->w.height - 2 * overviewgappo - overviewgappi) / 2;
|
||||
cw = (m->w.width - 2 * overviewgappo) * 0.65;
|
||||
i = 0;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
|
||||
if (c->mon != m)
|
||||
continue;
|
||||
|
||||
c->bw = m->visible_tiling_clients == 1 && no_border_when_single &&
|
||||
smartgaps
|
||||
? 0
|
||||
: borderpx;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_should_ignore_focus(c)) ||
|
||||
ISTILED(c))) {
|
||||
if (i == 0) {
|
||||
c->geom.x = m->w.x + (m->w.width - cw) / 2 + overviewgappo;
|
||||
c->geom.y = m->w.y + overviewgappo;
|
||||
c->geom.width = cw - 2 * c->bw;
|
||||
c->geom.height = ch - 2 * c->bw;
|
||||
resize(c, c->geom, 0);
|
||||
} else if (i == 1) {
|
||||
c->geom.x = m->w.x + (m->w.width - cw) / 2 + overviewgappo;
|
||||
c->geom.y = m->w.y + ch + overviewgappo + overviewgappi;
|
||||
c->geom.width = cw - 2 * c->bw;
|
||||
c->geom.height = ch - 2 * c->bw;
|
||||
resize(c, c->geom, 0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (rows = 0; rows <= n / 2; rows++) {
|
||||
if (rows * rows >= n) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
|
||||
|
||||
cw = (m->w.width - 2 * overviewgappo - (cols - 1) * overviewgappi) / cols;
|
||||
ch = (m->w.height - 2 * overviewgappo - (rows - 1) * overviewgappi) / rows;
|
||||
|
||||
overrows = n % rows;
|
||||
if (overrows) {
|
||||
dy =
|
||||
(m->w.height - overrows * ch - (overrows - 1) * overviewgappi) / 2 -
|
||||
overviewgappo;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->mon != m)
|
||||
continue;
|
||||
|
||||
c->bw =
|
||||
m->visible_tiling_clients == 1 && no_border_when_single && smartgaps
|
||||
? 0
|
||||
: borderpx;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_should_ignore_focus(c)) || ISTILED(c))) {
|
||||
cx = m->w.x + (i / rows) * (cw + overviewgappi);
|
||||
cy = m->w.y + (i % rows) * (ch + overviewgappi);
|
||||
if (overrows && i >= n - overrows) {
|
||||
cy += dy;
|
||||
}
|
||||
c->geom.x = cx + overviewgappo;
|
||||
c->geom.y = cy + overviewgappo;
|
||||
c->geom.width = cw - 2 * c->bw;
|
||||
c->geom.height = ch - 2 * c->bw;
|
||||
resize(c, c->geom, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vertical_deck(Monitor *m) {
|
||||
unsigned int mh, mx;
|
||||
int i, n = 0;
|
||||
Client *c = NULL;
|
||||
unsigned int cur_gappiv = enablegaps ? m->gappiv : 0;
|
||||
unsigned int cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
unsigned int cur_gappov = enablegaps ? m->gappov : 0;
|
||||
|
||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
Client *fc = NULL;
|
||||
double mfact = 0;
|
||||
int master_num = 0;
|
||||
int stack_num = 0;
|
||||
|
||||
n = m->visible_tiling_clients;
|
||||
master_num = m->pertag->nmasters[m->pertag->curtag];
|
||||
stack_num = n - master_num;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
float mfact = m->pertag ? m->pertag->mfacts[m->pertag->curtag] : m->mfact;
|
||||
unsigned int cur_gapih = enablegaps ? m->gappih : 0;
|
||||
unsigned int cur_gapiv = enablegaps ? m->gappiv : 0;
|
||||
unsigned int cur_gapoh = enablegaps ? m->gappoh : 0;
|
||||
unsigned int cur_gapov = enablegaps ? m->gappov : 0;
|
||||
|
||||
if (n > m->nmaster)
|
||||
mh = m->nmaster ? round((m->w.height - 2 * cur_gappov) * mfact) : 0;
|
||||
cur_gapih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapih;
|
||||
cur_gapiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapiv;
|
||||
cur_gapoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapoh;
|
||||
cur_gapov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapov;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc))
|
||||
break;
|
||||
}
|
||||
|
||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||
: m->pertag->mfacts[m->pertag->curtag];
|
||||
|
||||
if (n > m->pertag->nmasters[m->pertag->curtag])
|
||||
mh = m->pertag->nmasters[m->pertag->curtag]
|
||||
? (m->w.height + cur_gapiv * ie) * mfact
|
||||
: 0;
|
||||
else
|
||||
mh = m->w.height - 2 * cur_gappov;
|
||||
mh = m->w.height - 2 * cur_gapov + cur_gapiv * ie;
|
||||
|
||||
i = mx = 0;
|
||||
i = 0;
|
||||
mx = tx = cur_gapih;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, m) || !ISTILED(c))
|
||||
continue;
|
||||
if (i < m->nmaster) {
|
||||
resize(
|
||||
c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh + mx,
|
||||
.y = m->w.y + cur_gappov,
|
||||
.width = (m->w.width - 2 * cur_gappoh - mx) /
|
||||
(MIN(n, m->nmaster) - i),
|
||||
.height = mh},
|
||||
0);
|
||||
mx += c->geom.width;
|
||||
} else {
|
||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||
r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
||||
if (c->master_inner_per > 0.0f) {
|
||||
w = (m->w.width - 2 * cur_gapih -
|
||||
cur_gapih * ie * (master_num - 1)) *
|
||||
c->master_inner_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
w = (m->w.width - mx - cur_gapih - cur_gapih * ie * (r - 1)) /
|
||||
r;
|
||||
c->master_inner_per = w / (m->w.width - mx - cur_gapih -
|
||||
cur_gapih * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
resize(c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||
.y = m->w.y + mh + cur_gappov + cur_gappiv,
|
||||
.width = m->w.width - 2 * cur_gappoh,
|
||||
.height = m->w.height - mh -
|
||||
2 * cur_gappov - cur_gappiv},
|
||||
(struct wlr_box){.x = m->w.x + mx,
|
||||
.y = m->w.y + cur_gapov,
|
||||
.width = w,
|
||||
.height = mh - cur_gapiv * ie},
|
||||
0);
|
||||
if (c == focustop(m))
|
||||
wlr_scene_node_raise_to_top(&c->scene->node);
|
||||
mx += c->geom.width + cur_gapih * ie;
|
||||
} else {
|
||||
r = n - i;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
w = (m->w.width - 2 * cur_gapih -
|
||||
cur_gapih * ie * (stack_num - 1)) *
|
||||
c->stack_innder_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
w = (m->w.width - tx - cur_gapih - cur_gapih * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per = w / (m->w.width - tx - cur_gapih -
|
||||
cur_gapih * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
resize(c,
|
||||
(struct wlr_box){.x = m->w.x + tx,
|
||||
.y = m->w.y + mh + cur_gapov,
|
||||
.width = w,
|
||||
.height = m->w.height - mh - 2 * cur_gapov},
|
||||
0);
|
||||
tx += c->geom.width + cur_gapih * ie;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
@ -418,60 +217,3 @@ void vertical_scroller(Monitor *m) {
|
|||
|
||||
free(tempClients);
|
||||
}
|
||||
|
||||
void vertical_tile(Monitor *m) {
|
||||
unsigned int i, n = 0, w, r, ie = enablegaps, mh, mx, tx;
|
||||
Client *c = NULL;
|
||||
|
||||
n = m->visible_tiling_clients;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
unsigned int cur_gappiv = enablegaps ? m->gappiv : 0;
|
||||
unsigned int cur_gappih = enablegaps ? m->gappih : 0;
|
||||
unsigned int cur_gappov = enablegaps ? m->gappov : 0;
|
||||
unsigned int cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
|
||||
cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv;
|
||||
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||
|
||||
if (n > m->pertag->nmasters[m->pertag->curtag])
|
||||
mh = m->pertag->nmasters[m->pertag->curtag]
|
||||
? (m->w.height + cur_gappiv * ie) *
|
||||
m->pertag->mfacts[m->pertag->curtag]
|
||||
: 0;
|
||||
else
|
||||
mh = m->w.height - 2 * cur_gappoh + cur_gappiv * ie;
|
||||
i = 0;
|
||||
mx = tx = cur_gappov;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, m) || !ISTILED(c))
|
||||
continue;
|
||||
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||
r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i;
|
||||
w = (m->w.width - mx - cur_gappov - cur_gappiv * ie * (r - 1)) / r;
|
||||
resize(c,
|
||||
(struct wlr_box){.x = m->w.x + mx,
|
||||
.y = m->w.y + cur_gappoh,
|
||||
.width = w,
|
||||
.height = mh - cur_gappih * ie},
|
||||
0);
|
||||
mx += c->geom.width + cur_gappiv * ie;
|
||||
} else {
|
||||
r = n - i;
|
||||
w = (m->w.width - tx - cur_gappov - cur_gappiv * ie * (r - 1)) / r;
|
||||
resize(
|
||||
c,
|
||||
(struct wlr_box){.x = m->w.x + tx,
|
||||
.y = m->w.y + mh + cur_gappoh,
|
||||
.width = w,
|
||||
.height = m->w.height - mh - 2 * cur_gappoh},
|
||||
0);
|
||||
tx += c->geom.width + cur_gappiv * ie;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
135
src/mango.c
135
src/mango.c
|
|
@ -253,7 +253,8 @@ struct Client {
|
|||
/* Must keep these three elements in this order */
|
||||
unsigned int type; /* XDGShell or X11* */
|
||||
struct wlr_box geom, pending, float_geom, animainit_geom,
|
||||
overview_backup_geom, current; /* layout-relative, includes border */
|
||||
overview_backup_geom, current,
|
||||
drag_begin_geom; /* layout-relative, includes border */
|
||||
Monitor *mon;
|
||||
struct wlr_scene_tree *scene;
|
||||
struct wlr_scene_rect *border; /* top, bottom, left, right */
|
||||
|
|
@ -337,6 +338,12 @@ struct Client {
|
|||
float unfocused_opacity;
|
||||
char oldmonname[128];
|
||||
int noblur;
|
||||
double master_mfact_per, master_inner_per, stack_innder_per;
|
||||
double old_master_mfact_per, old_master_inner_per, old_stack_innder_per;
|
||||
double old_scroller_pproportion;
|
||||
bool ismaster;
|
||||
bool cursor_in_upper_half, cursor_in_left_half;
|
||||
bool isleftstack;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -413,6 +420,7 @@ typedef struct {
|
|||
const char *symbol;
|
||||
void (*arrange)(Monitor *);
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
} Layout;
|
||||
|
||||
struct Monitor {
|
||||
|
|
@ -706,6 +714,9 @@ static unsigned int get_tag_status(unsigned int tag, Monitor *m);
|
|||
static void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state);
|
||||
static Client *get_next_stack_client(Client *c, bool reverse);
|
||||
static void set_float_malposition(Client *tc);
|
||||
static void set_size_per(Monitor *m, Client *c);
|
||||
static void resize_tile_client(Client *grabc, bool isdrag, int offsetx,
|
||||
int offsety, unsigned int time);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
#include "dispatch/bind_declare.h"
|
||||
|
|
@ -765,7 +776,10 @@ static struct wl_list keyboards;
|
|||
static struct wl_list inputdevices;
|
||||
static unsigned int cursor_mode;
|
||||
static Client *grabc;
|
||||
static int grabcx, grabcy; /* client-relative */
|
||||
static int grabcx, grabcy; /* client-relative */
|
||||
static int drag_begin_cursorx, drag_begin_cursory; /* client-relative */
|
||||
static bool start_drag_window = false;
|
||||
static int last_apply_drap_time = 0;
|
||||
|
||||
static struct wlr_output_layout *output_layout;
|
||||
static struct wlr_box sgeom;
|
||||
|
|
@ -806,11 +820,10 @@ static struct {
|
|||
#include "config/preset.h"
|
||||
|
||||
struct Pertag {
|
||||
unsigned int curtag, prevtag; /* current and previous tag */
|
||||
int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
||||
float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
|
||||
float smfacts[LENGTH(tags) + 1]; /* smfacts per tag */
|
||||
bool no_hide[LENGTH(tags) + 1]; /* no_hide per tag */
|
||||
unsigned int curtag, prevtag; /* current and previous tag */
|
||||
int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
||||
float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
|
||||
bool no_hide[LENGTH(tags) + 1]; /* no_hide per tag */
|
||||
const Layout
|
||||
*ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */
|
||||
};
|
||||
|
|
@ -868,6 +881,7 @@ static struct wlr_xwayland *xwayland;
|
|||
#include "dispatch/bind_define.h"
|
||||
#include "ext-protocol/all.h"
|
||||
#include "fetch/fetch.h"
|
||||
#include "layout/arrange.h"
|
||||
#include "layout/horizontal.h"
|
||||
#include "layout/vertical.h"
|
||||
|
||||
|
|
@ -1291,6 +1305,8 @@ void applyrules(Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
set_size_per(mon, c);
|
||||
|
||||
// if no geom rule hit and is normal winodw, use the center pos and record
|
||||
// the hit size
|
||||
if (!hit_rule_pos &&
|
||||
|
|
@ -1366,57 +1382,6 @@ void applyrules(Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
void // 17
|
||||
arrange(Monitor *m, bool want_animation) {
|
||||
Client *c = NULL;
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
if (!m->wlr_output->enabled)
|
||||
return;
|
||||
|
||||
m->visible_clients = 0;
|
||||
m->visible_tiling_clients = 0;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->iskilling)
|
||||
continue;
|
||||
|
||||
if (c->mon == m && (c->isglobal || c->isunglobal)) {
|
||||
c->tags = m->tagset[m->seltags];
|
||||
if (c->mon->sel == NULL)
|
||||
focusclient(c, 0);
|
||||
}
|
||||
|
||||
if (c->mon == m) {
|
||||
if (VISIBLEON(c, m)) {
|
||||
|
||||
m->visible_clients++;
|
||||
if (ISTILED(c))
|
||||
m->visible_tiling_clients++;
|
||||
|
||||
set_arrange_visible(m, c, want_animation);
|
||||
} else {
|
||||
set_arrange_hidden(m, c, want_animation);
|
||||
}
|
||||
}
|
||||
|
||||
if (c->mon == m && c->ismaxmizescreen && !c->animation.tagouted &&
|
||||
!c->animation.tagouting && VISIBLEON(c, m)) {
|
||||
reset_maxmizescreen_size(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (m->isoverview) {
|
||||
overviewlayout.arrange(m);
|
||||
} else {
|
||||
m->pertag->ltidxs[m->pertag->curtag]->arrange(m);
|
||||
}
|
||||
|
||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||
checkidleinhibitor(NULL);
|
||||
}
|
||||
|
||||
void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area,
|
||||
int exclusive) {
|
||||
LayerSurface *l = NULL;
|
||||
|
|
@ -1917,6 +1882,8 @@ buttonpress(struct wl_listener *listener, void *data) {
|
|||
selmon->sel = grabc;
|
||||
tmpc = grabc;
|
||||
grabc = NULL;
|
||||
start_drag_window = false;
|
||||
last_apply_drap_time = 0;
|
||||
if (tmpc->drag_to_tile && drag_tile_to_tile) {
|
||||
place_drag_tile_client(tmpc);
|
||||
} else {
|
||||
|
|
@ -2667,7 +2634,6 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
for (i = 0; i <= LENGTH(tags); i++) {
|
||||
m->pertag->nmasters[i] = m->nmaster;
|
||||
m->pertag->mfacts[i] = m->mfact;
|
||||
m->pertag->smfacts[i] = default_smfact;
|
||||
m->pertag->ltidxs[i] = m->lt;
|
||||
}
|
||||
|
||||
|
|
@ -3542,6 +3508,9 @@ void init_client_properties(Client *c) {
|
|||
c->ignore_maximize = 0;
|
||||
c->ignore_minimize = 1;
|
||||
c->iscustomsize = 0;
|
||||
c->master_mfact_per = 0.0f;
|
||||
c->master_inner_per = 0.0f;
|
||||
c->stack_innder_per = 0.0f;
|
||||
}
|
||||
|
||||
void // old fix to 0.5
|
||||
|
|
@ -3866,14 +3835,18 @@ void motionnotify(unsigned int time, struct wlr_input_device *device, double dx,
|
|||
resize(grabc, grabc->float_geom, 1);
|
||||
return;
|
||||
} else if (cursor_mode == CurResize) {
|
||||
grabc->iscustomsize = 1;
|
||||
grabc->float_geom =
|
||||
(struct wlr_box){.x = grabc->geom.x,
|
||||
.y = grabc->geom.y,
|
||||
.width = (int)round(cursor->x) - grabc->geom.x,
|
||||
.height = (int)round(cursor->y) - grabc->geom.y};
|
||||
resize(grabc, grabc->float_geom, 1);
|
||||
return;
|
||||
if (grabc->isfloating) {
|
||||
grabc->iscustomsize = 1;
|
||||
grabc->float_geom = (struct wlr_box){
|
||||
.x = grabc->geom.x,
|
||||
.y = grabc->geom.y,
|
||||
.width = (int)round(cursor->x) - grabc->geom.x,
|
||||
.height = (int)round(cursor->y) - grabc->geom.y};
|
||||
resize(grabc, grabc->float_geom, 1);
|
||||
return;
|
||||
} else {
|
||||
resize_tile_client(grabc, true, 0, 0, time);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's no client surface under the cursor, set the cursor image
|
||||
|
|
@ -4174,12 +4147,27 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
|
||||
Monitor *tmp_mon = NULL;
|
||||
unsigned int tmp_tags;
|
||||
double master_inner_per = 0.0f;
|
||||
double master_mfact_per = 0.0f;
|
||||
double stack_innder_per = 0.0f;
|
||||
|
||||
if (c1 == NULL || c2 == NULL ||
|
||||
(!exchange_cross_monitor && c1->mon != c2->mon)) {
|
||||
return;
|
||||
}
|
||||
|
||||
master_inner_per = c1->master_inner_per;
|
||||
master_mfact_per = c1->master_mfact_per;
|
||||
stack_innder_per = c1->stack_innder_per;
|
||||
|
||||
c1->master_inner_per = c2->master_inner_per;
|
||||
c1->master_mfact_per = c2->master_mfact_per;
|
||||
c1->stack_innder_per = c2->stack_innder_per;
|
||||
|
||||
c2->master_inner_per = master_inner_per;
|
||||
c2->master_mfact_per = master_mfact_per;
|
||||
c2->stack_innder_per = stack_innder_per;
|
||||
|
||||
struct wl_list *tmp1_prev = c1->link.prev;
|
||||
struct wl_list *tmp2_prev = c2->link.prev;
|
||||
struct wl_list *tmp1_next = c1->link.next;
|
||||
|
|
@ -4403,6 +4391,10 @@ setfloating(Client *c, int floating) {
|
|||
layers[c->isfloating ? LyrTop : LyrTile]);
|
||||
}
|
||||
|
||||
if (!c->isfloating) {
|
||||
set_size_per(c->mon, c);
|
||||
}
|
||||
|
||||
arrange(c->mon, false);
|
||||
setborder_color(c);
|
||||
printstatus();
|
||||
|
|
@ -4447,12 +4439,15 @@ void setmaxmizescreen(Client *c, int maxmizescreen) {
|
|||
c->ismaxmizescreen = 0;
|
||||
if (c->isfloating)
|
||||
setfloating(c, 1);
|
||||
arrange(c->mon, false);
|
||||
}
|
||||
|
||||
wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile
|
||||
: c->isfloating ? LyrTop
|
||||
: LyrTile]);
|
||||
if (!c->ismaxmizescreen) {
|
||||
set_size_per(c->mon, c);
|
||||
}
|
||||
arrange(c->mon, false);
|
||||
}
|
||||
|
||||
void setfakefullscreen(Client *c, int fakefullscreen) {
|
||||
|
|
@ -4508,6 +4503,10 @@ void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带
|
|||
layers[fullscreen || c->isfloating ? LyrTop : LyrTile]);
|
||||
}
|
||||
|
||||
if (!c->isfullscreen) {
|
||||
set_size_per(c->mon, c);
|
||||
}
|
||||
|
||||
arrange(c->mon, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue