mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-04-10 08:21:13 -04:00
feat: support resize tile window
This commit is contained in:
parent
aec8c29210
commit
fe427f6917
6 changed files with 238 additions and 281 deletions
|
|
@ -897,6 +897,11 @@ void client_set_pending_state(Client *c) {
|
||||||
c->istagswitching = 0;
|
c->istagswitching = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (start_drag_window) {
|
||||||
|
c->animation.should_animate = false;
|
||||||
|
c->animation.duration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 开始动画
|
// 开始动画
|
||||||
client_commit(c);
|
client_commit(c);
|
||||||
c->dirty = true;
|
c->dirty = true;
|
||||||
|
|
|
||||||
|
|
@ -309,15 +309,15 @@ moveresize(const Arg *arg) {
|
||||||
xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL);
|
xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL);
|
||||||
if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen)
|
if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Float the window and tell motionnotify to grab it */
|
/* 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;
|
grabc->drag_to_tile = true;
|
||||||
setfloating(grabc, 1);
|
setfloating(grabc, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cursor_mode = arg->ui) {
|
switch (cursor_mode = arg->ui) {
|
||||||
case CurMove:
|
case CurMove:
|
||||||
|
|
||||||
grabcx = cursor->x - grabc->geom.x;
|
grabcx = cursor->x - grabc->geom.x;
|
||||||
grabcy = cursor->y - grabc->geom.y;
|
grabcy = cursor->y - grabc->geom.y;
|
||||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "grab");
|
wlr_cursor_set_xcursor(cursor, cursor_mgr, "grab");
|
||||||
|
|
@ -325,9 +325,14 @@ moveresize(const Arg *arg) {
|
||||||
case CurResize:
|
case CurResize:
|
||||||
/* Doesn't work for X11 output - the next absolute motion event
|
/* Doesn't work for X11 output - the next absolute motion event
|
||||||
* returns the cursor to where it started */
|
* returns the cursor to where it started */
|
||||||
wlr_cursor_warp_closest(cursor, NULL, grabc->geom.x + grabc->geom.width,
|
if (grabc->isfloating) {
|
||||||
grabc->geom.y + grabc->geom.height);
|
wlr_cursor_warp_closest(cursor, NULL,
|
||||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "bottom_right_corner");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
void grid(Monitor *m) {
|
||||||
unsigned int i, n;
|
unsigned int i, n;
|
||||||
|
|
@ -576,6 +451,8 @@ void center_tile(Monitor *m) {
|
||||||
void tile(Monitor *m) {
|
void tile(Monitor *m) {
|
||||||
unsigned int i, n = 0, h, r, ie = enablegaps, mw, my, ty;
|
unsigned int i, n = 0, h, r, ie = enablegaps, mw, my, ty;
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
Client *fc = NULL;
|
||||||
|
double mfact = 0;
|
||||||
|
|
||||||
n = m->visible_tiling_clients;
|
n = m->visible_tiling_clients;
|
||||||
|
|
||||||
|
|
@ -592,10 +469,14 @@ void tile(Monitor *m) {
|
||||||
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
|
||||||
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
|
||||||
|
|
||||||
|
wl_list_for_each(fc, &clients, link) { break; }
|
||||||
|
|
||||||
|
mfact = fc->master_width_per > 0.0f ? fc->master_width_per
|
||||||
|
: m->pertag->mfacts[m->pertag->curtag];
|
||||||
|
|
||||||
if (n > m->pertag->nmasters[m->pertag->curtag])
|
if (n > m->pertag->nmasters[m->pertag->curtag])
|
||||||
mw = m->pertag->nmasters[m->pertag->curtag]
|
mw = m->pertag->nmasters[m->pertag->curtag]
|
||||||
? (m->w.width + cur_gappih * ie) *
|
? (m->w.width + cur_gappih * ie) * mfact
|
||||||
m->pertag->mfacts[m->pertag->curtag]
|
|
||||||
: 0;
|
: 0;
|
||||||
else
|
else
|
||||||
mw = m->w.width - 2 * cur_gappoh + cur_gappih * ie;
|
mw = m->w.width - 2 * cur_gappoh + cur_gappih * ie;
|
||||||
|
|
@ -606,7 +487,18 @@ void tile(Monitor *m) {
|
||||||
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 = 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_height_per > 0.0f) {
|
||||||
|
h = (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (r - 1)) *
|
||||||
|
c->master_height_per;
|
||||||
|
c->master_width_per = mfact;
|
||||||
|
} else {
|
||||||
|
h = (m->w.height - my - cur_gappov -
|
||||||
|
cur_gappiv * ie * (r - 1)) /
|
||||||
|
r;
|
||||||
|
c->master_height_per = h / (m->w.height - my - cur_gappov -
|
||||||
|
cur_gappiv * ie * (r - 1));
|
||||||
|
c->master_width_per = mfact;
|
||||||
|
}
|
||||||
resize(c,
|
resize(c,
|
||||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||||
.y = m->w.y + my,
|
.y = m->w.y + my,
|
||||||
|
|
@ -616,7 +508,21 @@ void tile(Monitor *m) {
|
||||||
my += c->geom.height + cur_gappiv * ie;
|
my += c->geom.height + cur_gappiv * ie;
|
||||||
} else {
|
} else {
|
||||||
r = n - i;
|
r = n - i;
|
||||||
h = (m->w.height - ty - cur_gappov - cur_gappiv * ie * (r - 1)) / r;
|
if (c->slave_height_per > 0.0f) {
|
||||||
|
h = (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (r - 1)) *
|
||||||
|
c->slave_height_per;
|
||||||
|
c->master_width_per = mfact;
|
||||||
|
} else {
|
||||||
|
h = (m->w.height - ty - cur_gappov -
|
||||||
|
cur_gappiv * ie * (r - 1)) /
|
||||||
|
r;
|
||||||
|
c->slave_height_per = h / (m->w.height - ty - cur_gappov -
|
||||||
|
cur_gappiv * ie * (r - 1));
|
||||||
|
c->master_width_per = mfact;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wlr_log(WLR_ERROR, "slave_height_per: %f", c->slave_height_per);
|
||||||
|
|
||||||
resize(c,
|
resize(c,
|
||||||
(struct wlr_box){.x = m->w.x + mw + cur_gappoh,
|
(struct wlr_box){.x = m->w.x + mw + cur_gappoh,
|
||||||
.y = m->w.y + ty,
|
.y = m->w.y + ty,
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,12 @@ static void overview(Monitor *m);
|
||||||
static void grid(Monitor *m);
|
static void grid(Monitor *m);
|
||||||
static void scroller(Monitor *m);
|
static void scroller(Monitor *m);
|
||||||
static void deck(Monitor *mon);
|
static void deck(Monitor *mon);
|
||||||
static void dwindle(Monitor *mon);
|
|
||||||
static void spiral(Monitor *mon);
|
|
||||||
static void monocle(Monitor *m);
|
static void monocle(Monitor *m);
|
||||||
static void vertical_tile(Monitor *m);
|
static void vertical_tile(Monitor *m);
|
||||||
static void vertical_overview(Monitor *m);
|
static void vertical_overview(Monitor *m);
|
||||||
static void vertical_grid(Monitor *m);
|
static void vertical_grid(Monitor *m);
|
||||||
static void vertical_scroller(Monitor *m);
|
static void vertical_scroller(Monitor *m);
|
||||||
static void vertical_deck(Monitor *mon);
|
static void vertical_deck(Monitor *mon);
|
||||||
static void vertical_dwindle(Monitor *mon);
|
|
||||||
static void vertical_spiral(Monitor *mon);
|
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
Layout overviewlayout = {"", overview, "overview"};
|
Layout overviewlayout = {"", overview, "overview"};
|
||||||
|
|
@ -25,14 +21,10 @@ Layout layouts[] = {
|
||||||
{"T", tile, "tile"}, // 堆栈布局
|
{"T", tile, "tile"}, // 堆栈布局
|
||||||
{"G", grid, "grid"},
|
{"G", grid, "grid"},
|
||||||
{"M", monocle, "monocle"},
|
{"M", monocle, "monocle"},
|
||||||
{"D", dwindle, "dwindle"},
|
|
||||||
{"P", spiral, "spiral"},
|
|
||||||
{"K", deck, "deck"},
|
{"K", deck, "deck"},
|
||||||
{"CT", center_tile, "center_tile"},
|
{"CT", center_tile, "center_tile"},
|
||||||
{"VS", vertical_scroller, "vertical_scroller"},
|
{"VS", vertical_scroller, "vertical_scroller"},
|
||||||
{"VT", vertical_tile, "vertical_tile"},
|
{"VT", vertical_tile, "vertical_tile"},
|
||||||
{"VD", vertical_dwindle, "vertical_dwindle"},
|
|
||||||
{"VP", vertical_spiral, "vertical_spiral"},
|
|
||||||
{"VG", vertical_grid, "vertical_grid"},
|
{"VG", vertical_grid, "vertical_grid"},
|
||||||
{"VK", vertical_deck, "vertical_deck"},
|
{"VK", vertical_deck, "vertical_deck"},
|
||||||
};
|
};
|
||||||
|
|
@ -1,128 +1,3 @@
|
||||||
void vertical_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;
|
|
||||||
|
|
||||||
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) {
|
void vertical_grid(Monitor *m) {
|
||||||
unsigned int i, n;
|
unsigned int i, n;
|
||||||
unsigned int cx, cy, cw, ch;
|
unsigned int cx, cy, cw, ch;
|
||||||
|
|
|
||||||
202
src/mango.c
202
src/mango.c
|
|
@ -253,7 +253,8 @@ struct Client {
|
||||||
/* Must keep these three elements in this order */
|
/* Must keep these three elements in this order */
|
||||||
unsigned int type; /* XDGShell or X11* */
|
unsigned int type; /* XDGShell or X11* */
|
||||||
struct wlr_box geom, pending, float_geom, animainit_geom,
|
struct wlr_box geom, pending, float_geom, animainit_geom,
|
||||||
overview_backup_geom, current; /* layout-relative, includes border */
|
overview_backup_geom, current,
|
||||||
|
begin_geom; /* layout-relative, includes border */
|
||||||
Monitor *mon;
|
Monitor *mon;
|
||||||
struct wlr_scene_tree *scene;
|
struct wlr_scene_tree *scene;
|
||||||
struct wlr_scene_rect *border; /* top, bottom, left, right */
|
struct wlr_scene_rect *border; /* top, bottom, left, right */
|
||||||
|
|
@ -337,6 +338,10 @@ struct Client {
|
||||||
float unfocused_opacity;
|
float unfocused_opacity;
|
||||||
char oldmonname[128];
|
char oldmonname[128];
|
||||||
int noblur;
|
int noblur;
|
||||||
|
double master_width_per, master_height_per, slave_height_per;
|
||||||
|
double old_master_width_per, old_master_height_per, old_slave_height_per;
|
||||||
|
bool ismaster;
|
||||||
|
bool cursor_in_upper_half;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -706,6 +711,7 @@ static unsigned int get_tag_status(unsigned int tag, Monitor *m);
|
||||||
static void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state);
|
static void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state);
|
||||||
static Client *get_next_stack_client(Client *c, bool reverse);
|
static Client *get_next_stack_client(Client *c, bool reverse);
|
||||||
static void set_float_malposition(Client *tc);
|
static void set_float_malposition(Client *tc);
|
||||||
|
static void set_size_per(Monitor *m, Client *c);
|
||||||
|
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/bind_declare.h"
|
#include "dispatch/bind_declare.h"
|
||||||
|
|
@ -765,7 +771,9 @@ static struct wl_list keyboards;
|
||||||
static struct wl_list inputdevices;
|
static struct wl_list inputdevices;
|
||||||
static unsigned int cursor_mode;
|
static unsigned int cursor_mode;
|
||||||
static Client *grabc;
|
static Client *grabc;
|
||||||
static int grabcx, grabcy; /* client-relative */
|
static int grabcx, grabcy; /* client-relative */
|
||||||
|
static int begin_cursorx, begin_cursory; /* client-relative */
|
||||||
|
static bool start_drag_window = false;
|
||||||
|
|
||||||
static struct wlr_output_layout *output_layout;
|
static struct wlr_output_layout *output_layout;
|
||||||
static struct wlr_box sgeom;
|
static struct wlr_box sgeom;
|
||||||
|
|
@ -1291,6 +1299,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
|
// if no geom rule hit and is normal winodw, use the center pos and record
|
||||||
// the hit size
|
// the hit size
|
||||||
if (!hit_rule_pos &&
|
if (!hit_rule_pos &&
|
||||||
|
|
@ -1366,9 +1376,50 @@ void applyrules(Client *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_size_per_mon(Monitor *m, double total_slave_hight_percent,
|
||||||
|
double total_master_height_percent, int master_num,
|
||||||
|
int slave_num) {
|
||||||
|
Client *c;
|
||||||
|
int i = 0;
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
|
||||||
|
if (total_master_height_percent <= 0.0)
|
||||||
|
return;
|
||||||
|
// wlr_log(WLR_ERROR,"reset before: %f %f", c->slave_height_per,
|
||||||
|
// total_slave_hight_percent);
|
||||||
|
|
||||||
|
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||||
|
c->ismaster = true;
|
||||||
|
c->slave_height_per = slave_num ? 1.0f / slave_num : 1.0f;
|
||||||
|
c->master_height_per =
|
||||||
|
c->master_height_per / total_master_height_percent;
|
||||||
|
} else {
|
||||||
|
// wlr_log(WLR_ERROR,"###### reset before: %f %f",
|
||||||
|
// c->slave_height_per,
|
||||||
|
// total_slave_hight_percent);
|
||||||
|
c->ismaster = false;
|
||||||
|
c->master_height_per = 1.0f / master_num;
|
||||||
|
c->slave_height_per =
|
||||||
|
c->slave_height_per / total_slave_hight_percent;
|
||||||
|
// wlr_log(WLR_ERROR,"------reset after: %f %f",
|
||||||
|
// c->slave_height_per,
|
||||||
|
// total_slave_hight_percent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void // 17
|
void // 17
|
||||||
arrange(Monitor *m, bool want_animation) {
|
arrange(Monitor *m, bool want_animation) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
double total_slave_height_percent = 0;
|
||||||
|
double total_master_height_percent = 0;
|
||||||
|
int i = 0;
|
||||||
|
int master_num = 0;
|
||||||
|
int slave_num = 0;
|
||||||
|
|
||||||
if (!m)
|
if (!m)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1392,8 +1443,19 @@ arrange(Monitor *m, bool want_animation) {
|
||||||
if (VISIBLEON(c, m)) {
|
if (VISIBLEON(c, m)) {
|
||||||
|
|
||||||
m->visible_clients++;
|
m->visible_clients++;
|
||||||
if (ISTILED(c))
|
if (ISTILED(c)) {
|
||||||
|
|
||||||
|
if (i < m->pertag->nmasters[m->pertag->curtag]) {
|
||||||
|
master_num++;
|
||||||
|
total_master_height_percent += c->master_height_per;
|
||||||
|
} else {
|
||||||
|
slave_num++;
|
||||||
|
total_slave_height_percent += c->slave_height_per;
|
||||||
|
}
|
||||||
|
|
||||||
m->visible_tiling_clients++;
|
m->visible_tiling_clients++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
set_arrange_visible(m, c, want_animation);
|
set_arrange_visible(m, c, want_animation);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1407,14 +1469,19 @@ arrange(Monitor *m, bool want_animation) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset_size_per_mon(m, total_slave_height_percent,
|
||||||
|
total_master_height_percent, master_num, slave_num);
|
||||||
|
|
||||||
if (m->isoverview) {
|
if (m->isoverview) {
|
||||||
overviewlayout.arrange(m);
|
overviewlayout.arrange(m);
|
||||||
} else {
|
} else {
|
||||||
m->pertag->ltidxs[m->pertag->curtag]->arrange(m);
|
m->pertag->ltidxs[m->pertag->curtag]->arrange(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
if (!start_drag_window) {
|
||||||
checkidleinhibitor(NULL);
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||||
|
checkidleinhibitor(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area,
|
void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area,
|
||||||
|
|
@ -1917,6 +1984,7 @@ buttonpress(struct wl_listener *listener, void *data) {
|
||||||
selmon->sel = grabc;
|
selmon->sel = grabc;
|
||||||
tmpc = grabc;
|
tmpc = grabc;
|
||||||
grabc = NULL;
|
grabc = NULL;
|
||||||
|
start_drag_window = false;
|
||||||
if (tmpc->drag_to_tile && drag_tile_to_tile) {
|
if (tmpc->drag_to_tile && drag_tile_to_tile) {
|
||||||
place_drag_tile_client(tmpc);
|
place_drag_tile_client(tmpc);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3542,6 +3610,20 @@ void init_client_properties(Client *c) {
|
||||||
c->ignore_maximize = 0;
|
c->ignore_maximize = 0;
|
||||||
c->ignore_minimize = 1;
|
c->ignore_minimize = 1;
|
||||||
c->iscustomsize = 0;
|
c->iscustomsize = 0;
|
||||||
|
c->master_width_per = 0.0f;
|
||||||
|
c->master_height_per = 0.0f;
|
||||||
|
c->slave_height_per = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_size_per(Monitor *m, Client *c) {
|
||||||
|
Client *fc = NULL;
|
||||||
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
||||||
|
c->master_width_per = fc->master_width_per;
|
||||||
|
c->master_height_per = fc->master_height_per;
|
||||||
|
c->slave_height_per = fc->slave_height_per;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void // old fix to 0.5
|
void // old fix to 0.5
|
||||||
|
|
@ -3791,6 +3873,68 @@ void motionabsolute(struct wl_listener *listener, void *data) {
|
||||||
motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
|
motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resize_tile_client(Client *grabc) {
|
||||||
|
Client *tc;
|
||||||
|
|
||||||
|
if (!start_drag_window) {
|
||||||
|
begin_cursorx = cursor->x;
|
||||||
|
begin_cursory = cursor->y;
|
||||||
|
start_drag_window = true;
|
||||||
|
|
||||||
|
// 记录初始状态
|
||||||
|
grabc->old_master_width_per = grabc->master_width_per;
|
||||||
|
grabc->old_master_height_per = grabc->master_height_per;
|
||||||
|
grabc->old_slave_height_per = grabc->slave_height_per;
|
||||||
|
grabc->cursor_in_upper_half =
|
||||||
|
cursor->y < grabc->geom.y + grabc->geom.height / 2;
|
||||||
|
// 记录初始几何信息
|
||||||
|
grabc->begin_geom = grabc->geom;
|
||||||
|
} else {
|
||||||
|
// 计算相对于屏幕尺寸的比例变化
|
||||||
|
float delta_x = (float)(cursor->x - begin_cursorx) *
|
||||||
|
(1 - grabc->old_master_width_per) /
|
||||||
|
grabc->begin_geom.width;
|
||||||
|
float delta_y = (float)(cursor->y - begin_cursory) *
|
||||||
|
(grabc->old_slave_height_per) /
|
||||||
|
grabc->begin_geom.height;
|
||||||
|
|
||||||
|
|
||||||
|
bool moving_up = cursor->y < begin_cursory;
|
||||||
|
bool moving_down = cursor->y > begin_cursory;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接设置新的比例,基于初始值 + 变化量
|
||||||
|
float new_master_width_per = grabc->old_master_width_per + delta_x;
|
||||||
|
float new_master_height_per = grabc->old_master_height_per + delta_y;
|
||||||
|
float new_slave_height_per = grabc->old_slave_height_per + delta_y;
|
||||||
|
|
||||||
|
// 应用限制,确保比例在合理范围内
|
||||||
|
new_master_width_per = fmaxf(0.1f, fminf(0.9f, new_master_width_per));
|
||||||
|
new_master_height_per = fmaxf(0.1f, fminf(0.9f, new_master_height_per));
|
||||||
|
new_slave_height_per = fmaxf(0.1f, fminf(0.9f, new_slave_height_per));
|
||||||
|
|
||||||
|
// 应用到所有平铺窗口
|
||||||
|
wl_list_for_each(tc, &clients, link) {
|
||||||
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
|
tc->master_width_per = new_master_width_per;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grabc->master_height_per = new_master_height_per;
|
||||||
|
grabc->slave_height_per = new_slave_height_per;
|
||||||
|
|
||||||
|
arrange(grabc->mon, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void motionnotify(unsigned int time, struct wlr_input_device *device, double dx,
|
void motionnotify(unsigned int time, struct wlr_input_device *device, double dx,
|
||||||
double dy, double dx_unaccel, double dy_unaccel) {
|
double dy, double dx_unaccel, double dy_unaccel) {
|
||||||
double sx = 0, sy = 0, sx_confined, sy_confined;
|
double sx = 0, sy = 0, sx_confined, sy_confined;
|
||||||
|
|
@ -3866,14 +4010,18 @@ void motionnotify(unsigned int time, struct wlr_input_device *device, double dx,
|
||||||
resize(grabc, grabc->float_geom, 1);
|
resize(grabc, grabc->float_geom, 1);
|
||||||
return;
|
return;
|
||||||
} else if (cursor_mode == CurResize) {
|
} else if (cursor_mode == CurResize) {
|
||||||
grabc->iscustomsize = 1;
|
if (grabc->isfloating) {
|
||||||
grabc->float_geom =
|
grabc->iscustomsize = 1;
|
||||||
(struct wlr_box){.x = grabc->geom.x,
|
grabc->float_geom = (struct wlr_box){
|
||||||
.y = grabc->geom.y,
|
.x = grabc->geom.x,
|
||||||
.width = (int)round(cursor->x) - grabc->geom.x,
|
.y = grabc->geom.y,
|
||||||
.height = (int)round(cursor->y) - grabc->geom.y};
|
.width = (int)round(cursor->x) - grabc->geom.x,
|
||||||
resize(grabc, grabc->float_geom, 1);
|
.height = (int)round(cursor->y) - grabc->geom.y};
|
||||||
return;
|
resize(grabc, grabc->float_geom, 1);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
resize_tile_client(grabc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there's no client surface under the cursor, set the cursor image
|
/* If there's no client surface under the cursor, set the cursor image
|
||||||
|
|
@ -4174,12 +4322,27 @@ void exchange_two_client(Client *c1, Client *c2) {
|
||||||
|
|
||||||
Monitor *tmp_mon = NULL;
|
Monitor *tmp_mon = NULL;
|
||||||
unsigned int tmp_tags;
|
unsigned int tmp_tags;
|
||||||
|
double master_height_per = 0.0f;
|
||||||
|
double master_width_per = 0.0f;
|
||||||
|
double slave_height_per = 0.0f;
|
||||||
|
|
||||||
if (c1 == NULL || c2 == NULL ||
|
if (c1 == NULL || c2 == NULL ||
|
||||||
(!exchange_cross_monitor && c1->mon != c2->mon)) {
|
(!exchange_cross_monitor && c1->mon != c2->mon)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
master_height_per = c1->master_height_per;
|
||||||
|
master_width_per = c1->master_width_per;
|
||||||
|
slave_height_per = c1->slave_height_per;
|
||||||
|
|
||||||
|
c1->master_height_per = c2->master_height_per;
|
||||||
|
c1->master_width_per = c2->master_width_per;
|
||||||
|
c1->slave_height_per = c2->slave_height_per;
|
||||||
|
|
||||||
|
c2->master_height_per = master_height_per;
|
||||||
|
c2->master_width_per = master_width_per;
|
||||||
|
c2->slave_height_per = slave_height_per;
|
||||||
|
|
||||||
struct wl_list *tmp1_prev = c1->link.prev;
|
struct wl_list *tmp1_prev = c1->link.prev;
|
||||||
struct wl_list *tmp2_prev = c2->link.prev;
|
struct wl_list *tmp2_prev = c2->link.prev;
|
||||||
struct wl_list *tmp1_next = c1->link.next;
|
struct wl_list *tmp1_next = c1->link.next;
|
||||||
|
|
@ -4403,6 +4566,10 @@ setfloating(Client *c, int floating) {
|
||||||
layers[c->isfloating ? LyrTop : LyrTile]);
|
layers[c->isfloating ? LyrTop : LyrTile]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!c->isfloating) {
|
||||||
|
set_size_per(c->mon, c);
|
||||||
|
}
|
||||||
|
|
||||||
arrange(c->mon, false);
|
arrange(c->mon, false);
|
||||||
setborder_color(c);
|
setborder_color(c);
|
||||||
printstatus();
|
printstatus();
|
||||||
|
|
@ -4447,12 +4614,15 @@ void setmaxmizescreen(Client *c, int maxmizescreen) {
|
||||||
c->ismaxmizescreen = 0;
|
c->ismaxmizescreen = 0;
|
||||||
if (c->isfloating)
|
if (c->isfloating)
|
||||||
setfloating(c, 1);
|
setfloating(c, 1);
|
||||||
arrange(c->mon, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile
|
wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile
|
||||||
: c->isfloating ? LyrTop
|
: c->isfloating ? LyrTop
|
||||||
: LyrTile]);
|
: LyrTile]);
|
||||||
|
if (!c->ismaxmizescreen) {
|
||||||
|
set_size_per(c->mon, c);
|
||||||
|
}
|
||||||
|
arrange(c->mon, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setfakefullscreen(Client *c, int fakefullscreen) {
|
void setfakefullscreen(Client *c, int fakefullscreen) {
|
||||||
|
|
@ -4508,6 +4678,10 @@ void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带
|
||||||
layers[fullscreen || c->isfloating ? LyrTop : LyrTile]);
|
layers[fullscreen || c->isfloating ? LyrTop : LyrTile]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!c->isfullscreen) {
|
||||||
|
set_size_per(c->mon, c);
|
||||||
|
}
|
||||||
|
|
||||||
arrange(c->mon, false);
|
arrange(c->mon, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue