diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 43e8badc..d0b19c1e 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -16,7 +16,7 @@ jobs: days-before-issue-stale: -1 # 手动标记后,14 天后关闭 days-before-issue-close: 7 - # 使用的标签(必须和你手动添加的标签一致) + # 使用的标签 stale-issue-label: "stale" # 自动关闭时自动加上的标签 close-issue-label: "automatic-closing" diff --git a/src/layout/arrange.h b/src/layout/arrange.h index 1ef89c3a..69d221d1 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -1,11 +1,31 @@ +void save_old_size_per(Monitor *m) { + Client *c = NULL; + + wl_list_for_each(c, &clients, link) { + if (VISIBLEON(c, m) && ISTILED(c)) { + c->old_master_inner_per = c->master_inner_per; + c->old_stack_inner_per = c->stack_inner_per; + } + } +} + void restore_size_per(Monitor *m, Client *c) { Client *fc = NULL; - double total_master_inner_per = 0; - double total_stack_inner_per = 0; if (!m || !c) return; + wl_list_for_each(fc, &clients, link) { + if (VISIBLEON(fc, m) && ISTILED(fc)) { + fc->old_ismaster = fc->ismaster; + } + } + + c->old_master_inner_per = c->master_inner_per; + c->old_stack_inner_per = c->stack_inner_per; + + pre_caculate_before_arrange(m, false, false, true); + const Layout *current_layout = m->pertag->ltidxs[m->pertag->curtag]; if (current_layout->id == SCROLLER || @@ -15,7 +35,7 @@ void restore_size_per(Monitor *m, Client *c) { return; } - if (current_layout->id == CENTER_TILE || c->ismaster) { + if (current_layout->id == CENTER_TILE) { wl_list_for_each(fc, &clients, link) { if (VISIBLEON(fc, m) && ISTILED(fc) && !c->ismaster) { set_size_per(m, fc); @@ -24,19 +44,28 @@ void restore_size_per(Monitor *m, Client *c) { return; } - wl_list_for_each(fc, &clients, link) { - if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) { - if (fc->ismaster) { - total_master_inner_per += fc->master_inner_per; - } else { - total_stack_inner_per += fc->stack_inner_per; - } - } + if (!c->ismaster && c->old_stack_inner_per < 1.0 && + c->stack_inner_per < 1.0) { + c->stack_inner_per = (1.0 - c->stack_inner_per) * + c->old_stack_inner_per / + (1.0 - c->old_stack_inner_per); } - if (!c->ismaster && total_stack_inner_per) { - c->stack_inner_per = total_stack_inner_per * c->stack_inner_per / - (1 - c->stack_inner_per); + if (c->ismaster && c->old_master_inner_per < 1.0 && + c->master_inner_per < 1.0) { + c->master_inner_per = (1.0 - c->master_inner_per) * + c->old_master_inner_per / + (1.0 - c->old_master_inner_per); + } + + wl_list_for_each(fc, &clients, link) { + if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c && !fc->ismaster && + fc->old_ismaster && fc->old_stack_inner_per < 1.0 && + fc->stack_inner_per < 1.0) { + fc->stack_inner_per = (1.0 - fc->stack_inner_per) * + fc->old_stack_inner_per / + (1.0 - fc->old_stack_inner_per); + } } } @@ -90,8 +119,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx, break; } - if (!begin_find_nextnext && VISIBLEON(tc, grabc->mon) && - ISTILED(tc)) { // 根据你的实际字段名调整 + if (!begin_find_nextnext && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) { next = tc; begin_find_nextnext = true; continue; @@ -107,8 +135,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx, break; } - if (!begin_find_prevprev && VISIBLEON(tc, grabc->mon) && - ISTILED(tc)) { // 根据你的实际字段名调整 + if (!begin_find_prevprev && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) { prev = tc; begin_find_prevprev = true; continue; @@ -276,8 +303,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx, for (node = grabc->link.next; node != &clients; node = node->next) { tc = wl_container_of(node, tc, link); - if (VISIBLEON(tc, grabc->mon) && - ISTILED(tc)) { // 根据你的实际字段名调整 + if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) { next = tc; break; } @@ -287,8 +313,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx, for (node = grabc->link.prev; node != &clients; node = node->prev) { tc = wl_container_of(node, tc, link); - if (VISIBLEON(tc, grabc->mon) && - ISTILED(tc)) { // 根据你的实际字段名调整 + if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) { prev = tc; break; } @@ -705,8 +730,8 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num, } } -void // 17 -arrange(Monitor *m, bool want_animation, bool from_view) { +void pre_caculate_before_arrange(Monitor *m, bool want_animation, + bool from_view, bool only_caculate) { Client *c = NULL; double total_stack_inner_percent = 0; double total_master_inner_percent = 0; @@ -795,14 +820,17 @@ arrange(Monitor *m, bool want_animation, bool from_view) { i++; } - set_arrange_visible(m, c, want_animation); + if (!only_caculate) + set_arrange_visible(m, c, want_animation); } else { - set_arrange_hidden(m, c, want_animation); + if (!only_caculate) + set_arrange_hidden(m, c, want_animation); } } - if (c->mon == m && c->ismaximizescreen && !c->animation.tagouted && - !c->animation.tagouting && VISIBLEON(c, m)) { + if (!only_caculate && c->mon == m && c->ismaximizescreen && + !c->animation.tagouted && !c->animation.tagouting && + VISIBLEON(c, m)) { reset_maximizescreen_size(c); } } @@ -811,6 +839,12 @@ arrange(Monitor *m, bool want_animation, bool from_view) { m, m->visible_tiling_clients, total_left_stack_hight_percent, total_right_stack_hight_percent, total_stack_inner_percent, total_master_inner_percent, master_num, stack_num); +} + +void // 17 +arrange(Monitor *m, bool want_animation, bool from_view) { + + pre_caculate_before_arrange(m, want_animation, from_view, false); if (m->isoverview) { overviewlayout.arrange(m); diff --git a/src/mango.c b/src/mango.c index 9a027a33..3ae5ccc9 100644 --- a/src/mango.c +++ b/src/mango.c @@ -412,6 +412,7 @@ struct Client { double old_master_mfact_per, old_master_inner_per, old_stack_inner_per; double old_scroller_pproportion; bool ismaster; + bool old_ismaster; bool cursor_in_upper_half, cursor_in_left_half; bool isleftstack; int32_t tearing_hint; @@ -488,7 +489,6 @@ typedef struct { typedef struct { struct wlr_xdg_popup *wlr_popup; - uint32_t type; struct wl_listener destroy; struct wl_listener commit; struct wl_listener reposition; @@ -804,6 +804,8 @@ static void last_cursor_surface_destroy(struct wl_listener *listener, void *data); static int32_t keep_idle_inhibit(void *data); static void check_keep_idle_inhibit(Client *c); +static void pre_caculate_before_arrange(Monitor *m, bool want_animation, + bool from_view, bool only_caculate); #include "data/static_keymap.h" #include "dispatch/bind_declare.h" @@ -2591,6 +2593,9 @@ void destroydecoration(struct wl_listener *listener, void *data) { static void popup_unconstrain(Popup *popup) { struct wlr_xdg_popup *wlr_popup = popup->wlr_popup; + Client *c = NULL; + LayerSurface *l = NULL; + int32_t type = -1; if (!wlr_popup || !wlr_popup->parent) { return; @@ -2601,16 +2606,17 @@ static void popup_unconstrain(Popup *popup) { wlr_log(WLR_ERROR, "Popup parent has no scene node"); return; } + + type = toplevel_from_wlr_surface(wlr_popup->base->surface, &c, &l); + if ((l && !l->mon) || (c && !c->mon)) { + wlr_xdg_popup_destroy(wlr_popup); + return; + } + int parent_lx, parent_ly; wlr_scene_node_coords(parent_node, &parent_lx, &parent_ly); - struct wlr_box *scheduled = &wlr_popup->scheduled.geometry; - int popup_lx = parent_lx + scheduled->x; - int popup_ly = parent_ly + scheduled->y; - - Monitor *mon = get_monitor_nearest_to(popup_lx, popup_ly); - - struct wlr_box usable = popup->type == LayerShell ? mon->m : mon->w; + struct wlr_box usable = type == LayerShell ? l->mon->m : c->mon->w; struct wlr_box constraint_box = { .x = usable.x - parent_lx, @@ -2633,33 +2639,22 @@ static void commitpopup(struct wl_listener *listener, void *data) { Popup *popup = wl_container_of(listener, popup, commit); struct wlr_surface *surface = data; - struct wlr_xdg_popup *wkr_popup = + struct wlr_xdg_popup *wlr_popup = wlr_xdg_popup_try_from_wlr_surface(surface); - Client *c = NULL; - LayerSurface *l = NULL; - int32_t type = -1; - - if (!wkr_popup || !wkr_popup->base->initial_commit) + if (!wlr_popup || !wlr_popup->base->initial_commit) goto commitpopup_listen_free; - type = toplevel_from_wlr_surface(wkr_popup->base->surface, &c, &l); - if (!wkr_popup->parent || !wkr_popup->parent->data || type < 0) { - wlr_xdg_popup_destroy(wkr_popup); + if (!wlr_popup->parent || !wlr_popup->parent->data) { goto commitpopup_listen_free; } - wlr_scene_node_raise_to_top(wkr_popup->parent->data); + wlr_scene_node_raise_to_top(wlr_popup->parent->data); - wkr_popup->base->surface->data = - wlr_scene_xdg_surface_create(wkr_popup->parent->data, wkr_popup->base); - if ((l && !l->mon) || (c && !c->mon)) { - wlr_xdg_popup_destroy(wkr_popup); - goto commitpopup_listen_free; - } + wlr_popup->base->surface->data = + wlr_scene_xdg_surface_create(wlr_popup->parent->data, wlr_popup->base); - popup->type = type; - popup->wlr_popup = wkr_popup; + popup->wlr_popup = wlr_popup; popup_unconstrain(popup); @@ -3989,6 +3984,7 @@ void init_client_properties(Client *c) { c->swallowing = NULL; c->swallowedby = NULL; c->ismaster = 0; + c->old_ismaster = 0; c->isleftstack = 0; c->ismaximizescreen = 0; c->isfullscreen = 0; @@ -5055,6 +5051,10 @@ setfloating(Client *c, int32_t floating) { restore_size_per(c->mon, c); } + if (c->isfloating && !old_floating_state) { + save_old_size_per(c->mon); + } + if (!c->force_maximize) client_set_maximized(c, false); @@ -5141,6 +5141,10 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) { restore_size_per(c->mon, c); } + if (c->ismaximizescreen && !old_maximizescreen_state) { + save_old_size_per(c->mon); + } + if (!c->force_maximize && !c->ismaximizescreen) { client_set_maximized(c, false); } else if (!c->force_maximize && c->ismaximizescreen) { @@ -5212,6 +5216,10 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 restore_size_per(c->mon, c); } + if (c->isfullscreen && !old_fullscreen_state) { + save_old_size_per(c->mon); + } + arrange(c->mon, false, false); }