diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 61c2468..a7a9746 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -378,6 +378,195 @@ void scroller(Monitor *m) { free(tempClients); // 最后释放内存 } +void horizontal_dual_scroll_adjust_fullandmax(Client *c, + struct wlr_box *target_geom) { + Monitor *m = c->mon; + unsigned int cur_gappih = enablegaps ? m->gappih : 0; + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + unsigned int cur_gappov = enablegaps ? m->gappov : 0; + + cur_gappih = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih; + cur_gappoh = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh; + cur_gappov = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov; + + if (c->isfullscreen) { + target_geom->height = m->m.height; + target_geom->width = m->m.width; + target_geom->y = m->m.y; + return; + } + + if (c->ismaximizescreen) { + target_geom->height = m->w.height - 2 * cur_gappov; + target_geom->width = m->w.width - 2 * cur_gappoh; + target_geom->y = m->w.y + cur_gappov; + return; + } + + target_geom->height = m->w.height - 2 * cur_gappov; + target_geom->y = m->w.y + (m->w.height - target_geom->height) / 2; +} + +// 滚动布局 +void dual_scroller(Monitor *m) { + unsigned int i, n, j; + float single_proportion = 1.0; + + Client *c = NULL, *root_client = NULL; + Client **tempClients = NULL; // 初始化为 NULL + struct wlr_box target_geom; + int focus_client_index = 0; + bool need_scroller = false; + unsigned int cur_gappih = enablegaps ? m->gappih : 0; + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + unsigned int cur_gappov = enablegaps ? m->gappov : 0; + + cur_gappih = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih; + cur_gappoh = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh; + cur_gappov = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov; + + unsigned int max_client_width = + m->w.width - 2 * scroller_structs - cur_gappih; + + n = m->visible_scroll_tiling_clients; + + if (n == 0) { + return; // 没有需要处理的客户端,直接返回 + } + + // 动态分配内存 + tempClients = malloc(n * sizeof(Client *)); + if (!tempClients) { + // 处理内存分配失败的情况 + return; + } + + // 第二次遍历,填充 tempClients + j = 0; + wl_list_for_each(c, &clients, link) { + if (VISIBLEON(c, m) && ISSCROLLTILED(c)) { + tempClients[j] = c; + j++; + } + } + + if (n == 1 && !scroller_ignore_proportion_single && + !tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) { + c = tempClients[0]; + + single_proportion = c->scroller_proportion_single > 0.0f + ? c->scroller_proportion_single + : scroller_default_proportion_single; + + target_geom.height = m->w.height - 2 * cur_gappov; + target_geom.width = (m->w.width - 2 * cur_gappoh) * single_proportion; + target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; + target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; + resize(c, target_geom, 0); + free(tempClients); // 释放内存 + return; + } + + if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating) { + root_client = m->sel; + } else if (m->prevsel && ISSCROLLTILED(m->prevsel) && + VISIBLEON(m->prevsel, m) && !client_is_unmanaged(m->prevsel)) { + root_client = m->prevsel; + } else { + root_client = center_tiled_select(m); + } + + if (!root_client) { + free(tempClients); // 释放内存 + return; + } + + for (i = 0; i < n; i++) { + c = tempClients[i]; + if (root_client == c) { + if (!c->is_pending_open_animation && + c->geom.x >= m->w.x + scroller_structs && + c->geom.x + c->geom.width <= + m->w.x + m->w.width - scroller_structs) { + need_scroller = false; + } else { + need_scroller = true; + } + focus_client_index = i; + break; + } + } + + if (n == 1 && scroller_ignore_proportion_single) { + need_scroller = true; + } + + 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; + horizontal_scroll_adjust_fullandmax(tempClients[focus_client_index], + &target_geom); + if (tempClients[focus_client_index]->isfullscreen) { + target_geom.x = m->m.x; + resize(tempClients[focus_client_index], target_geom, 0); + } else if (tempClients[focus_client_index]->ismaximizescreen) { + target_geom.x = m->w.x + cur_gappoh; + resize(tempClients[focus_client_index], target_geom, 0); + } else if (need_scroller) { + if (scroller_focus_center || + ((!m->prevsel || + (ISSCROLLTILED(m->prevsel) && + (m->prevsel->scroller_proportion * max_client_width) + + (root_client->scroller_proportion * max_client_width) > + m->w.width - 2 * scroller_structs - cur_gappih)) && + scroller_prefer_center)) { + target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; + } else { + target_geom.x = root_client->geom.x > m->w.x + (m->w.width) / 2 + ? m->w.x + (m->w.width - + root_client->scroller_proportion * + max_client_width - + scroller_structs) + : m->w.x + scroller_structs; + } + resize(tempClients[focus_client_index], target_geom, 0); + } else { + target_geom.x = c->geom.x; + resize(tempClients[focus_client_index], target_geom, 0); + } + + for (i = 1; i <= focus_client_index; i++) { + c = tempClients[focus_client_index - i]; + target_geom.width = max_client_width * c->scroller_proportion; + horizontal_scroll_adjust_fullandmax(c, &target_geom); + target_geom.x = tempClients[focus_client_index - i + 1]->geom.x - + cur_gappih - target_geom.width; + + resize(c, target_geom, 0); + } + + for (i = 1; i < n - focus_client_index; i++) { + c = tempClients[focus_client_index + i]; + target_geom.width = max_client_width * c->scroller_proportion; + horizontal_scroll_adjust_fullandmax(c, &target_geom); + target_geom.x = tempClients[focus_client_index + i - 1]->geom.x + + cur_gappih + + tempClients[focus_client_index + i - 1]->geom.width; + resize(c, target_geom, 0); + } + + free(tempClients); // 最后释放内存 +} + void center_tile(Monitor *m) { unsigned int i, n = 0, h, r, ie = enablegaps, mw, mx, my, oty, ety, tw; Client *c = NULL; @@ -782,17 +971,6 @@ void right_tile(Monitor *m) { } } -void dual_scroller(Monitor *m) { - Client *c = NULL; - wl_list_for_each(c, &clients, link) { - c->geom.x = m->w.x; - c->geom.y = m->w.y; - c->geom.width = m->w.width; - c->geom.height = m->w.height; - resize(c, c->geom, 0); - } -} - void // 17 monocle(Monitor *m) { Client *c = NULL;