mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-14 05:34:21 -04:00
fix: fix the scrolling stack error
This commit is contained in:
parent
535f41e76b
commit
810933cbf8
7 changed files with 193 additions and 225 deletions
|
|
@ -205,7 +205,6 @@ typedef struct {
|
|||
int32_t scroller_ignore_proportion_single;
|
||||
int32_t scroller_focus_center;
|
||||
int32_t scroller_prefer_center;
|
||||
int32_t stacker_loop;
|
||||
int32_t edge_scroller_pointer_focus;
|
||||
int32_t focus_cross_monitor;
|
||||
int32_t exchange_cross_monitor;
|
||||
|
|
@ -1081,26 +1080,11 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
|
|||
} else if (strcmp(func_name, "toggle_monitor") == 0) {
|
||||
func = toggle_monitor;
|
||||
(*arg).v = strdup(arg_value);
|
||||
} else if (strcmp(func_name, "expand_client_left") == 0) {
|
||||
func = expand_client_left;
|
||||
if (arg_value && *arg_value) {
|
||||
(*arg).f = atof(arg_value);
|
||||
} else {
|
||||
(*arg).f = 0.05;
|
||||
}
|
||||
} else if (strcmp(func_name, "collapse_client_right") == 0) {
|
||||
func = collapse_client_right;
|
||||
if (arg_value && *arg_value) {
|
||||
(*arg).f = atof(arg_value);
|
||||
} else {
|
||||
(*arg).f = -0.05;
|
||||
}
|
||||
} else if (strcmp(func_name, "stack_with_left") == 0) {
|
||||
func = stack_with_left;
|
||||
} else if (strcmp(func_name, "unstack") == 0) {
|
||||
func = unstack;
|
||||
} else if (strcmp(func_name, "revert_size") == 0) {
|
||||
func = revert_size;
|
||||
} else if (strcmp(func_name, "scroller_stack") == 0) {
|
||||
func = scroller_stack;
|
||||
(*arg).i = parse_direction(arg_value);
|
||||
} else if (strcmp(func_name, "scroller_unstack") == 0) {
|
||||
func = scroller_unstack;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1242,8 +1226,6 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
config->scroller_focus_center = atoi(value);
|
||||
} else if (strcmp(key, "scroller_prefer_center") == 0) {
|
||||
config->scroller_prefer_center = atoi(value);
|
||||
} else if (strcmp(key, "stacker_loop") == 0) {
|
||||
config->stacker_loop = atoi(value);
|
||||
} else if (strcmp(key, "edge_scroller_pointer_focus") == 0) {
|
||||
config->edge_scroller_pointer_focus = atoi(value);
|
||||
} else if (strcmp(key, "focus_cross_monitor") == 0) {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ float scroller_default_proportion_single = 1.0;
|
|||
int32_t scroller_ignore_proportion_single = 0;
|
||||
int32_t scroller_focus_center = 0;
|
||||
int32_t scroller_prefer_center = 0;
|
||||
int32_t stacker_loop = 1;
|
||||
int32_t focus_cross_monitor = 0;
|
||||
int32_t focus_cross_tag = 0;
|
||||
int32_t exchange_cross_monitor = 0;
|
||||
|
|
|
|||
|
|
@ -69,8 +69,5 @@ int32_t setoption(const Arg *arg);
|
|||
int32_t disable_monitor(const Arg *arg);
|
||||
int32_t enable_monitor(const Arg *arg);
|
||||
int32_t toggle_monitor(const Arg *arg);
|
||||
int32_t expand_client_left(const Arg *arg);
|
||||
int32_t collapse_client_right(const Arg *arg);
|
||||
int32_t stack_with_left(const Arg *arg);
|
||||
int32_t unstack(const Arg *arg);
|
||||
int32_t revert_size(const Arg *arg);
|
||||
int32_t scroller_stack(const Arg *arg);
|
||||
int32_t scroller_unstack(const Arg *arg);
|
||||
|
|
@ -107,7 +107,7 @@ int32_t exchange_client(const Arg *arg) {
|
|||
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
|
||||
return 0;
|
||||
|
||||
exchange_two_client(c, direction_select(arg));
|
||||
exchange_two_client(c, direction_select(arg), false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ int32_t exchange_stack_client(const Arg *arg) {
|
|||
tc = get_next_stack_client(c, true);
|
||||
}
|
||||
if (tc)
|
||||
exchange_two_client(c, tc);
|
||||
exchange_two_client(c, tc, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -427,7 +427,8 @@ int32_t resizewin(const Arg *arg) {
|
|||
|
||||
if (ISTILED(c)) {
|
||||
Client *target_client = c;
|
||||
if (is_scroller_layout(c->mon) && (c->prev_in_stack || c->next_in_stack)) {
|
||||
if (is_scroller_layout(c->mon) &&
|
||||
(c->prev_in_stack || c->next_in_stack)) {
|
||||
while (target_client->prev_in_stack) {
|
||||
target_client = target_client->prev_in_stack;
|
||||
}
|
||||
|
|
@ -1592,143 +1593,69 @@ int32_t toggle_monitor(const Arg *arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t expand_client_left(const Arg *arg) {
|
||||
int32_t scroller_stack(const Arg *arg) {
|
||||
Client *c = selmon->sel;
|
||||
if (selmon && c && is_scroller_layout(selmon)) {
|
||||
c->scroller_proportion += arg->f;
|
||||
if (c->scroller_proportion > 1.0)
|
||||
c->scroller_proportion = 1.0;
|
||||
arrange(selmon, false, false);
|
||||
} else {
|
||||
setmfact(arg);
|
||||
if (!c || c->isfloating || !is_scroller_layout(selmon))
|
||||
return 0;
|
||||
|
||||
Client *left_c = find_client_by_direction(c, arg, false, true);
|
||||
|
||||
if (!left_c)
|
||||
return 0;
|
||||
|
||||
if (c->isfullscreen) {
|
||||
setfullscreen(c, 0);
|
||||
}
|
||||
|
||||
if (c->ismaximizescreen) {
|
||||
setmaximizescreen(c, 0);
|
||||
}
|
||||
|
||||
exit_scroller_stack(c);
|
||||
|
||||
// Find the tail of left_c's stack
|
||||
Client *stack_tail = left_c;
|
||||
while (stack_tail->next_in_stack) {
|
||||
stack_tail = stack_tail->next_in_stack;
|
||||
}
|
||||
|
||||
// Add c to the stack
|
||||
stack_tail->next_in_stack = c;
|
||||
c->prev_in_stack = stack_tail;
|
||||
c->next_in_stack = NULL;
|
||||
|
||||
arrange(selmon, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t collapse_client_right(const Arg *arg) {
|
||||
int32_t scroller_unstack(const Arg *arg) {
|
||||
Client *c = selmon->sel;
|
||||
if (selmon && c && is_scroller_layout(selmon)) {
|
||||
c->scroller_proportion += arg->f;
|
||||
if (c->scroller_proportion < 0.1)
|
||||
c->scroller_proportion = 0.1;
|
||||
arrange(selmon, false, false);
|
||||
} else {
|
||||
setmfact(arg);
|
||||
if (!c || !c->prev_in_stack) {
|
||||
// Not in a stack or is the head of a stack, do nothing.
|
||||
return 0;
|
||||
}
|
||||
|
||||
Client *scroller_stack_head = c;
|
||||
while (scroller_stack_head->prev_in_stack) {
|
||||
scroller_stack_head = scroller_stack_head->prev_in_stack;
|
||||
}
|
||||
|
||||
// Remove c from its current stack
|
||||
if (c->prev_in_stack) {
|
||||
c->prev_in_stack->next_in_stack = c->next_in_stack;
|
||||
}
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = c->prev_in_stack;
|
||||
}
|
||||
|
||||
c->next_in_stack = NULL;
|
||||
c->prev_in_stack = NULL;
|
||||
|
||||
// Insert c after the stack it was in
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_insert(&scroller_stack_head->link, &c->link);
|
||||
|
||||
focusclient(c, 1);
|
||||
arrange(selmon, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t stack_with_left(const Arg *arg) {
|
||||
Client *c = selmon->sel;
|
||||
if (!c || c->isfloating || !is_scroller_layout(selmon))
|
||||
return 0;
|
||||
|
||||
if (!config.stacker_loop) {
|
||||
Client *first_tiled = NULL;
|
||||
Client *iter_c = NULL;
|
||||
wl_list_for_each(iter_c, &clients, link) {
|
||||
if (ISTILED(iter_c) && VISIBLEON(iter_c, selmon)) {
|
||||
first_tiled = iter_c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c == first_tiled) {
|
||||
return 0; // It's the first client and loop is disabled, so do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
Client *left_c = get_next_stack_client(c, true);
|
||||
if (!left_c)
|
||||
return 0;
|
||||
|
||||
// If c is already in a stack, remove it.
|
||||
if (c->prev_in_stack) {
|
||||
c->prev_in_stack->next_in_stack = c->next_in_stack;
|
||||
}
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = c->prev_in_stack;
|
||||
}
|
||||
// If c was a stack head, its next client becomes the new head.
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = NULL;
|
||||
}
|
||||
|
||||
|
||||
// Find the tail of left_c's stack
|
||||
Client *stack_tail = left_c;
|
||||
while (stack_tail->next_in_stack) {
|
||||
stack_tail = stack_tail->next_in_stack;
|
||||
}
|
||||
|
||||
// Add c to the stack
|
||||
stack_tail->next_in_stack = c;
|
||||
c->prev_in_stack = stack_tail;
|
||||
c->next_in_stack = NULL;
|
||||
|
||||
arrange(selmon, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t unstack(const Arg *arg) {
|
||||
Client *c = selmon->sel;
|
||||
if (!c || !c->prev_in_stack) {
|
||||
// Not in a stack or is the head of a stack, do nothing.
|
||||
return 0;
|
||||
}
|
||||
|
||||
Client *stack_head = c;
|
||||
while(stack_head->prev_in_stack) {
|
||||
stack_head = stack_head->prev_in_stack;
|
||||
}
|
||||
|
||||
// Remove c from its current stack
|
||||
if (c->prev_in_stack) {
|
||||
c->prev_in_stack->next_in_stack = c->next_in_stack;
|
||||
}
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = c->prev_in_stack;
|
||||
}
|
||||
|
||||
c->next_in_stack = NULL;
|
||||
c->prev_in_stack = NULL;
|
||||
|
||||
// Insert c after the stack it was in
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_insert(&stack_head->link, &c->link);
|
||||
|
||||
focusclient(c, 1);
|
||||
arrange(selmon, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t revert_size(const Arg *arg) {
|
||||
Client *c = selmon->sel;
|
||||
if (!c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ensure the client is not floating and its size is managed by the layout
|
||||
if (c->isfloating) {
|
||||
setfloating(c, false);
|
||||
}
|
||||
c->iscustomsize = 0; // Let the layout manage its size
|
||||
|
||||
// Explicitly remove the client from any stack it might be in
|
||||
if (c->prev_in_stack) {
|
||||
c->prev_in_stack->next_in_stack = c->next_in_stack;
|
||||
}
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = c->prev_in_stack;
|
||||
}
|
||||
c->prev_in_stack = NULL;
|
||||
c->next_in_stack = NULL;
|
||||
|
||||
// Explicitly reset float_geom to ensure arrange recalculates geometry
|
||||
c->float_geom = (struct wlr_box){0};
|
||||
|
||||
// The arrange function will now correctly size and position the window
|
||||
// within the scroller layout, giving it full vertical size and preventing overlaps.
|
||||
arrange(selmon, false, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -447,4 +447,12 @@ bool client_only_in_one_tag(Client *c) {
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Client *get_scroll_stack_head(Client *c) {
|
||||
Client *scroller_stack_head = c;
|
||||
while (scroller_stack_head->prev_in_stack) {
|
||||
scroller_stack_head = scroller_stack_head->prev_in_stack;
|
||||
}
|
||||
return scroller_stack_head;
|
||||
}
|
||||
|
|
@ -212,31 +212,32 @@ void horizontal_scroll_adjust_fullandmax(Client *c,
|
|||
target_geom->y = m->w.y + (m->w.height - target_geom->height) / 2;
|
||||
}
|
||||
|
||||
void arrange_stack(Client *stack_head, struct wlr_box geometry, int32_t gappiv) {
|
||||
int32_t stack_size = 0;
|
||||
Client *iter = stack_head;
|
||||
while (iter) {
|
||||
stack_size++;
|
||||
iter = iter->next_in_stack;
|
||||
}
|
||||
void arrange_stack(Client *scroller_stack_head, struct wlr_box geometry,
|
||||
int32_t gappiv) {
|
||||
int32_t stack_size = 0;
|
||||
Client *iter = scroller_stack_head;
|
||||
while (iter) {
|
||||
stack_size++;
|
||||
iter = iter->next_in_stack;
|
||||
}
|
||||
|
||||
if (stack_size == 0) return;
|
||||
if (stack_size == 0)
|
||||
return;
|
||||
|
||||
int32_t client_height = (geometry.height - (stack_size - 1) * gappiv) / stack_size;
|
||||
int32_t current_y = geometry.y;
|
||||
int32_t client_height =
|
||||
(geometry.height - (stack_size - 1) * gappiv) / stack_size;
|
||||
int32_t current_y = geometry.y;
|
||||
|
||||
iter = stack_head;
|
||||
while (iter) {
|
||||
struct wlr_box client_geom = {
|
||||
.x = geometry.x,
|
||||
.y = current_y,
|
||||
.width = geometry.width,
|
||||
.height = client_height
|
||||
};
|
||||
resize(iter, client_geom, 0);
|
||||
current_y += client_height + gappiv;
|
||||
iter = iter->next_in_stack;
|
||||
}
|
||||
iter = scroller_stack_head;
|
||||
while (iter) {
|
||||
struct wlr_box client_geom = {.x = geometry.x,
|
||||
.y = current_y,
|
||||
.width = geometry.width,
|
||||
.height = client_height};
|
||||
resize(iter, client_geom, 0);
|
||||
current_y += client_height + gappiv;
|
||||
iter = iter->next_in_stack;
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动布局
|
||||
|
|
@ -252,7 +253,7 @@ void scroller(Monitor *m) {
|
|||
int32_t cur_gappih = enablegaps ? m->gappih : 0;
|
||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
int32_t cur_gappiv = enablegaps ? m->gappiv : 0;
|
||||
int32_t cur_gappiv = enablegaps ? m->gappiv : 0;
|
||||
|
||||
cur_gappih =
|
||||
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih;
|
||||
|
|
@ -311,13 +312,12 @@ void scroller(Monitor *m) {
|
|||
root_client = center_tiled_select(m);
|
||||
}
|
||||
|
||||
// root_client might be in a stack, find the stack head
|
||||
if (root_client) {
|
||||
while(root_client->prev_in_stack) {
|
||||
root_client = root_client->prev_in_stack;
|
||||
}
|
||||
}
|
||||
|
||||
// root_client might be in a stack, find the stack head
|
||||
if (root_client) {
|
||||
while (root_client->prev_in_stack) {
|
||||
root_client = root_client->prev_in_stack;
|
||||
}
|
||||
}
|
||||
|
||||
if (!root_client) {
|
||||
free(tempClients); // 释放内存
|
||||
|
|
|
|||
117
src/mango.c
117
src/mango.c
|
|
@ -627,7 +627,7 @@ static void motionrelative(struct wl_listener *listener, void *data);
|
|||
static void reset_foreign_tolevel(Client *c);
|
||||
static void remove_foreign_topleve(Client *c);
|
||||
static void add_foreign_topleve(Client *c);
|
||||
static void exchange_two_client(Client *c1, Client *c2);
|
||||
static void exchange_two_client(Client *c1, Client *c2, bool samemon);
|
||||
static void outputmgrapply(struct wl_listener *listener, void *data);
|
||||
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config,
|
||||
int32_t test);
|
||||
|
|
@ -764,6 +764,9 @@ static void init_client_properties(Client *c);
|
|||
static float *get_border_color(Client *c);
|
||||
static void clear_fullscreen_and_maximized_state(Monitor *m);
|
||||
static void request_fresh_all_monitors(void);
|
||||
static Client *find_client_by_direction(Client *tc, const Arg *arg,
|
||||
bool findfloating, bool ignore_align);
|
||||
static void exit_scroller_stack(Client *c);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
#include "dispatch/bind_declare.h"
|
||||
|
|
@ -1840,7 +1843,7 @@ void place_drag_tile_client(Client *c) {
|
|||
closest_client->link.prev->next = &c->link;
|
||||
closest_client->link.prev = &c->link;
|
||||
} else if (closest_client) {
|
||||
exchange_two_client(c, closest_client);
|
||||
exchange_two_client(c, closest_client, false);
|
||||
}
|
||||
setfloating(c, 0);
|
||||
}
|
||||
|
|
@ -3640,25 +3643,6 @@ void keypressmod(struct wl_listener *listener, void *data) {
|
|||
void pending_kill_client(Client *c) {
|
||||
if (!c || c->iskilling)
|
||||
return;
|
||||
|
||||
// If the client is in a stack, remove it from the stack
|
||||
if (c->prev_in_stack || c->next_in_stack) {
|
||||
if (c->prev_in_stack) {
|
||||
c->prev_in_stack->next_in_stack = c->next_in_stack;
|
||||
}
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = c->prev_in_stack;
|
||||
if (!c->prev_in_stack) { // c was the head of the stack
|
||||
// The next client becomes the new head, so we need to ensure it's treated as such.
|
||||
// This is implicitly handled by setting its prev_in_stack to NULL.
|
||||
}
|
||||
}
|
||||
c->prev_in_stack = NULL;
|
||||
c->next_in_stack = NULL;
|
||||
arrange(c->mon, false, false);
|
||||
}
|
||||
|
||||
c->iskilling = 1;
|
||||
client_send_close(c);
|
||||
}
|
||||
|
||||
|
|
@ -3845,7 +3829,7 @@ mapnotify(struct wl_listener *listener, void *data) {
|
|||
|
||||
if (selmon->sel && ISSCROLLTILED(selmon->sel) &&
|
||||
VISIBLEON(selmon->sel, selmon)) {
|
||||
at_client = selmon->sel;
|
||||
at_client = get_scroll_stack_head(selmon->sel);
|
||||
} else {
|
||||
at_client = center_tiled_select(selmon);
|
||||
}
|
||||
|
|
@ -4368,7 +4352,7 @@ void setborder_color(Client *c) {
|
|||
client_set_border_color(c, border_color);
|
||||
}
|
||||
|
||||
void exchange_two_client(Client *c1, Client *c2) {
|
||||
void exchange_two_client(Client *c1, Client *c2, bool samemon) {
|
||||
|
||||
Monitor *tmp_mon = NULL;
|
||||
uint32_t tmp_tags;
|
||||
|
|
@ -4381,6 +4365,10 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (samemon && c1->mon != c2->mon)
|
||||
return;
|
||||
|
||||
// 交换布局参数
|
||||
master_inner_per = c1->master_inner_per;
|
||||
master_mfact_per = c1->master_mfact_per;
|
||||
stack_inner_per = c1->stack_inner_per;
|
||||
|
|
@ -4393,17 +4381,46 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
c2->master_mfact_per = master_mfact_per;
|
||||
c2->stack_inner_per = stack_inner_per;
|
||||
|
||||
// 交换栈链表连接
|
||||
Client *tmp1_next_in_stack = c1->next_in_stack;
|
||||
Client *tmp1_prev_in_stack = c1->prev_in_stack;
|
||||
Client *tmp2_next_in_stack = c2->next_in_stack;
|
||||
Client *tmp2_prev_in_stack = c2->prev_in_stack;
|
||||
|
||||
// 处理相邻节点的情况
|
||||
if (c1->next_in_stack == c2) {
|
||||
c1->next_in_stack = tmp2_next_in_stack;
|
||||
c2->next_in_stack = c1;
|
||||
c1->prev_in_stack = c2;
|
||||
c2->prev_in_stack = tmp1_prev_in_stack;
|
||||
if (tmp1_prev_in_stack)
|
||||
tmp1_prev_in_stack->next_in_stack = c2;
|
||||
if (tmp2_next_in_stack)
|
||||
tmp2_next_in_stack->prev_in_stack = c1;
|
||||
} else if (c2->next_in_stack == c1) {
|
||||
c2->next_in_stack = tmp1_next_in_stack;
|
||||
c1->next_in_stack = c2;
|
||||
c2->prev_in_stack = c1;
|
||||
c1->prev_in_stack = tmp2_prev_in_stack;
|
||||
if (tmp2_prev_in_stack)
|
||||
tmp2_prev_in_stack->next_in_stack = c1;
|
||||
if (tmp1_next_in_stack)
|
||||
tmp1_next_in_stack->prev_in_stack = c2;
|
||||
} else if (c1->prev_in_stack || c2->prev_in_stack) {
|
||||
Client *c1head = get_scroll_stack_head(c1);
|
||||
Client *c2head = get_scroll_stack_head(c2);
|
||||
exchange_two_client(c1head, c2head, true);
|
||||
focusclient(c1, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// 交换全局链表连接
|
||||
struct wl_list *tmp1_prev = c1->link.prev;
|
||||
struct wl_list *tmp2_prev = c2->link.prev;
|
||||
struct wl_list *tmp1_next = c1->link.next;
|
||||
struct wl_list *tmp2_next = c2->link.next;
|
||||
|
||||
// wl_list
|
||||
// 是双向链表,其中clients是头部节点,它的下一个节点是第一个客户端的链表节点
|
||||
// 最后一个客户端的链表节点的下一个节点也指向clients,但clients本身不是客户端的链表节点
|
||||
// 客户端遍历从clients的下一个节点开始,到检测到客户端节点的下一个是clients结束
|
||||
|
||||
// 当c1和c2为相邻节点时
|
||||
// 处理相邻节点的情况
|
||||
if (c1->link.next == &c2->link) {
|
||||
c1->link.next = c2->link.next;
|
||||
c1->link.prev = &c2->link;
|
||||
|
|
@ -4430,6 +4447,7 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
tmp2_next->prev = &c1->link;
|
||||
}
|
||||
|
||||
// 处理跨监视器交换
|
||||
if (exchange_cross_monitor) {
|
||||
tmp_mon = c2->mon;
|
||||
tmp_tags = c2->tags;
|
||||
|
|
@ -4440,7 +4458,6 @@ void exchange_two_client(Client *c1, Client *c2) {
|
|||
focusclient(c1, 0);
|
||||
} else {
|
||||
arrange(c1->mon, false, false);
|
||||
focusclient(c1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4631,6 +4648,19 @@ void reset_maximizescreen_size(Client *c) {
|
|||
resize(c, c->geom, 0);
|
||||
}
|
||||
|
||||
void exit_scroller_stack(Client *c) {
|
||||
// If c is already in a stack, remove it.
|
||||
if (c->prev_in_stack) {
|
||||
c->prev_in_stack->next_in_stack = c->next_in_stack;
|
||||
}
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = c->prev_in_stack;
|
||||
}
|
||||
|
||||
c->prev_in_stack = NULL;
|
||||
c->next_in_stack = NULL;
|
||||
}
|
||||
|
||||
void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
||||
struct wlr_box maximizescreen_box;
|
||||
if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling)
|
||||
|
|
@ -4646,6 +4676,8 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
|||
if (c->isfullscreen)
|
||||
setfullscreen(c, 0);
|
||||
|
||||
exit_scroller_stack(c);
|
||||
|
||||
if (c->isfloating)
|
||||
c->float_geom = c->geom;
|
||||
|
||||
|
|
@ -4706,6 +4738,8 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
|
|||
if (c->ismaximizescreen)
|
||||
setmaximizescreen(c, 0);
|
||||
|
||||
exit_scroller_stack(c);
|
||||
|
||||
if (c->isfloating)
|
||||
c->float_geom = c->geom;
|
||||
|
||||
|
|
@ -5426,12 +5460,27 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
*/
|
||||
Client *c = wl_container_of(listener, c, unmap);
|
||||
Monitor *m = NULL;
|
||||
Client *nextfocus = NULL;
|
||||
Client *next_in_stack = c->next_in_stack;
|
||||
Client *prev_in_stack = c->prev_in_stack;
|
||||
c->iskilling = 1;
|
||||
|
||||
if (animations && !c->is_clip_to_hide && !c->isminimized &&
|
||||
(!c->mon || VISIBLEON(c, c->mon)))
|
||||
init_fadeout_client(c);
|
||||
|
||||
// If the client is in a stack, remove it from the stack
|
||||
if (c->prev_in_stack || c->next_in_stack) {
|
||||
if (c->prev_in_stack) {
|
||||
c->prev_in_stack->next_in_stack = c->next_in_stack;
|
||||
}
|
||||
if (c->next_in_stack) {
|
||||
c->next_in_stack->prev_in_stack = c->prev_in_stack;
|
||||
}
|
||||
c->prev_in_stack = NULL;
|
||||
c->next_in_stack = NULL;
|
||||
}
|
||||
|
||||
if (c->swallowedby) {
|
||||
c->swallowedby->mon = c->mon;
|
||||
swallow(c->swallowedby, c);
|
||||
|
|
@ -5455,7 +5504,13 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
if (c->mon && c->mon == selmon) {
|
||||
Client *nextfocus = focustop(selmon);
|
||||
if (next_in_stack) {
|
||||
nextfocus = next_in_stack;
|
||||
} else if (prev_in_stack) {
|
||||
nextfocus = prev_in_stack;
|
||||
} else {
|
||||
nextfocus = focustop(selmon);
|
||||
}
|
||||
|
||||
if (nextfocus) {
|
||||
focusclient(nextfocus, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue