diff --git a/src/animation/client.h b/src/animation/client.h index 2c39e511..03466f37 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -1,7 +1,27 @@ #include "wlr/util/log.h" + +static inline bool client_is_ignore_output_clip(Client *c) { + return c == grabc || (!ISSCROLLTILED(c) && !c->animation.tagining && + !c->animation.tagouting); +} + +static inline struct ivec2 compute_edge_offsets(Client *c) { + struct ivec2 offsets = {0}; + if (client_is_ignore_output_clip(c)) + return offsets; + + struct wlr_box cur = c->animation.current; + offsets.width = + GEZERO(cur.x + cur.width - c->mon->m.x - c->mon->m.width); // right + offsets.height = + GEZERO(cur.y + cur.height - c->mon->m.y - c->mon->m.height); // bottom + offsets.x = GEZERO(c->mon->m.x - cur.x); // left + offsets.y = GEZERO(c->mon->m.y - cur.y); // top + return offsets; +} + void client_actual_size(Client *c, int32_t *width, int32_t *height) { *width = c->animation.current.width - 2 * (int32_t)c->bw; - *height = c->animation.current.height - 2 * (int32_t)c->bw; } @@ -13,55 +33,48 @@ struct fx_corner_radii set_client_corner_location(Client *c) { struct fx_corner_radii current_corner_location = corner_radii_all(config.border_radius); - if (c == grabc || (!ISSCROLLTILED(c) && !c->animation.tagining && - !c->animation.tagouting)) { + if (client_is_ignore_output_clip(c)) return current_corner_location; - } struct wlr_box target_geom = config.animations ? c->animation.current : c->geom; if (target_geom.x + config.border_radius <= c->mon->m.x) { - current_corner_location.top_left = 0; // 清除左标志位 - current_corner_location.bottom_left = 0; // 清除左标志位 + current_corner_location.top_left = 0; + current_corner_location.bottom_left = 0; } if (target_geom.x + target_geom.width - config.border_radius >= c->mon->m.x + c->mon->m.width) { - current_corner_location.top_right = 0; // 清除右标志位 - current_corner_location.bottom_right = 0; // 清除右标志位 + current_corner_location.top_right = 0; + current_corner_location.bottom_right = 0; } if (target_geom.y + config.border_radius <= c->mon->m.y) { - current_corner_location.top_left = 0; // 清除上标志位 - current_corner_location.top_right = 0; // 清除上标志位 + current_corner_location.top_left = 0; + current_corner_location.top_right = 0; } if (target_geom.y + target_geom.height - config.border_radius >= c->mon->m.y + c->mon->m.height) { - current_corner_location.bottom_left = 0; // 清除下标志位 - current_corner_location.bottom_right = 0; // 清除下标志位 + current_corner_location.bottom_left = 0; + current_corner_location.bottom_right = 0; } return current_corner_location; } bool is_horizontal_stack_layout(Monitor *m) { - if (m->pertag->curtag && (m->pertag->ltidxs[m->pertag->curtag]->id == TILE || m->pertag->ltidxs[m->pertag->curtag]->id == DECK)) return true; - return false; } bool is_horizontal_right_stack_layout(Monitor *m) { - if (m->pertag->curtag && - (m->pertag->ltidxs[m->pertag->curtag]->id == RIGHT_TILE)) + m->pertag->ltidxs[m->pertag->curtag]->id == RIGHT_TILE) return true; - return false; } int32_t is_special_animation_rule(Client *c) { - if (is_scroller_layout(c->mon) && !c->isfloating) { return DOWN; } else if (c->mon->visible_tiling_clients == 1 && !c->isfloating) { @@ -182,30 +195,25 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int32_t sx, BufferData *buffer_data = (BufferData *)data; if (buffer_data->should_scale && buffer_data->height_scale < 1 && - buffer_data->width_scale < 1) { + buffer_data->width_scale < 1) buffer_data->should_scale = false; - } if (buffer_data->should_scale && buffer_data->height_scale == 1 && - buffer_data->width_scale < 1) { + buffer_data->width_scale < 1) buffer_data->should_scale = false; - } if (buffer_data->should_scale && buffer_data->height_scale < 1 && - buffer_data->width_scale == 1) { + buffer_data->width_scale == 1) buffer_data->should_scale = false; - } struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(buffer); - if (scene_surface == NULL) return; struct wlr_surface *surface = scene_surface->surface; if (buffer_data->should_scale) { - int32_t surface_width = surface->current.width; int32_t surface_height = surface->current.height; @@ -217,31 +225,25 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int32_t sx, : buffer_data->height_scale * surface_height; if (surface_width > buffer_data->width && - wlr_subsurface_try_from_wlr_surface(surface) == NULL) { + wlr_subsurface_try_from_wlr_surface(surface) == NULL) surface_width = buffer_data->width; - } if (surface_height > buffer_data->height && - wlr_subsurface_try_from_wlr_surface(surface) == NULL) { + wlr_subsurface_try_from_wlr_surface(surface) == NULL) surface_height = buffer_data->height; - } if (surface_width > buffer_data->width && - wlr_subsurface_try_from_wlr_surface(surface) != NULL) { + wlr_subsurface_try_from_wlr_surface(surface) != NULL) return; - } if (surface_height > buffer_data->height && - wlr_subsurface_try_from_wlr_surface(surface) != NULL) { + wlr_subsurface_try_from_wlr_surface(surface) != NULL) return; - } - if (surface_height > 0 && surface_width > 0) { + if (surface_height > 0 && surface_width > 0) wlr_scene_buffer_set_dest_size(buffer, surface_width, surface_height); - } } - // TODO: blur set, opacity set if (wlr_xdg_popup_try_from_wlr_surface(surface) != NULL) return; @@ -253,8 +255,7 @@ void scene_buffer_apply_overview_effect(struct wlr_scene_buffer *buffer, int32_t sx, int32_t sy, void *data) { BufferData *buffer_data = (BufferData *)data; - int32_t surface_width = 0; - int32_t surface_height = 0; + int32_t surface_width = 0, surface_height = 0; bool is_subsurface = false; struct wlr_scene_tree *parent_tree = buffer->node.parent; @@ -284,38 +285,32 @@ void scene_buffer_apply_overview_effect(struct wlr_scene_buffer *buffer, } void buffer_set_effect(Client *c, BufferData data) { - if (!c || c->iskilling) return; if (c->animation.tagouting || c->animation.tagouted || - c->animation.tagining) { + c->animation.tagining) data.should_scale = false; - } if (c == grabc) data.should_scale = false; if (c->isfullscreen || (config.no_radius_when_single && c->mon && - c->mon->visible_tiling_clients == 1)) { + c->mon->visible_tiling_clients == 1)) data.corner_location = corner_radii_none(); - } - if (config.blur && !c->noblur) { + if (config.blur && !c->noblur) wlr_scene_blur_set_corner_radii(c->blur, data.corner_location); - } - if (c->overview_scene_surface) { + if (c->overview_scene_surface) wlr_scene_node_for_each_buffer( &c->scene_surface->node, scene_buffer_apply_overview_effect, &data); - } else { + else wlr_scene_node_for_each_buffer(&c->scene_surface->node, scene_buffer_apply_effect, &data); - } } -void client_draw_shadow(Client *c) { - +void client_draw_shadow(Client *c, struct ivec2 offsets) { if (c->iskilling || !client_surface(c)->mapped || c->isnoshadow) return; @@ -336,18 +331,19 @@ void client_draw_shadow(Client *c) { ? corner_radii_none() : set_client_corner_location(c); - int32_t bwoffset = c->bw != 0 && hit_no_border ? (int32_t)c->bw : 0; + int32_t bw = (int32_t)c->bw; + int32_t bwoffset = bw != 0 && hit_no_border ? bw : 0; int32_t width, height; client_actual_size(c, &width, &height); - int32_t delta = config.shadows_size + (int32_t)c->bw - bwoffset; + int32_t delta = config.shadows_size + bw - bwoffset; struct wlr_box client_box = { .x = bwoffset, .y = bwoffset, - .width = width + 2 * (int32_t)c->bw - 2 * bwoffset, - .height = height + 2 * (int32_t)c->bw - 2 * bwoffset, + .width = width + 2 * bw - 2 * bwoffset, + .height = height + 2 * bw - 2 * bwoffset, }; struct wlr_box shadow_box = { @@ -367,53 +363,45 @@ void client_draw_shadow(Client *c) { .corners = current_corner_location, }; + struct wlr_box cur = c->animation.current; struct wlr_box absolute_shadow_box = { - .x = shadow_box.x + c->animation.current.x, - .y = shadow_box.y + c->animation.current.y, + .x = shadow_box.x + cur.x, + .y = shadow_box.y + cur.y, .width = shadow_box.width, .height = shadow_box.height, }; - int32_t right_offset, bottom_offset, left_offset, top_offset; - - if (c == grabc || (!ISSCROLLTILED(c) && !c->animation.tagining && - !c->animation.tagouting)) { - right_offset = 0; - bottom_offset = 0; - left_offset = 0; - top_offset = 0; + int32_t left, right, top, bottom; + if (client_is_ignore_output_clip(c)) { + left = right = top = bottom = 0; } else { - right_offset = - GEZERO(absolute_shadow_box.x + absolute_shadow_box.width - - c->mon->m.x - c->mon->m.width); - bottom_offset = - GEZERO(absolute_shadow_box.y + absolute_shadow_box.height - - c->mon->m.y - c->mon->m.height); - - left_offset = GEZERO(c->mon->m.x - absolute_shadow_box.x); - top_offset = GEZERO(c->mon->m.y - absolute_shadow_box.y); + right = GEZERO(absolute_shadow_box.x + absolute_shadow_box.width - + c->mon->m.x - c->mon->m.width); + bottom = GEZERO(absolute_shadow_box.y + absolute_shadow_box.height - + c->mon->m.y - c->mon->m.height); + left = GEZERO(c->mon->m.x - absolute_shadow_box.x); + top = GEZERO(c->mon->m.y - absolute_shadow_box.y); } - left_offset = MANGO_MIN(left_offset, shadow_box.width); - right_offset = MANGO_MIN(right_offset, shadow_box.width); - top_offset = MANGO_MIN(top_offset, shadow_box.height); - bottom_offset = MANGO_MIN(bottom_offset, shadow_box.height); + left = MANGO_MIN(left, shadow_box.width); + right = MANGO_MIN(right, shadow_box.width); + top = MANGO_MIN(top, shadow_box.height); + bottom = MANGO_MIN(bottom, shadow_box.height); - wlr_scene_node_set_position(&c->shadow->node, shadow_box.x + left_offset, - shadow_box.y + top_offset); + wlr_scene_node_set_position(&c->shadow->node, shadow_box.x + left, + shadow_box.y + top); - wlr_scene_shadow_set_size( - c->shadow, GEZERO(shadow_box.width - left_offset - right_offset), - GEZERO(shadow_box.height - top_offset - bottom_offset)); + wlr_scene_shadow_set_size(c->shadow, + GEZERO(shadow_box.width - left - right), + GEZERO(shadow_box.height - top - bottom)); - clipped_region.area.x = clipped_region.area.x - left_offset; - clipped_region.area.y = clipped_region.area.y - top_offset; + clipped_region.area.x = clipped_region.area.x - left; + clipped_region.area.y = clipped_region.area.y - top; wlr_scene_shadow_set_clipped_region(c->shadow, clipped_region); } -void client_draw_groupbar(Client *c) { - +void client_draw_groupbar(Client *c, struct ivec2 offsets) { if (!c || !c->group_bar) return; @@ -445,30 +433,19 @@ void client_draw_groupbar(Client *c) { int32_t tw = c->animation.current.width; int32_t th = config.group_bar_height; - int32_t left_over = c->mon->m.x - tab_x; - int32_t right_over = tab_x + tw - c->mon->m.x - c->mon->m.width; - int32_t top_over = c->mon->m.y - tab_y; - int32_t bottom_over = - tab_y + config.group_bar_height - c->mon->m.y - c->mon->m.height; - - if (c == grabc || (!ISSCROLLTILED(c) && !c->animation.tagining && - !c->animation.tagouting)) { - top_over = 0; - bottom_over = 0; - left_over = 0; - right_over = 0; - } + int32_t top_over = offsets.y; // top + int32_t bottom_over = offsets.height; // bottom + int32_t left_over = offsets.x; // left + int32_t right_over = offsets.width; // right if (top_over > 0) { tab_y = c->mon->m.y; th = config.group_bar_height - top_over; } - if (bottom_over > 0) { + if (bottom_over > 0) th = th - bottom_over; - } - if (right_over > 0) { + if (right_over > 0) tw = tw - right_over; - } if (left_over > 0) { tab_x = c->mon->m.x; tw = tw - left_over; @@ -500,34 +477,14 @@ void client_draw_groupbar(Client *c) { } } -void client_draw_shield(Client *c, struct wlr_box clip_box) { +void client_draw_shield(Client *c, struct ivec2 clip_box) { - if (clip_box.width <= 0 || clip_box.height <= 0) { - wlr_scene_node_set_enabled(&c->shield->node, false); - return; - } + int32_t shield_x = 0; + int32_t shield_y = 0; + int32_t shield_width = 0; + int32_t shield_height = 0; - struct wlr_box surface_relative_geom; - client_get_clip(c, &surface_relative_geom); - - if (c == grabc || (!ISSCROLLTILED(c) && !c->animation.tagining && - !c->animation.tagouting)) { - clip_box.x = surface_relative_geom.x; - clip_box.y = surface_relative_geom.y; - clip_box.width = c->animation.current.width - 2 * (int32_t)c->bw; - clip_box.height = c->animation.current.height - 2 * (int32_t)c->bw; - } - - if (active_capture_count > 0 && c->shield_when_capture) { - int32_t shield_x = - clip_box.x - surface_relative_geom.x + (int32_t)c->bw; - int32_t shield_y = - clip_box.y - surface_relative_geom.y + (int32_t)c->bw; - wlr_scene_node_raise_to_top(&c->shield->node); - wlr_scene_node_set_position(&c->shield->node, shield_x, shield_y); - wlr_scene_rect_set_size(c->shield, clip_box.width, clip_box.height); - wlr_scene_node_set_enabled(&c->shield->node, true); - } else { + if (active_capture_count <= 0 || !c->shield_when_capture) { if (c->shield->node.enabled) { wlr_scene_node_lower_to_bottom(&c->shield->node); wlr_scene_node_set_position(&c->shield->node, 0, 0); @@ -535,41 +492,66 @@ void client_draw_shield(Client *c, struct wlr_box clip_box) { c->animation.current.height); wlr_scene_node_set_enabled(&c->shield->node, false); } + return; } + + if (client_is_ignore_output_clip(c)) { + shield_x = c->bw; + shield_y = c->bw; + shield_width = c->animation.current.width - 2 * (int32_t)c->bw; + shield_height = c->animation.current.height - 2 * (int32_t)c->bw; + } else { + shield_x = clip_box.x + (int32_t)c->bw; + shield_y = clip_box.y + (int32_t)c->bw; + shield_width = c->animation.current.width - 2 * (int32_t)c->bw - + clip_box.width - clip_box.x; + shield_height = c->animation.current.height - 2 * (int32_t)c->bw - + clip_box.height - clip_box.y; + } + + if (shield_width <= 0 || shield_height <= 0) { + wlr_scene_node_set_enabled(&c->shield->node, false); + return; + } + + wlr_scene_node_raise_to_top(&c->shield->node); + wlr_scene_node_set_position(&c->shield->node, shield_x, shield_y); + wlr_scene_rect_set_size(c->shield, shield_width, shield_height); + wlr_scene_node_set_enabled(&c->shield->node, true); } -void client_draw_blur(Client *c, struct wlr_box clip_box, struct ivec2 offset) { +void client_draw_blur(Client *c, struct ivec2 clip_box) { if (c->isfullscreen) { - if (c->blur->node.enabled) { + if (c->blur->node.enabled) wlr_scene_node_set_enabled(&c->blur->node, false); - } return; - } else { - if (config.blur && !c->noblur) { + } - struct wlr_box surface_relative_geom; - client_get_clip(c, &surface_relative_geom); + int32_t blur_x = 0; + int32_t blur_y = 0; + int32_t blur_width = 0; + int32_t blur_height = 0; - if (c == grabc || (!ISSCROLLTILED(c) && !c->animation.tagining && - !c->animation.tagouting)) { - clip_box.x = surface_relative_geom.x; - clip_box.y = surface_relative_geom.y; - clip_box.width = - c->animation.current.width - 2 * (int32_t)c->bw; - clip_box.height = - c->animation.current.height - 2 * (int32_t)c->bw; - } + if (config.blur && !c->noblur) { - int32_t blur_x = - clip_box.x - surface_relative_geom.x + (int32_t)c->bw; - int32_t blur_y = - clip_box.y - surface_relative_geom.y + (int32_t)c->bw; - wlr_scene_node_set_enabled(&c->blur->node, true); - wlr_scene_node_set_position(&c->blur->node, blur_x, blur_y); - wlr_scene_blur_set_size(c->blur, clip_box.width, clip_box.height); - } else { - wlr_scene_node_set_enabled(&c->blur->node, false); + if (client_is_ignore_output_clip(c)) { + blur_x = c->bw; + blur_y = c->bw; + blur_width = c->animation.current.width - 2 * (int32_t)c->bw; + blur_height = c->animation.current.height - 2 * (int32_t)c->bw; } + + blur_x = clip_box.x + (int32_t)c->bw; + blur_y = clip_box.y + (int32_t)c->bw; + blur_width = c->animation.current.width - 2 * (int32_t)c->bw - + clip_box.width - clip_box.x; + blur_height = c->animation.current.height - 2 * (int32_t)c->bw - + clip_box.height - clip_box.y; + wlr_scene_node_set_enabled(&c->blur->node, true); + wlr_scene_node_set_position(&c->blur->node, blur_x, blur_y); + wlr_scene_blur_set_size(c->blur, blur_width, blur_height); + } else { + wlr_scene_node_set_enabled(&c->blur->node, false); } } @@ -582,8 +564,8 @@ void global_draw_group_bar(Client *c, int32_t x, int32_t y, int32_t width, mango_group_bar_set_size(c->group_bar, width, height); } -void client_draw_split_border(Client *c, bool hit_no_border) { - +void client_draw_split_border(Client *c, bool hit_no_border, + struct ivec2 offsets) { if (c->iskilling || !c->mon || !client_surface(c)->mapped) return; @@ -591,78 +573,55 @@ void client_draw_split_border(Client *c, bool hit_no_border) { if (hit_no_border || !ISTILED(c) || layout->id != DWINDLE || !config.dwindle_manual_split || c->isfullscreen) { - if (c->splitindicator[0]->node.enabled) { + if (c->splitindicator[0]->node.enabled) wlr_scene_node_set_enabled(&c->splitindicator[0]->node, false); - } - if (c->splitindicator[1]->node.enabled) { + if (c->splitindicator[1]->node.enabled) wlr_scene_node_set_enabled(&c->splitindicator[1]->node, false); - } return; + } + + DwindleNode **root = &c->mon->pertag->dwindle_root[c->mon->pertag->curtag]; + DwindleNode *dnode = dwindle_find_leaf(*root, c); + if (!dnode) { + wlr_scene_node_set_enabled(&c->splitindicator[0]->node, false); + wlr_scene_node_set_enabled(&c->splitindicator[1]->node, false); + return; + } + + if (dnode->custom_leaf_split_h) { + wlr_scene_node_set_enabled(&c->splitindicator[0]->node, false); + wlr_scene_node_set_enabled(&c->splitindicator[1]->node, true); } else { - - DwindleNode **root = - &c->mon->pertag->dwindle_root[c->mon->pertag->curtag]; - DwindleNode *dnode = dwindle_find_leaf(*root, c); - - if (!dnode) { - wlr_scene_node_set_enabled(&c->splitindicator[0]->node, false); - wlr_scene_node_set_enabled(&c->splitindicator[1]->node, false); - return; - } else { - if (dnode->custom_leaf_split_h) { - wlr_scene_node_set_enabled(&c->splitindicator[0]->node, false); - wlr_scene_node_set_enabled(&c->splitindicator[1]->node, true); - } else { - wlr_scene_node_set_enabled(&c->splitindicator[0]->node, true); - wlr_scene_node_set_enabled(&c->splitindicator[1]->node, false); - } - } + wlr_scene_node_set_enabled(&c->splitindicator[0]->node, true); + wlr_scene_node_set_enabled(&c->splitindicator[1]->node, false); } struct wlr_box fullgeom = c->animation.current; - // 一但在GEZERO如果使用无符号,那么其他数据也会转换为无符号导致没有负数出错 int32_t bw = (int32_t)c->bw; - - int32_t right_offset, bottom_offset, left_offset, top_offset; - - if (c == grabc) { - right_offset = 0; - bottom_offset = 0; - left_offset = 0; - top_offset = 0; - } else { - right_offset = - GEZERO(c->animation.current.x + c->animation.current.width - - c->mon->m.x - c->mon->m.width); - bottom_offset = - GEZERO(c->animation.current.y + c->animation.current.height - - c->mon->m.y - c->mon->m.height); - - left_offset = GEZERO(c->mon->m.x - c->animation.current.x); - top_offset = GEZERO(c->mon->m.y - c->animation.current.y); - } + int32_t left = offsets.x, right = offsets.width, top = offsets.y, + bottom = offsets.height; int32_t border_down_width = GEZERO(fullgeom.width - 2 * config.border_radius - - GEZERO((left_offset + right_offset) - config.border_radius)); + GEZERO((left + right) - config.border_radius)); int32_t border_down_height = - GEZERO(bw - bottom_offset - GEZERO(top_offset + bw - fullgeom.height)); + GEZERO(bw - bottom - GEZERO(top + bw - fullgeom.height)); int32_t border_right_width = - GEZERO(bw - right_offset - GEZERO(left_offset + bw - fullgeom.width)); + GEZERO(bw - right - GEZERO(left + bw - fullgeom.width)); int32_t border_right_height = GEZERO(fullgeom.height - 2 * config.border_radius - - GEZERO((top_offset + bottom_offset) - config.border_radius)); + GEZERO((top + bottom) - config.border_radius)); - int32_t border_down_x = GEZERO(config.border_radius + - GEZERO(left_offset - config.border_radius)); - int32_t border_down_y = GEZERO(fullgeom.height - bw) + - GEZERO(top_offset + bw - fullgeom.height); + int32_t border_down_x = + GEZERO(config.border_radius + GEZERO(left - config.border_radius)); + int32_t border_down_y = + GEZERO(fullgeom.height - bw) + GEZERO(top + bw - fullgeom.height); int32_t border_right_x = - GEZERO(fullgeom.width - bw) + GEZERO(left_offset + bw - fullgeom.width); - int32_t border_right_y = GEZERO(config.border_radius + - GEZERO(top_offset - config.border_radius)); + GEZERO(fullgeom.width - bw) + GEZERO(left + bw - fullgeom.width); + int32_t border_right_y = + GEZERO(config.border_radius + GEZERO(top - config.border_radius)); set_rect_size(c->splitindicator[0], border_down_width, border_down_height); set_rect_size(c->splitindicator[1], border_right_width, @@ -673,7 +632,7 @@ void client_draw_split_border(Client *c, bool hit_no_border) { border_right_y); } -void client_draw_border(Client *c) { +void client_draw_border(Client *c, struct ivec2 offsets) { if (!c || c->iskilling || !client_surface(c)->mapped) return; @@ -686,13 +645,12 @@ void client_draw_border(Client *c) { } return; } else { - if (!c->border->node.enabled) { + if (!c->border->node.enabled) wlr_scene_node_set_enabled(&c->border->node, true); - } } bool hit_no_border = check_hit_no_border(c); - client_draw_split_border(c, hit_no_border); + client_draw_split_border(c, hit_no_border, offsets); struct fx_corner_radii current_corner_location = c->isfullscreen || (config.no_radius_when_single && c->mon && @@ -713,61 +671,30 @@ void client_draw_border(Client *c) { c->fake_no_border = false; } - struct wlr_box clip_box = c->animation.current; - // 一但在GEZERO如果使用无符号,那么其他数据也会转换为无符号导致没有负数出错 + struct wlr_box cur = c->animation.current; int32_t bw = (int32_t)c->bw; + int32_t left = offsets.x, right = offsets.width, top = offsets.y, + bottom = offsets.height; - int32_t right_offset, bottom_offset, left_offset, top_offset; + int32_t inner_surface_width = GEZERO(cur.width - 2 * bw); + int32_t inner_surface_height = GEZERO(cur.height - 2 * bw); + int32_t inner_surface_x = GEZERO(bw - left); + int32_t inner_surface_y = GEZERO(bw - top); - if (c == grabc || (!ISSCROLLTILED(c) && !c->animation.tagining && - !c->animation.tagouting)) { - right_offset = 0; - bottom_offset = 0; - left_offset = 0; - top_offset = 0; - } else { - right_offset = - GEZERO(c->animation.current.x + c->animation.current.width - - c->mon->m.x - c->mon->m.width); - bottom_offset = - GEZERO(c->animation.current.y + c->animation.current.height - - c->mon->m.y - c->mon->m.height); + int32_t rect_x = left; + int32_t rect_y = top; + int32_t rect_width = GEZERO(cur.width - left - right); + int32_t rect_height = GEZERO(cur.height - top - bottom); - left_offset = GEZERO(c->mon->m.x - c->animation.current.x); - top_offset = GEZERO(c->mon->m.y - c->animation.current.y); - } - - int32_t inner_surface_width = GEZERO(clip_box.width - 2 * bw); - int32_t inner_surface_height = GEZERO(clip_box.height - 2 * bw); - - int32_t inner_surface_x = GEZERO(bw - left_offset); - int32_t inner_surface_y = GEZERO(bw - top_offset); - - int32_t rect_x = left_offset; - int32_t rect_y = top_offset; - - int32_t rect_width = - GEZERO(c->animation.current.width - left_offset - right_offset); - int32_t rect_height = - GEZERO(c->animation.current.height - top_offset - bottom_offset); - - if (left_offset > c->bw) - inner_surface_width = - inner_surface_width - left_offset + (int32_t)c->bw; - - if (top_offset > c->bw) + if (left > c->bw) + inner_surface_width = inner_surface_width - left + bw; + if (top > c->bw) + inner_surface_height = inner_surface_height - top + bw; + if (right > 0) + inner_surface_width = MANGO_MIN(cur.width, inner_surface_width + right); + if (bottom > 0) inner_surface_height = - inner_surface_height - top_offset + (int32_t)c->bw; - - if (right_offset > 0) { - inner_surface_width = - MANGO_MIN(clip_box.width, inner_surface_width + right_offset); - } - - if (bottom_offset > 0) { - inner_surface_height = - MANGO_MIN(clip_box.height, inner_surface_height + bottom_offset); - } + MANGO_MIN(cur.height, inner_surface_height + bottom); struct clipped_region clipped_region = { .area = {inner_surface_x, inner_surface_y, inner_surface_width, @@ -782,57 +709,35 @@ void client_draw_border(Client *c) { wlr_scene_rect_set_clipped_region(c->border, clipped_region); } -struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { - int32_t offsetx = 0, offsety = 0, offsetw = 0, offseth = 0; - struct ivec2 offset = {0, 0, 0, 0}; +struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box, + struct ivec2 offsets) { + struct ivec2 offset = {0}; if (!ISSCROLLTILED(c) && !c->animation.tagining && !c->animation.tagouted && !c->animation.tagouting) return offset; - int32_t bottom_out_offset = - GEZERO(c->animation.current.y + c->animation.current.height - - c->mon->m.y - c->mon->m.height); - int32_t right_out_offset = - GEZERO(c->animation.current.x + c->animation.current.width - - c->mon->m.x - c->mon->m.width); - int32_t left_out_offset = GEZERO(c->mon->m.x - c->animation.current.x); - int32_t top_out_offset = GEZERO(c->mon->m.y - c->animation.current.y); - - // 必须转换为int,否计算会没有负数导致判断错误 int32_t bw = (int32_t)c->bw; + int32_t left = offsets.x, right = offsets.width, top = offsets.y, + bottom = offsets.height; - /* - 计算窗口表面超出屏幕四个方向的偏差,避免窗口超出屏幕 - 需要主要border超出屏幕的时候不计算如偏差之内而是 - 要等窗口表面超出才开始计算偏差 - */ - if (ISSCROLLTILED(c) || c->animation.tagining || c->animation.tagouted || - c->animation.tagouting) { - if (left_out_offset > 0) { - offsetx = GEZERO(left_out_offset - bw); - clip_box->x = clip_box->x + offsetx; - clip_box->width = clip_box->width - offsetx; - } else if (right_out_offset > 0) { - offsetw = GEZERO(right_out_offset - bw); - clip_box->width = clip_box->width - offsetw; - } - - if (top_out_offset > 0) { - offsety = GEZERO(top_out_offset - bw); - clip_box->y = clip_box->y + offsety; - clip_box->height = clip_box->height - offsety; - } else if (bottom_out_offset > 0) { - offseth = GEZERO(bottom_out_offset - bw); - clip_box->height = clip_box->height - offseth; - } + if (left > 0) { + offset.x = GEZERO(left - bw); + clip_box->x += offset.x; + clip_box->width -= offset.x; + } else if (right > 0) { + offset.width = GEZERO(right - bw); + clip_box->width -= offset.width; } - // 窗口表面超出屏幕四个方向的偏差 - offset.x = offsetx; - offset.y = offsety; - offset.width = offsetw; - offset.height = offseth; + if (top > 0) { + offset.y = GEZERO(top - bw); + clip_box->y += offset.y; + clip_box->height -= offset.y; + } else if (bottom > 0) { + offset.height = GEZERO(bottom - bw); + clip_box->height -= offset.height; + } if ((clip_box->width + bw <= 0 || clip_box->height + bw <= 0) && (ISSCROLLTILED(c) || c->animation.tagouting || c->animation.tagining)) { @@ -854,9 +759,8 @@ void client_set_drop_area(Client *c) { if (!c || !c->mon) return; - if (!c->enable_drop_area_draw && !c->droparea->node.enabled) { + if (!c->enable_drop_area_draw && !c->droparea->node.enabled) return; - } if (!c->enable_drop_area_draw && c->droparea->node.enabled) { wlr_scene_node_lower_to_bottom(&c->droparea->node); @@ -872,12 +776,10 @@ void client_set_drop_area(Client *c) { int32_t client_width = c->geom.width - 2 * bw; int32_t client_height = c->geom.height - 2 * bw; - // 光标在窗口客户区内的相对坐标 double rel_x = cursor->x - c->geom.x - bw; double rel_y = cursor->y - c->geom.y - bw; struct wlr_box drop_box; - const Layout *cur_layout = c->mon->pertag->ltidxs[c->mon->pertag->curtag]; bool dwindle_familiar = cur_layout->id == DWINDLE && config.dwindle_drop_simple_split; @@ -917,7 +819,6 @@ void client_set_drop_area(Client *c) { } } else if (cur_layout->id == TILE || cur_layout->id == DECK || cur_layout->id == CENTER_TILE || cur_layout->id == RIGHT_TILE) { - if (c->ismaster) { if (c->mon->visible_tiling_clients == 1) { if (rel_x < client_width * 0.5) { @@ -979,7 +880,6 @@ void client_set_drop_area(Client *c) { drop_box.height = client_height; drop_direction = UNDIR; } - } else { if (rel_x < client_width * 0.5) { drop_direction = LEFT; @@ -995,7 +895,6 @@ void client_set_drop_area(Client *c) { drop_box.height = client_height; } } - } else { double dist_left = rel_x; double dist_right = client_width - rel_x; @@ -1030,23 +929,25 @@ void client_set_drop_area(Client *c) { } } - if (!first_draw && c->drop_direction == drop_direction) { + if (!first_draw && c->drop_direction == drop_direction) return; - } c->drop_direction = drop_direction; wlr_scene_node_set_position(&c->droparea->node, drop_box.x, drop_box.y); wlr_scene_rect_set_size(c->droparea, drop_box.width, drop_box.height); } -void client_apply_clip(Client *c, float factor) { +/* ---------- central rendering entry point ---------- */ +void client_apply_clip(Client *c, float factor) { if (c->iskilling || !client_surface(c)->mapped) return; + struct ivec2 offsets = compute_edge_offsets(c); + struct wlr_box clip_box; bool should_render_client_surface = false; - struct ivec2 offset; + struct ivec2 surface_clip_offset; BufferData buffer_data; struct fx_corner_radii current_corner_location = @@ -1059,14 +960,13 @@ void client_apply_clip(Client *c, float factor) { c->geom; client_get_clip(c, &clip_box); + surface_clip_offset = clip_to_hide(c, &clip_box, offsets); - offset = clip_to_hide(c, &clip_box); - - client_draw_border(c); - client_draw_shadow(c); - client_draw_groupbar(c); - client_draw_blur(c, clip_box, offset); - client_draw_shield(c, clip_box); + client_draw_border(c, offsets); + client_draw_shadow(c, offsets); + client_draw_groupbar(c, offsets); + client_draw_blur(c, surface_clip_offset); + client_draw_shield(c, surface_clip_offset); if (clip_box.width <= 0 || clip_box.height <= 0) { should_render_client_surface = false; @@ -1076,14 +976,12 @@ void client_apply_clip(Client *c, float factor) { wlr_scene_node_set_enabled(&c->scene_surface->node, true); } - if (!should_render_client_surface) { + if (!should_render_client_surface) return; - } - if (!c->overview_scene_surface) { + if (!c->overview_scene_surface) wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); - } buffer_set_effect(c, (BufferData){1.0f, 1.0f, clip_box.width, clip_box.height, @@ -1091,11 +989,9 @@ void client_apply_clip(Client *c, float factor) { return; } - // 获取窗口动画实时位置矩形 int32_t width, height; client_actual_size(c, &width, &height); - // 计算出除了边框的窗口实际剪切大小 struct wlr_box geometry; client_get_geometry(c, &geometry); clip_box = (struct wlr_box){ @@ -1110,17 +1006,14 @@ void client_apply_clip(Client *c, float factor) { clip_box.y = 0; } - // 检测窗口是否需要剪切超出屏幕部分,如果需要就调整实际要剪切的矩形 - offset = clip_to_hide(c, &clip_box); + surface_clip_offset = clip_to_hide(c, &clip_box, offsets); - // 应用窗口装饰 - client_draw_border(c); - client_draw_shadow(c); - client_draw_groupbar(c); - client_draw_shield(c, clip_box); - client_draw_blur(c, clip_box, offset); + client_draw_border(c, offsets); + client_draw_shadow(c, offsets); + client_draw_groupbar(c, offsets); + client_draw_shield(c, surface_clip_offset); + client_draw_blur(c, surface_clip_offset); - // 如果窗口剪切区域已经剪切到0,则不渲染窗口表面 if (clip_box.width <= 0 || clip_box.height <= 0) { should_render_client_surface = false; wlr_scene_node_set_enabled(&c->scene_surface->node, false); @@ -1129,21 +1022,18 @@ void client_apply_clip(Client *c, float factor) { wlr_scene_node_set_enabled(&c->scene_surface->node, true); } - // 不用在执行下面的窗口表面剪切和缩放等效果操作 - if (!should_render_client_surface) { + if (!should_render_client_surface) return; - } - // 应用窗口表面剪切 - if (!c->overview_scene_surface) { + if (!c->overview_scene_surface) wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); - } - // 获取剪切后的表面的实际大小用于计算缩放 - int32_t acutal_surface_width = geometry.width - offset.x - offset.width; - int32_t acutal_surface_height = geometry.height - offset.y - offset.height; + int32_t actual_surface_width = + geometry.width - surface_clip_offset.x - surface_clip_offset.width; + int32_t actual_surface_height = + geometry.height - surface_clip_offset.y - surface_clip_offset.height; - if (acutal_surface_width <= 0 || acutal_surface_height <= 0) + if (actual_surface_width <= 0 || actual_surface_height <= 0) return; buffer_data.should_scale = true; @@ -1156,9 +1046,9 @@ void client_apply_clip(Client *c, float factor) { buffer_data.height_scale = 1.0; } else { buffer_data.width_scale = - (float)buffer_data.width / acutal_surface_width; + (float)buffer_data.width / actual_surface_width; buffer_data.height_scale = - (float)buffer_data.height / acutal_surface_height; + (float)buffer_data.height / actual_surface_height; } buffer_set_effect(c, buffer_data); @@ -1168,8 +1058,6 @@ void fadeout_client_animation_next_tick(Client *c) { if (!c) return; - BufferData buffer_data; - struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); @@ -1179,14 +1067,13 @@ void fadeout_client_animation_next_tick(Client *c) { ? (double)passed_time / (double)c->animation.duration : 1.0; - int32_t type = c->animation.action = c->animation.action; + int32_t type = c->animation.action; double factor = find_animation_curve_at(animation_passed, type); int32_t width = c->animation.initial.width + (c->current.width - c->animation.initial.width) * factor; int32_t height = c->animation.initial.height + (c->current.height - c->animation.initial.height) * factor; - int32_t x = c->animation.initial.x + (c->current.x - c->animation.initial.x) * factor; int32_t y = c->animation.initial.y + @@ -1203,10 +1090,8 @@ void fadeout_client_animation_next_tick(Client *c) { double opacity_eased_progress = find_animation_curve_at(animation_passed, OPAFADEOUT); - double percent = config.fadeout_begin_opacity - (opacity_eased_progress * config.fadeout_begin_opacity); - double opacity = MANGO_MAX(percent, 0); if (config.animation_fade_out && !c->nofadeout) @@ -1217,12 +1102,11 @@ void fadeout_client_animation_next_tick(Client *c) { strcmp(c->animation_type_close, "zoom") == 0) || (!c->animation_type_close && strcmp(config.animation_type_close, "zoom") == 0)) { - + BufferData buffer_data; buffer_data.width = width; buffer_data.height = height; buffer_data.width_scale = animation_passed; buffer_data.height_scale = animation_passed; - wlr_scene_node_for_each_buffer( &c->scene->node, snap_scene_buffer_apply_effect, &buffer_data); } @@ -1231,7 +1115,6 @@ void fadeout_client_animation_next_tick(Client *c) { wl_list_remove(&c->fadeout_link); wlr_scene_node_destroy(&c->scene->node); free(c); - c = NULL; } } @@ -1248,15 +1131,10 @@ void client_animation_next_tick(Client *c) { int32_t type = c->animation.action == NONE ? MOVE : c->animation.action; double factor = find_animation_curve_at(animation_passed, type); - Client *pointer_c = NULL; - double sx = 0, sy = 0; - struct wlr_surface *surface = NULL; - int32_t width = c->animation.initial.width + (c->current.width - c->animation.initial.width) * factor; int32_t height = c->animation.initial.height + (c->current.height - c->animation.initial.height) * factor; - int32_t x = c->animation.initial.x + (c->current.x - c->animation.initial.x) * factor; int32_t y = c->animation.initial.y + @@ -1271,16 +1149,10 @@ void client_animation_next_tick(Client *c) { }; c->is_pending_open_animation = false; - client_apply_clip(c, factor); if (animation_passed >= 1.0) { - - // clear the open action state - // To prevent him from being mistaken that - // it's still in the opening animation in resize c->animation.action = MOVE; - c->animation.tagining = false; c->animation.running = false; c->animation.overining = false; @@ -1292,40 +1164,34 @@ void client_animation_next_tick(Client *c) { c->animation.current = c->geom; } + Client *pointer_c = NULL; + double sx, sy; xytonode(cursor->x, cursor->y, NULL, &pointer_c, NULL, NULL, &sx, &sy); - - surface = + struct wlr_surface *surface = pointer_c && pointer_c == c ? client_surface(pointer_c) : NULL; - // avoid game window force grab pointer in overview mode - if (surface && pointer_c == selmon->sel && !selmon->isoverview) { + if (surface && pointer_c == selmon->sel && !selmon->isoverview) wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - } - // end flush in next frame, not the current frame c->need_output_flush = false; } } void init_fadeout_client(Client *c) { - if (!c->mon || client_is_unmanaged(c)) return; - if (!c->scene) { + if (!c->scene) return; - } - if (c->shield_when_capture && active_capture_count > 0) { + if (c->shield_when_capture && active_capture_count > 0) return; - } if ((c->animation_type_close && strcmp(c->animation_type_close, "none") == 0) || (!c->animation_type_close && - strcmp(config.animation_type_close, "none") == 0)) { + strcmp(config.animation_type_close, "none") == 0)) return; - } Client *fadeout_client = ecalloc(1, sizeof(*fadeout_client)); @@ -1354,9 +1220,6 @@ void init_fadeout_client(Client *c) { fadeout_client->bw = c->bw; fadeout_client->nofadeout = c->nofadeout; - // 这里snap节点的坐标设置是使用的相对坐标,所以不能加上原来坐标 - // 这跟普通node有区别 - fadeout_client->animation.initial.x = 0; fadeout_client->animation.initial.y = 0; @@ -1374,10 +1237,9 @@ void init_fadeout_client(Client *c) { strcmp(config.animation_type_close, "slide") == 0)) { fadeout_client->current.y = c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2 - ? c->mon->m.height - - (c->animation.current.y - c->mon->m.y) // down out - : c->mon->m.y - c->geom.height; // up out - fadeout_client->current.x = 0; // x无偏差,垂直划出 + ? c->mon->m.height - (c->animation.current.y - c->mon->m.y) + : c->mon->m.y - c->geom.height; + fadeout_client->current.x = 0; } else { fadeout_client->current.y = (fadeout_client->geom.height - @@ -1397,52 +1259,44 @@ void init_fadeout_client(Client *c) { wlr_scene_node_set_enabled(&fadeout_client->scene->node, true); wl_list_insert(&fadeout_clients, &fadeout_client->fadeout_link); - // 请求刷新屏幕 request_fresh_all_monitors(); } void client_commit(Client *c) { - c->current = c->pending; // 设置动画的结束位置 + c->current = c->pending; if (c->animation.should_animate) { - if (!c->animation.running) { + if (!c->animation.running) c->animation.current = c->animainit_geom; - } c->animation.initial = c->animainit_geom; c->animation.time_started = get_now_in_ms(); - - // 标记动画开始 c->animation.running = true; c->animation.should_animate = false; } - // 请求刷新屏幕 request_fresh_all_monitors(); } void client_set_pending_state(Client *c) { - if (!c || c->iskilling) return; - if (!config.animations) { + if (!config.animations) c->animation.should_animate = false; - } else if (config.animations && c->animation.tagining) { + else if (config.animations && c->animation.tagining) c->animation.should_animate = true; - } else if (c == grabc || (!c->is_pending_open_animation && - wlr_box_equal(&c->current, &c->pending))) { + else if (c == grabc || (!c->is_pending_open_animation && + wlr_box_equal(&c->current, &c->pending))) c->animation.should_animate = false; - } else { + else c->animation.should_animate = true; - } if (((c->animation_type_open && strcmp(c->animation_type_open, "none") == 0) || (!c->animation_type_open && strcmp(config.animation_type_open, "none") == 0)) && - c->animation.action == OPEN) { + c->animation.action == OPEN) c->animation.duration = 0; - } if (c->istagswitching) { c->animation.duration = 0; @@ -1459,58 +1313,46 @@ void client_set_pending_state(Client *c) { c->animation.duration = 0; } - // 开始动画 client_commit(c); c->dirty = true; } void resize(Client *c, struct wlr_box geo, int32_t interact) { - - // 动画设置的起始函数,这里用来计算一些动画的起始值 - // 动画起始位置大小是由于c->animainit_geom确定的 - if (!c || !c->mon || !client_surface(c)->mapped) return; - struct wlr_box *bbox; - struct wlr_box clip; - if (!c->mon) return; c->need_output_flush = true; c->dirty = true; - // float_geom = c->geom; - bbox = (interact || c->isfloating || c->isfullscreen) ? &sgeom : &c->mon->w; + struct wlr_box *bbox = + (interact || c->isfloating || c->isfullscreen) ? &sgeom : &c->mon->w; + struct wlr_box clip; if (is_scroller_layout(c->mon) && (!c->isfloating || c == grabc)) { c->geom = geo; c->geom.width = MANGO_MAX(1 + 2 * (int32_t)c->bw, c->geom.width); c->geom.height = MANGO_MAX(1 + 2 * (int32_t)c->bw, c->geom.height); - } else { // 这里会限制不允许窗口划出屏幕 + } else { c->geom = geo; - applybounds( - c, - bbox); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 + applybounds(c, bbox); } if (!c->isnosizehint && !c->ismaximizescreen && !c->isfullscreen && - c->isfloating) { + c->isfloating) client_set_size_bound(c); - } - if (!c->is_pending_open_animation) { + if (!c->is_pending_open_animation) c->animation.begin_fade_in = false; - } - if (c->animation.overining) { + if (c->animation.overining) c->animation.action = OVERVIEW; - } else if (c->animation.action == OPEN && !c->animation.tagining && - !c->animation.tagouting && - wlr_box_equal(&c->geom, &c->current)) { - c->animation.action = c->animation.action; - } else if (c->animation.tagouting) { + else if (c->animation.action == OPEN && !c->animation.tagining && + !c->animation.tagouting && wlr_box_equal(&c->geom, &c->current)) + ; /* keep current action */ + else if (c->animation.tagouting) { c->animation.duration = config.animation_duration_tag; c->animation.action = TAG; } else if (c->animation.tagining) { @@ -1524,21 +1366,18 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) { c->animation.action = MOVE; } - // 动画起始位置大小设置 - if (c->animation.tagouting) { + if (c->animation.tagouting) c->animainit_geom = c->animation.current; - } else if (c->animation.tagining) { + else if (c->animation.tagining) { c->animainit_geom.height = c->animation.current.height; c->animainit_geom.width = c->animation.current.width; - } else if (c->is_pending_open_animation) { + } else if (c->is_pending_open_animation) set_client_open_animation(c, c->geom); - } else { + else c->animainit_geom = c->animation.current; - } - if (c->isnoborder || c->iskilling) { + if (c->isnoborder || c->iskilling) c->bw = 0; - } bool hit_no_border = check_hit_no_border(c); if (hit_no_border && config.smartgaps) { @@ -1546,71 +1385,59 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) { c->fake_no_border = true; } - // c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局 - if (!c->mon->isoverview || !config.ov_no_resize) { + if (!c->mon->isoverview || !config.ov_no_resize) c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); - } - if (c->configure_serial != 0) { + if (c->configure_serial != 0) c->mon->resizing_count_pending++; - } if (c == grabc) { + struct ivec2 offsets = compute_edge_offsets(c); + c->animation.running = false; c->need_output_flush = false; - c->animainit_geom = c->current = c->pending = c->animation.current = c->geom; wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); - client_draw_border(c); + client_draw_border(c, offsets); client_get_clip(c, &clip); - client_draw_shield(c, clip); - client_draw_shadow(c); - client_draw_groupbar(c); + client_draw_groupbar(c, offsets); + client_draw_shadow(c, offsets); + + struct ivec2 surface_clip_offset = clip_to_hide(c, &clip, offsets); + client_draw_shield(c, surface_clip_offset); + client_draw_blur(c, surface_clip_offset); + wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); - if (config.blur && !c->noblur) - wlr_scene_blur_set_size(c->blur, - c->animation.current.width - 2 * c->bw, - c->animation.current.height - 2 * c->bw); return; } - // 如果不是工作区切换时划出去的窗口,就让动画的结束位置,就是上面的真实位置和大小 - // c->pending 决定动画的终点,一般在其他调用resize的函数的附近设置了 - if (!c->animation.tagouting && !c->iskilling) { + + if (!c->animation.tagouting && !c->iskilling) c->pending = c->geom; - } - if (c->swallowing && c->animation.action == OPEN) { + if (c->swallowing && c->animation.action == OPEN) c->animainit_geom = c->swallowing->animation.current; - } - if (c->swallowdby) { + if (c->swallowdby) c->animainit_geom = c->geom; - } if ((c->isglobal || c->isunglobal) && c->isfloating && - c->animation.action == TAG) { + c->animation.action == TAG) c->animainit_geom = c->geom; - } - if (c->scratchpad_switching_mon && c->isfloating) { + if (c->scratchpad_switching_mon && c->isfloating) c->animainit_geom = c->geom; - } if (config.animations && config.ov_no_resize && c->mon->isoverview && - c != c->mon->sel && c->animation.action == OVERVIEW) { + c != c->mon->sel && c->animation.action == OVERVIEW) set_overview_enter_animation(c); - } - if (!config.animations && config.ov_no_resize && c->mon->isoverview) { + if (!config.animations && config.ov_no_resize && c->mon->isoverview) c->animainit_geom = c->geom; - } - // 开始应用动画设置 client_set_pending_state(c); - setborder_color(c); } @@ -1640,7 +1467,6 @@ void client_set_focused_opacity_animation(Client *c) { c->opacity_animation.current_border_color, sizeof(c->opacity_animation.initial_border_color)); c->opacity_animation.initial_opacity = c->opacity_animation.current_opacity; - c->opacity_animation.running = true; } @@ -1655,20 +1481,16 @@ void client_set_unfocused_opacity_animation(Client *c) { c->opacity_animation.duration = config.animation_duration_focus; memcpy(c->opacity_animation.target_border_color, border_color, sizeof(c->opacity_animation.target_border_color)); - // Start opacity animation to unfocused c->opacity_animation.target_opacity = c->unfocused_opacity; c->opacity_animation.time_started = get_now_in_ms(); - memcpy(c->opacity_animation.initial_border_color, c->opacity_animation.current_border_color, sizeof(c->opacity_animation.initial_border_color)); c->opacity_animation.initial_opacity = c->opacity_animation.current_opacity; - c->opacity_animation.running = true; } bool client_apply_focus_opacity(Client *c) { - // Animate focus transitions (opacity + border color) float *border_color = get_border_color(c); if (c->isfullscreen) { c->opacity_animation.running = false; @@ -1686,36 +1508,30 @@ bool client_apply_focus_opacity(Client *c) { double opacity_eased_progress = find_animation_curve_at(linear_progress, OPAFADEIN); - float percent = config.animation_fade_in && !c->nofadein ? opacity_eased_progress : 1.0; float opacity = c == selmon->sel ? c->focused_opacity : c->unfocused_opacity; - float target_opacity = percent * (1.0 - config.fadein_begin_opacity) + config.fadein_begin_opacity; - if (target_opacity > opacity) { + if (target_opacity > opacity) target_opacity = opacity; - } + memcpy(c->opacity_animation.current_border_color, c->opacity_animation.target_border_color, sizeof(c->opacity_animation.current_border_color)); c->opacity_animation.current_opacity = target_opacity; client_set_opacity(c, target_opacity); if (config.blur && !c->noblur && !config.blur_optimized) { - wlr_scene_blur_set_strength( - c->blur, MIN(percent * (1.0 - config.fadein_begin_opacity) + - config.fadein_begin_opacity, - 1.0)); - wlr_scene_blur_set_alpha( - c->blur, MIN(percent * (1.0 - config.fadein_begin_opacity) + - config.fadein_begin_opacity, - 1.0)); + float blur_val = MIN(percent * (1.0 - config.fadein_begin_opacity) + + config.fadein_begin_opacity, + 1.0); + wlr_scene_blur_set_strength(c->blur, blur_val); + wlr_scene_blur_set_alpha(c->blur, blur_val); } client_set_border_color(c, c->opacity_animation.target_border_color); } else if (config.animations && c->opacity_animation.running) { - struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); @@ -1735,7 +1551,6 @@ bool client_apply_focus_opacity(Client *c) { eased_progress; client_set_opacity(c, c->opacity_animation.current_opacity); - // Animate border color for (int32_t i = 0; i < 4; i++) { c->opacity_animation.current_border_color[i] = c->opacity_animation.initial_border_color[i] + @@ -1744,11 +1559,10 @@ bool client_apply_focus_opacity(Client *c) { eased_progress; } client_set_border_color(c, c->opacity_animation.current_border_color); - if (linear_progress >= 1.0f) { + if (linear_progress >= 1.0f) c->opacity_animation.running = false; - } else { + else return true; - } } else if (c == selmon->sel) { c->opacity_animation.running = false; c->opacity_animation.current_opacity = c->focused_opacity; @@ -1767,13 +1581,11 @@ bool client_apply_focus_opacity(Client *c) { } bool client_draw_frame(Client *c) { - if (!c || !client_surface(c)->mapped) return false; - if (!c->need_output_flush) { + if (!c->need_output_flush) return client_apply_focus_opacity(c); - } if (config.animations && c->animation.running) { client_animation_next_tick(c); @@ -1785,6 +1597,5 @@ bool client_draw_frame(Client *c) { client_apply_clip(c, 1.0); c->need_output_flush = false; } - client_apply_focus_opacity(c); - return true; -} + return client_apply_focus_opacity(c); +} \ No newline at end of file diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 3258b20d..8df865c9 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -2148,7 +2148,8 @@ int32_t dwindle_set_split_direction(Client *c, bool istoggle, bool horizontal) { leaf->custom_leaf_split_h = false; } bool hit_no_border = check_hit_no_border(c); - client_draw_split_border(c, hit_no_border); + struct ivec2 offsets = compute_edge_offsets(c); + client_draw_split_border(c, hit_no_border, offsets); return 0; } diff --git a/src/mango.c b/src/mango.c index 6c318ceb..0f4aeecd 100644 --- a/src/mango.c +++ b/src/mango.c @@ -843,7 +843,7 @@ get_nearest_output_mode(struct wlr_output *output, int32_t width, static void client_commit(Client *c); static void layer_commit(LayerSurface *l); -static void client_draw_border(Client *c); +static void client_draw_border(Client *c, struct ivec2 offsets); static void client_set_opacity(Client *c, double opacity); static void init_baked_points(void); static void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer,