This commit is contained in:
Ernesto Cruz 2026-06-19 17:54:18 +00:00 committed by GitHub
commit 95790c6822
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 80 additions and 6 deletions

View file

@ -1026,6 +1026,9 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
} else if (strcmp(func_name, "exchange_client") == 0) {
func = exchange_client;
(*arg).i = parse_direction(arg_value);
} else if (strcmp(func_name, "move_client") == 0) {
func = move_client;
(*arg).i = parse_direction(arg_value);
} else if (strcmp(func_name, "exchange_stack_client") == 0) {
func = exchange_stack_client;
(*arg).i = parse_circle_direction(arg_value);

View file

@ -32,6 +32,7 @@ int32_t setmfact(const Arg *arg);
int32_t quit(const Arg *arg);
int32_t moveresize(const Arg *arg);
int32_t exchange_client(const Arg *arg);
int32_t move_client(const Arg *arg);
int32_t exchange_stack_client(const Arg *arg);
int32_t killclient(const Arg *arg);
int32_t toggleglobal(const Arg *arg);

View file

@ -111,6 +111,33 @@ int32_t exchange_client(const Arg *arg) {
return 0;
}
int32_t move_client(const Arg *arg) {
if (!selmon)
return 0;
Client *c = arg->tc ? arg->tc : selmon->sel;
if (!c || c->isfloating)
return 0;
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
return 0;
Client *tc = direction_select(arg);
tc = get_focused_stack_client(tc, arg->tc);
if (!tc)
return 0;
if (c->mon && c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == DWINDLE) {
uint32_t tag = c->mon->pertag->curtag;
dwindle_move_client(&c->mon->pertag->dwindle_root[tag], c, tc,
config.dwindle_split_ratio, arg->i, false);
arrange(c->mon, false, false);
} else {
move_two_client(c, tc, arg->i);
}
return 0;
}
int32_t exchange_stack_client(const Arg *arg) {
if (!selmon)
return 0;

View file

@ -287,15 +287,33 @@ static void dwindle_assign(DwindleNode *node, int32_t ax, int32_t ay,
}
static void dwindle_move_client(DwindleNode **root, Client *c, Client *target,
float ratio, int32_t dir) {
float ratio, int32_t dir, bool lock) {
if (!c || !target || c == target)
return;
if (!dwindle_find_leaf(*root, c) || !dwindle_find_leaf(*root, target))
DwindleNode *c_leaf = dwindle_find_leaf(*root, c);
DwindleNode *t_leaf = dwindle_find_leaf(*root, target);
if (!c_leaf || !t_leaf)
return;
dwindle_remove(root, c);
bool as_first = (dir == UP || dir == LEFT);
if (c_leaf->parent && c_leaf->parent == t_leaf->parent) {
DwindleNode *p = c_leaf->parent;
DwindleNode *tmp = p->first;
p->first = p->second;
p->second = tmp;
return;
}
bool split_h = (dir == LEFT || dir == RIGHT);
dwindle_insert(root, c, target, ratio, as_first, split_h, true);
bool as_first;
if (dir == LEFT || dir == RIGHT) {
int cy = c->geom.y + c->geom.height / 2;
int ty = target->geom.y + target->geom.height / 2;
as_first = (cy < ty);
} else {
as_first = (dir == UP);
}
dwindle_remove(root, c);
dwindle_insert(root, c, target, ratio, as_first, split_h, lock);
}
static void dwindle_swap_clients(Client *c1, Client *c2) {

View file

@ -734,6 +734,7 @@ static void motionrelative(struct wl_listener *listener, void *data);
static void reset_foreign_tolevel(Client *c, Monitor *oldmon, Monitor *newmon);
static void add_foreign_topleve(Client *c);
static void exchange_two_client(Client *c1, Client *c2);
static void move_two_client(Client *c, Client *target, int32_t dir);
static void outputmgrapply(struct wl_listener *listener, void *data);
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config,
int32_t test);
@ -897,7 +898,7 @@ static void client_pending_minimized_state(Client *c, int32_t isminimized);
static void scroller_insert_stack(Client *c, Client *target_client,
bool insert_before);
static void dwindle_move_client(DwindleNode **root, Client *c, Client *target,
float ratio, int32_t dir);
float ratio, int32_t dir, bool lock);
static void dwindle_resize_client_step(Monitor *m, Client *c, int32_t dx,
int32_t dy);
static void dwindle_resize_client(Monitor *m, Client *c);
@ -5267,6 +5268,30 @@ void exchange_two_client(Client *c1, Client *c2) {
finish_exchange_arrange_and_focus(c1, c2, m1, m2);
}
static void move_two_client(Client *c, Client *target, int32_t dir) {
if (c == NULL || target == NULL || c == target ||
(!config.exchange_cross_monitor && c->mon != target->mon)) {
return;
}
Monitor *m = c->mon;
const Layout *layout = m->pertag->ltidxs[m->pertag->curtag];
if (layout->id == SCROLLER) {
exchange_two_scroller_clients(c, target);
return;
}
wl_list_remove(&c->link);
if (dir == UP || dir == LEFT) {
wl_list_insert(target->link.prev, &c->link);
} else {
wl_list_insert(&target->link, &c->link);
}
arrange(m, false, false);
}
void set_activation_env() {
if (!getenv("DBUS_SESSION_BUS_ADDRESS")) {
wlr_log(WLR_INFO, "Not updating dbus execution environment: "