mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-27 21:37:30 -04:00
feat: dont resize client when in overview
This commit is contained in:
parent
9e4fade55e
commit
a6a765caff
9 changed files with 446 additions and 137 deletions
|
|
@ -78,6 +78,7 @@ dwindle_preserve_split=0
|
||||||
hotarea_size=10
|
hotarea_size=10
|
||||||
enable_hotarea=1
|
enable_hotarea=1
|
||||||
ov_tab_mode=0
|
ov_tab_mode=0
|
||||||
|
ov_no_resize=0
|
||||||
overviewgappi=5
|
overviewgappi=5
|
||||||
overviewgappo=30
|
overviewgappo=30
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ description: Configure the overview mode for window navigation.
|
||||||
| `ov_tab_mode` | integer | `0` | Overview tab mode (0: disable, 1: enable). |
|
| `ov_tab_mode` | integer | `0` | Overview tab mode (0: disable, 1: enable). |
|
||||||
| `overviewgappi` | integer | `5` | Inner gap in overview mode. |
|
| `overviewgappi` | integer | `5` | Inner gap in overview mode. |
|
||||||
| `overviewgappo` | integer | `30` | Outer gap in overview mode. |
|
| `overviewgappo` | integer | `30` | Outer gap in overview mode. |
|
||||||
|
| `ov_no_resize` | integer | `0` | Disable window resizing in overview mode. |
|
||||||
|
|
||||||
### Setting Descriptions
|
### Setting Descriptions
|
||||||
|
|
||||||
|
|
@ -20,6 +21,7 @@ description: Configure the overview mode for window navigation.
|
||||||
- `hotarea_size` — Size of the hot area trigger zone in pixels.
|
- `hotarea_size` — Size of the hot area trigger zone in pixels.
|
||||||
- `hotarea_corner` — Corner that triggers the hot area (0: top-left, 1: top-right, 2: bottom-left, 3: bottom-right).
|
- `hotarea_corner` — Corner that triggers the hot area (0: top-left, 1: top-right, 2: bottom-left, 3: bottom-right).
|
||||||
- `ov_tab_mode` — Circles focus through windows in overview; releasing the mod key exits overview.
|
- `ov_tab_mode` — Circles focus through windows in overview; releasing the mod key exits overview.
|
||||||
|
- `ov_no_resize` — Disables resizing of windows in overview mode(use snap to display).
|
||||||
|
|
||||||
### Mouse Interaction in Overview
|
### Mouse Interaction in Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,14 @@ int32_t is_special_animation_rule(Client *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_overview_enter_animation(Client *c) {
|
||||||
|
struct wlr_box geo = c->geom;
|
||||||
|
c->animainit_geom.width = geo.width * 1.2;
|
||||||
|
c->animainit_geom.height = geo.height * 1.2;
|
||||||
|
c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width) / 2;
|
||||||
|
c->animainit_geom.y = geo.y + (geo.height - c->animainit_geom.height) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
void set_client_open_animation(Client *c, struct wlr_box geo) {
|
void set_client_open_animation(Client *c, struct wlr_box geo) {
|
||||||
int32_t slide_direction;
|
int32_t slide_direction;
|
||||||
int32_t horizontal, horizontal_value;
|
int32_t horizontal, horizontal_value;
|
||||||
|
|
@ -231,6 +239,19 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int32_t sx,
|
||||||
buffer_data->corner_location);
|
buffer_data->corner_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scene_buffer_apply_overview_effect(struct wlr_scene_buffer *buffer,
|
||||||
|
int32_t sx, int32_t sy, void *data) {
|
||||||
|
BufferData *buffer_data = (BufferData *)data;
|
||||||
|
|
||||||
|
if (buffer_data->width > 0 && buffer_data->height > 0) {
|
||||||
|
wlr_scene_buffer_set_dest_size(buffer, buffer_data->width,
|
||||||
|
buffer_data->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_corner_radius(buffer, config.border_radius,
|
||||||
|
buffer_data->corner_location);
|
||||||
|
}
|
||||||
|
|
||||||
void buffer_set_effect(Client *c, BufferData data) {
|
void buffer_set_effect(Client *c, BufferData data) {
|
||||||
|
|
||||||
if (!c || c->iskilling)
|
if (!c || c->iskilling)
|
||||||
|
|
@ -250,8 +271,13 @@ void buffer_set_effect(Client *c, BufferData data) {
|
||||||
data.corner_location = CORNER_LOCATION_NONE;
|
data.corner_location = CORNER_LOCATION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
|
if (c->mon->isoverview && config.ov_no_resize) {
|
||||||
scene_buffer_apply_effect, &data);
|
wlr_scene_node_for_each_buffer(
|
||||||
|
&c->scene_surface->node, scene_buffer_apply_overview_effect, &data);
|
||||||
|
} 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) {
|
||||||
|
|
@ -793,7 +819,11 @@ void client_apply_clip(Client *c, float factor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box);
|
if (!c->mon->isoverview || !config.ov_no_resize) {
|
||||||
|
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node,
|
||||||
|
&clip_box);
|
||||||
|
}
|
||||||
|
|
||||||
buffer_set_effect(c, (BufferData){1.0f, 1.0f, clip_box.width,
|
buffer_set_effect(c, (BufferData){1.0f, 1.0f, clip_box.width,
|
||||||
clip_box.height,
|
clip_box.height,
|
||||||
current_corner_location, true});
|
current_corner_location, true});
|
||||||
|
|
@ -841,7 +871,9 @@ void client_apply_clip(Client *c, float factor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用窗口表面剪切
|
// 应用窗口表面剪切
|
||||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box);
|
if (!c->mon->isoverview || !config.ov_no_resize) {
|
||||||
|
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_width = geometry.width - offset.x - offset.width;
|
||||||
|
|
@ -987,6 +1019,7 @@ void client_animation_next_tick(Client *c) {
|
||||||
|
|
||||||
c->animation.tagining = false;
|
c->animation.tagining = false;
|
||||||
c->animation.running = false;
|
c->animation.running = false;
|
||||||
|
c->animation.overining = false;
|
||||||
|
|
||||||
if (c->animation.tagouting) {
|
if (c->animation.tagouting) {
|
||||||
c->animation.tagouting = false;
|
c->animation.tagouting = false;
|
||||||
|
|
@ -1125,9 +1158,8 @@ void client_set_pending_state(Client *c) {
|
||||||
c->animation.should_animate = false;
|
c->animation.should_animate = false;
|
||||||
} else if (config.animations && c->animation.tagining) {
|
} else if (config.animations && c->animation.tagining) {
|
||||||
c->animation.should_animate = true;
|
c->animation.should_animate = true;
|
||||||
} else if (!config.animations || c == grabc ||
|
} else if (c == grabc || (!c->is_pending_open_animation &&
|
||||||
(!c->is_pending_open_animation &&
|
wlr_box_equal(&c->current, &c->pending))) {
|
||||||
wlr_box_equal(&c->current, &c->pending))) {
|
|
||||||
c->animation.should_animate = false;
|
c->animation.should_animate = false;
|
||||||
} else {
|
} else {
|
||||||
c->animation.should_animate = true;
|
c->animation.should_animate = true;
|
||||||
|
|
@ -1201,8 +1233,11 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
c->animation.begin_fade_in = false;
|
c->animation.begin_fade_in = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->animation.action == OPEN && !c->animation.tagining &&
|
if (c->animation.overining) {
|
||||||
!c->animation.tagouting && wlr_box_equal(&c->geom, &c->current)) {
|
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;
|
c->animation.action = c->animation.action;
|
||||||
} else if (c->animation.tagouting) {
|
} else if (c->animation.tagouting) {
|
||||||
c->animation.duration = config.animation_duration_tag;
|
c->animation.duration = config.animation_duration_tag;
|
||||||
|
|
@ -1241,8 +1276,10 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局
|
// c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局
|
||||||
c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw,
|
if (!c->mon->isoverview || !config.ov_no_resize) {
|
||||||
c->geom.height - 2 * c->bw);
|
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++;
|
c->mon->resizing_count_pending++;
|
||||||
|
|
@ -1285,6 +1322,15 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
c->animainit_geom = c->geom;
|
c->animainit_geom = c->geom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.animations && config.ov_no_resize && c->mon->isoverview &&
|
||||||
|
c != c->mon->sel && c->animation.action == OVERVIEW) {
|
||||||
|
set_overview_enter_animation(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config.animations && config.ov_no_resize && c->mon->isoverview) {
|
||||||
|
c->animainit_geom = c->geom;
|
||||||
|
}
|
||||||
|
|
||||||
// 开始应用动画设置
|
// 开始应用动画设置
|
||||||
client_set_pending_state(c);
|
client_set_pending_state(c);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -252,10 +252,11 @@ typedef struct {
|
||||||
int32_t dwindle_manual_split;
|
int32_t dwindle_manual_split;
|
||||||
float dwindle_split_ratio;
|
float dwindle_split_ratio;
|
||||||
|
|
||||||
uint32_t hotarea_size;
|
int32_t hotarea_size;
|
||||||
uint32_t hotarea_corner;
|
int32_t hotarea_corner;
|
||||||
uint32_t enable_hotarea;
|
int32_t enable_hotarea;
|
||||||
uint32_t ov_tab_mode;
|
int32_t ov_tab_mode;
|
||||||
|
int32_t ov_no_resize;
|
||||||
int32_t overviewgappi;
|
int32_t overviewgappi;
|
||||||
int32_t overviewgappo;
|
int32_t overviewgappo;
|
||||||
uint32_t cursor_hide_timeout;
|
uint32_t cursor_hide_timeout;
|
||||||
|
|
@ -1655,6 +1656,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
config->enable_hotarea = atoi(value);
|
config->enable_hotarea = atoi(value);
|
||||||
} else if (strcmp(key, "ov_tab_mode") == 0) {
|
} else if (strcmp(key, "ov_tab_mode") == 0) {
|
||||||
config->ov_tab_mode = atoi(value);
|
config->ov_tab_mode = atoi(value);
|
||||||
|
} else if (strcmp(key, "ov_no_resize") == 0) {
|
||||||
|
config->ov_no_resize = atoi(value);
|
||||||
} else if (strcmp(key, "overviewgappi") == 0) {
|
} else if (strcmp(key, "overviewgappi") == 0) {
|
||||||
config->overviewgappi = atoi(value);
|
config->overviewgappi = atoi(value);
|
||||||
} else if (strcmp(key, "overviewgappo") == 0) {
|
} else if (strcmp(key, "overviewgappo") == 0) {
|
||||||
|
|
@ -3237,6 +3240,7 @@ void override_config(void) {
|
||||||
config.hotarea_corner = CLAMP_INT(config.hotarea_corner, 0, 3);
|
config.hotarea_corner = CLAMP_INT(config.hotarea_corner, 0, 3);
|
||||||
config.enable_hotarea = CLAMP_INT(config.enable_hotarea, 0, 1);
|
config.enable_hotarea = CLAMP_INT(config.enable_hotarea, 0, 1);
|
||||||
config.ov_tab_mode = CLAMP_INT(config.ov_tab_mode, 0, 1);
|
config.ov_tab_mode = CLAMP_INT(config.ov_tab_mode, 0, 1);
|
||||||
|
config.ov_no_resize = CLAMP_INT(config.ov_no_resize, 0, 1);
|
||||||
config.overviewgappi = CLAMP_INT(config.overviewgappi, 0, 1000);
|
config.overviewgappi = CLAMP_INT(config.overviewgappi, 0, 1000);
|
||||||
config.overviewgappo = CLAMP_INT(config.overviewgappo, 0, 1000);
|
config.overviewgappo = CLAMP_INT(config.overviewgappo, 0, 1000);
|
||||||
config.xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
config.xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
||||||
|
|
@ -3386,6 +3390,7 @@ void set_value_default() {
|
||||||
config.capslock = 0;
|
config.capslock = 0;
|
||||||
|
|
||||||
config.ov_tab_mode = 0;
|
config.ov_tab_mode = 0;
|
||||||
|
config.ov_no_resize = 0;
|
||||||
config.hotarea_size = 10;
|
config.hotarea_size = 10;
|
||||||
config.hotarea_corner = BOTTOM_LEFT;
|
config.hotarea_corner = BOTTOM_LEFT;
|
||||||
config.enable_hotarea = 1;
|
config.enable_hotarea = 1;
|
||||||
|
|
|
||||||
|
|
@ -1743,15 +1743,18 @@ int32_t toggleoverview(const Arg *arg) {
|
||||||
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c && c->mon == selmon && !client_is_unmanaged(c) &&
|
if (c && c->mon == selmon && !client_is_unmanaged(c) &&
|
||||||
!client_is_x11_popup(c) && !c->isunglobal)
|
!client_is_x11_popup(c) && !c->isunglobal) {
|
||||||
|
c->animation.overining = true;
|
||||||
overview_backup(c);
|
overview_backup(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c && c->mon == selmon && !c->iskilling &&
|
if (c && c->mon == selmon && !c->iskilling &&
|
||||||
!client_is_unmanaged(c) && !c->isunglobal &&
|
!client_is_unmanaged(c) && !c->isunglobal &&
|
||||||
!client_is_x11_popup(c) && client_surface(c)->mapped)
|
!client_is_x11_popup(c) && client_surface(c)->mapped) {
|
||||||
overview_restore(c, &(Arg){.ui = target});
|
overview_restore(c, &(Arg){.ui = target});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,19 @@ void get_layout_abbr(char *abbr, const char *full_name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Client *xytoclient(double x, double y) {
|
||||||
|
Client *c = NULL, *tmp = NULL;
|
||||||
|
wl_list_for_each_safe(c, tmp, &clients, link) {
|
||||||
|
if (VISIBLEON(c, c->mon) && c->animation.current.x <= x &&
|
||||||
|
c->animation.current.y <= y &&
|
||||||
|
c->animation.current.x + c->animation.current.width >= x &&
|
||||||
|
c->animation.current.y + c->animation.current.height >= y) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||||
LayerSurface **pl, double *nx, double *ny) {
|
LayerSurface **pl, double *nx, double *ny) {
|
||||||
struct wlr_scene_node *node, *pnode;
|
struct wlr_scene_node *node, *pnode;
|
||||||
|
|
@ -84,6 +97,7 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
LayerSurface *l = NULL;
|
LayerSurface *l = NULL;
|
||||||
int32_t layer;
|
int32_t layer;
|
||||||
|
Client *ovc = NULL;
|
||||||
|
|
||||||
for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
|
for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
|
||||||
|
|
||||||
|
|
@ -96,10 +110,16 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||||
if (!node->enabled)
|
if (!node->enabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (node->type == WLR_SCENE_NODE_BUFFER)
|
if (node->type == WLR_SCENE_NODE_BUFFER) {
|
||||||
surface = wlr_scene_surface_try_from_buffer(
|
struct wlr_scene_surface *scene_surface =
|
||||||
wlr_scene_buffer_from_node(node))
|
wlr_scene_surface_try_from_buffer(
|
||||||
->surface;
|
wlr_scene_buffer_from_node(node));
|
||||||
|
if (scene_surface) {
|
||||||
|
surface = scene_surface->surface;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* start from the topmost layer,
|
/* start from the topmost layer,
|
||||||
find a sureface that can be focused by pointer,
|
find a sureface that can be focused by pointer,
|
||||||
|
|
@ -130,4 +150,12 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||||
*pc = c;
|
*pc = c;
|
||||||
if (pl)
|
if (pl)
|
||||||
*pl = l;
|
*pl = l;
|
||||||
|
|
||||||
|
if (selmon && selmon->isoverview && !l) {
|
||||||
|
ovc = xytoclient(x, y);
|
||||||
|
if (pc)
|
||||||
|
*pc = ovc;
|
||||||
|
if (psurface && ovc)
|
||||||
|
*psurface = client_surface(ovc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,117 +1,3 @@
|
||||||
|
|
||||||
// 网格布局窗口大小和位置计算
|
|
||||||
void overview(Monitor *m) {
|
|
||||||
int32_t i, n;
|
|
||||||
int32_t cx, cy, cw, ch;
|
|
||||||
int32_t dx;
|
|
||||||
int32_t cols, rows, overcols;
|
|
||||||
Client *c = NULL;
|
|
||||||
n = 0;
|
|
||||||
int32_t target_gappo =
|
|
||||||
enablegaps ? m->isoverview ? config.overviewgappo : config.gappoh : 0;
|
|
||||||
int32_t target_gappi =
|
|
||||||
enablegaps ? m->isoverview ? config.overviewgappi : config.gappih : 0;
|
|
||||||
float single_width_ratio = m->isoverview ? 0.7 : 0.9;
|
|
||||||
float single_height_ratio = m->isoverview ? 0.8 : 0.9;
|
|
||||||
|
|
||||||
n = m->isoverview ? m->visible_clients : m->visible_tiling_clients;
|
|
||||||
|
|
||||||
if (n == 0) {
|
|
||||||
return; // 没有需要处理的客户端,直接返回
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n == 1) {
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
|
||||||
|
|
||||||
if (c->mon != m)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
|
||||||
((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) {
|
|
||||||
cw = (m->w.width - 2 * target_gappo) * single_width_ratio;
|
|
||||||
ch = (m->w.height - 2 * target_gappo) * single_height_ratio;
|
|
||||||
c->geom.x = m->w.x + (m->w.width - cw) / 2;
|
|
||||||
c->geom.y = m->w.y + (m->w.height - ch) / 2;
|
|
||||||
c->geom.width = cw;
|
|
||||||
c->geom.height = ch;
|
|
||||||
resize(c, c->geom, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n == 2) {
|
|
||||||
cw = (m->w.width - 2 * target_gappo - target_gappi) / 2;
|
|
||||||
ch = (m->w.height - 2 * target_gappo) * 0.65;
|
|
||||||
i = 0;
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
|
||||||
if (c->mon != m)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
|
||||||
((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) {
|
|
||||||
if (i == 0) {
|
|
||||||
c->geom.x = m->w.x + target_gappo;
|
|
||||||
c->geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
|
||||||
c->geom.width = cw;
|
|
||||||
c->geom.height = ch;
|
|
||||||
resize(c, c->geom, 0);
|
|
||||||
} else if (i == 1) {
|
|
||||||
c->geom.x = m->w.x + cw + target_gappo + target_gappi;
|
|
||||||
c->geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
|
||||||
c->geom.width = cw;
|
|
||||||
c->geom.height = ch;
|
|
||||||
resize(c, c->geom, 0);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算列数和行数
|
|
||||||
for (cols = 0; cols <= n / 2; cols++) {
|
|
||||||
if (cols * cols >= n) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols;
|
|
||||||
|
|
||||||
// 计算每个客户端的高度和宽度
|
|
||||||
ch = (m->w.height - 2 * target_gappo - (rows - 1) * target_gappi) / rows;
|
|
||||||
cw = (m->w.width - 2 * target_gappo - (cols - 1) * target_gappi) / cols;
|
|
||||||
|
|
||||||
// 处理多余的列
|
|
||||||
overcols = n % cols;
|
|
||||||
if (overcols) {
|
|
||||||
dx = (m->w.width - overcols * cw - (overcols - 1) * target_gappi) / 2 -
|
|
||||||
target_gappo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调整每个客户端的位置和大小
|
|
||||||
i = 0;
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
|
||||||
|
|
||||||
if (c->mon != m)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
|
||||||
((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) {
|
|
||||||
cx = m->w.x + (i % cols) * (cw + target_gappi);
|
|
||||||
cy = m->w.y + (i / cols) * (ch + target_gappi);
|
|
||||||
if (overcols && i >= n - overcols) {
|
|
||||||
cx += dx;
|
|
||||||
}
|
|
||||||
c->geom.x = cx + target_gappo;
|
|
||||||
c->geom.y = cy + target_gappo;
|
|
||||||
c->geom.width = cw;
|
|
||||||
c->geom.height = ch;
|
|
||||||
resize(c, c->geom, 0);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void deck(Monitor *m) {
|
void deck(Monitor *m) {
|
||||||
int32_t mw, my;
|
int32_t mw, my;
|
||||||
int32_t i, n = 0;
|
int32_t i, n = 0;
|
||||||
|
|
|
||||||
298
src/layout/overview.h
Normal file
298
src/layout/overview.h
Normal file
|
|
@ -0,0 +1,298 @@
|
||||||
|
void overview_scale(Monitor *m) {
|
||||||
|
int32_t target_gappo = config.overviewgappo;
|
||||||
|
int32_t target_gappi = config.overviewgappi;
|
||||||
|
|
||||||
|
int orig_n = m->visible_clients;
|
||||||
|
|
||||||
|
if (orig_n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t sz_c_arr = orig_n * sizeof(Client *);
|
||||||
|
size_t sz_aspects = orig_n * sizeof(float);
|
||||||
|
size_t sz_suffix_sums = (orig_n + 1) * sizeof(float);
|
||||||
|
size_t sz_best_items = orig_n * sizeof(int);
|
||||||
|
size_t sz_temp_items = orig_n * sizeof(int);
|
||||||
|
size_t sz_items = orig_n * sizeof(int);
|
||||||
|
size_t sz_A_sum = orig_n * sizeof(float);
|
||||||
|
|
||||||
|
size_t total_size = sz_c_arr + sz_aspects + sz_suffix_sums + sz_best_items +
|
||||||
|
sz_temp_items + sz_items + sz_A_sum;
|
||||||
|
|
||||||
|
void *buffer = malloc(total_size);
|
||||||
|
if (!buffer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client **c_arr = (Client **)buffer;
|
||||||
|
float *aspects = (float *)((char *)buffer + sz_c_arr);
|
||||||
|
float *suffix_sums = (float *)((char *)aspects + sz_aspects);
|
||||||
|
int *best_items_per_row = (int *)((char *)suffix_sums + sz_suffix_sums);
|
||||||
|
int *temp_items_per_row =
|
||||||
|
(int *)((char *)best_items_per_row + sz_best_items);
|
||||||
|
int *items_per_row = (int *)((char *)temp_items_per_row + sz_temp_items);
|
||||||
|
float *A_sum = (float *)((char *)items_per_row + sz_items);
|
||||||
|
|
||||||
|
int actual_n = 0;
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (c->mon != m)
|
||||||
|
continue;
|
||||||
|
if (VISIBLEON(c, m) && !c->isunglobal && !client_is_x11_popup(c)) {
|
||||||
|
|
||||||
|
c_arr[actual_n] = c;
|
||||||
|
float aspect = 1.0f;
|
||||||
|
if (c->overview_backup_geom.height > 0 &&
|
||||||
|
c->overview_backup_geom.width > 0) {
|
||||||
|
aspect = (float)c->overview_backup_geom.width /
|
||||||
|
c->overview_backup_geom.height;
|
||||||
|
}
|
||||||
|
if (aspect < 0.2f)
|
||||||
|
aspect = 0.2f;
|
||||||
|
if (aspect > 5.0f)
|
||||||
|
aspect = 5.0f;
|
||||||
|
|
||||||
|
aspects[actual_n] = aspect;
|
||||||
|
actual_n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = actual_n;
|
||||||
|
if (n == 0) {
|
||||||
|
free(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
suffix_sums[n] = 0.0f;
|
||||||
|
for (int i = n - 1; i >= 0; i--) {
|
||||||
|
suffix_sums[i] = suffix_sums[i + 1] + aspects[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
float max_avail_w = m->w.width - 2 * target_gappo;
|
||||||
|
float max_avail_h = m->w.height - 2 * target_gappo;
|
||||||
|
if (max_avail_w < 10)
|
||||||
|
max_avail_w = 10;
|
||||||
|
if (max_avail_h < 10)
|
||||||
|
max_avail_h = 10;
|
||||||
|
|
||||||
|
int best_rows = 1;
|
||||||
|
float best_row_height = 0.0f;
|
||||||
|
best_items_per_row[0] = n;
|
||||||
|
|
||||||
|
for (int R = 1; R <= n; R++) {
|
||||||
|
int start_idx = 0;
|
||||||
|
|
||||||
|
for (int r = 0; r < R; r++) {
|
||||||
|
int rows_left = R - r;
|
||||||
|
|
||||||
|
float S_rem = suffix_sums[start_idx];
|
||||||
|
float target_sum = S_rem / rows_left;
|
||||||
|
|
||||||
|
float current_sum = 0;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
while (start_idx + count < n - (rows_left - 1)) {
|
||||||
|
float next_val = aspects[start_idx + count];
|
||||||
|
if (rows_left == 1) {
|
||||||
|
current_sum += next_val;
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
float diff_without = fabs(current_sum - target_sum);
|
||||||
|
float diff_with = fabs(current_sum + next_val - target_sum);
|
||||||
|
if (diff_with > diff_without) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_sum += next_val;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
temp_items_per_row[r] = count;
|
||||||
|
start_idx += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
float min_h_max_w = 999999.0f;
|
||||||
|
start_idx = 0;
|
||||||
|
for (int r = 0; r < R; r++) {
|
||||||
|
float row_A_sum = suffix_sums[start_idx] -
|
||||||
|
suffix_sums[start_idx + temp_items_per_row[r]];
|
||||||
|
start_idx += temp_items_per_row[r];
|
||||||
|
|
||||||
|
float gap_x_total = (temp_items_per_row[r] - 1) * target_gappi;
|
||||||
|
float w_avail = max_avail_w - gap_x_total;
|
||||||
|
if (w_avail < 1)
|
||||||
|
w_avail = 1;
|
||||||
|
|
||||||
|
float h_limit = w_avail / row_A_sum;
|
||||||
|
if (h_limit < min_h_max_w) {
|
||||||
|
min_h_max_w = h_limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float gap_y_total_temp = (R - 1) * target_gappi;
|
||||||
|
float h_avail = max_avail_h - gap_y_total_temp;
|
||||||
|
if (h_avail < 1)
|
||||||
|
h_avail = 1;
|
||||||
|
|
||||||
|
float h_max_h = h_avail / R;
|
||||||
|
float final_h = min_h_max_w < h_max_h ? min_h_max_w : h_max_h;
|
||||||
|
|
||||||
|
if (final_h > best_row_height) {
|
||||||
|
best_row_height = final_h;
|
||||||
|
best_rows = R;
|
||||||
|
for (int r = 0; r < R; r++) {
|
||||||
|
best_items_per_row[r] = temp_items_per_row[r];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rows = best_rows;
|
||||||
|
float row_height = best_row_height;
|
||||||
|
|
||||||
|
int current_render_idx = 0;
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
items_per_row[r] = best_items_per_row[r];
|
||||||
|
A_sum[r] = suffix_sums[current_render_idx] -
|
||||||
|
suffix_sums[current_render_idx + items_per_row[r]];
|
||||||
|
current_render_idx += items_per_row[r];
|
||||||
|
}
|
||||||
|
|
||||||
|
float gap_y_total = (rows - 1) * target_gappi;
|
||||||
|
float total_layout_height = rows * row_height + gap_y_total;
|
||||||
|
float start_y = m->w.y + (m->w.height - total_layout_height) / 2.0f;
|
||||||
|
|
||||||
|
int current_idx = 0;
|
||||||
|
float current_y = start_y;
|
||||||
|
|
||||||
|
for (int r = 0; r < rows; r++) {
|
||||||
|
float row_width =
|
||||||
|
row_height * A_sum[r] + (items_per_row[r] - 1) * target_gappi;
|
||||||
|
float current_x = m->w.x + (m->w.width - row_width) / 2.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < items_per_row[r]; i++) {
|
||||||
|
Client *client = c_arr[current_idx];
|
||||||
|
float aspect = aspects[current_idx];
|
||||||
|
float client_width = row_height * aspect;
|
||||||
|
|
||||||
|
struct wlr_box client_geom;
|
||||||
|
client_geom.x = (int)(current_x + 0.5f);
|
||||||
|
client_geom.y = (int)(current_y + 0.5f);
|
||||||
|
|
||||||
|
float next_x = current_x + client_width;
|
||||||
|
client_geom.width = (int)(next_x + 0.5f) - client_geom.x;
|
||||||
|
|
||||||
|
float next_y = current_y + row_height;
|
||||||
|
client_geom.height = (int)(next_y + 0.5f) - client_geom.y;
|
||||||
|
|
||||||
|
resize(client, client_geom, 0);
|
||||||
|
|
||||||
|
current_x = next_x + target_gappi;
|
||||||
|
current_idx++;
|
||||||
|
}
|
||||||
|
current_y += row_height + target_gappi;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void overview_resize(Monitor *m) {
|
||||||
|
int32_t i, n;
|
||||||
|
int32_t cx, cy, cw, ch;
|
||||||
|
int32_t dx;
|
||||||
|
int32_t cols, rows, overcols;
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
|
int32_t target_gappo = config.overviewgappo;
|
||||||
|
int32_t target_gappi = config.overviewgappi;
|
||||||
|
float single_width_ratio = 0.7;
|
||||||
|
float single_height_ratio = 0.8;
|
||||||
|
|
||||||
|
n = m->visible_clients;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (c->mon != m)
|
||||||
|
continue;
|
||||||
|
if (VISIBLEON(c, m) && !c->isunglobal && !client_is_x11_popup(c)) {
|
||||||
|
cw = (m->w.width - 2 * target_gappo) * single_width_ratio;
|
||||||
|
ch = (m->w.height - 2 * target_gappo) * single_height_ratio;
|
||||||
|
c->geom.x = m->w.x + (m->w.width - cw) / 2;
|
||||||
|
c->geom.y = m->w.y + (m->w.height - ch) / 2;
|
||||||
|
c->geom.width = cw;
|
||||||
|
c->geom.height = ch;
|
||||||
|
resize(c, c->geom, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 2) {
|
||||||
|
cw = (m->w.width - 2 * target_gappo - target_gappi) / 2;
|
||||||
|
ch = (m->w.height - 2 * target_gappo) * 0.65;
|
||||||
|
i = 0;
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (c->mon != m)
|
||||||
|
continue;
|
||||||
|
if (VISIBLEON(c, m) && !c->isunglobal && !client_is_x11_popup(c)) {
|
||||||
|
if (i == 0) {
|
||||||
|
c->geom.x = m->w.x + target_gappo;
|
||||||
|
c->geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||||
|
} else if (i == 1) {
|
||||||
|
c->geom.x = m->w.x + cw + target_gappo + target_gappi;
|
||||||
|
c->geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||||
|
}
|
||||||
|
c->geom.width = cw;
|
||||||
|
c->geom.height = ch;
|
||||||
|
resize(c, c->geom, 0);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cols = 0; cols <= n / 2; cols++) {
|
||||||
|
if (cols * cols >= n)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols;
|
||||||
|
|
||||||
|
ch = (m->w.height - 2 * target_gappo - (rows - 1) * target_gappi) / rows;
|
||||||
|
cw = (m->w.width - 2 * target_gappo - (cols - 1) * target_gappi) / cols;
|
||||||
|
|
||||||
|
overcols = n % cols;
|
||||||
|
if (overcols) {
|
||||||
|
dx = (m->w.width - overcols * cw - (overcols - 1) * target_gappi) / 2 -
|
||||||
|
target_gappo;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (c->mon != m)
|
||||||
|
continue;
|
||||||
|
if (VISIBLEON(c, m) && !c->isunglobal && !client_is_x11_popup(c)) {
|
||||||
|
cx = m->w.x + (i % cols) * (cw + target_gappi);
|
||||||
|
cy = m->w.y + (i / cols) * (ch + target_gappi);
|
||||||
|
if (overcols && i >= n - overcols)
|
||||||
|
cx += dx;
|
||||||
|
c->geom.x = cx + target_gappo;
|
||||||
|
c->geom.y = cy + target_gappo;
|
||||||
|
c->geom.width = cw;
|
||||||
|
c->geom.height = ch;
|
||||||
|
resize(c, c->geom, 0);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void overview(Monitor *m) {
|
||||||
|
if (config.ov_no_resize) {
|
||||||
|
overview_scale(m);
|
||||||
|
} else {
|
||||||
|
overview_resize(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/mango.c
44
src/mango.c
|
|
@ -175,7 +175,7 @@ enum {
|
||||||
}; /* EWMH atoms */
|
}; /* EWMH atoms */
|
||||||
#endif
|
#endif
|
||||||
enum { UP, DOWN, LEFT, RIGHT, UNDIR }; /* smartmovewin */
|
enum { UP, DOWN, LEFT, RIGHT, UNDIR }; /* smartmovewin */
|
||||||
enum { NONE, OPEN, MOVE, CLOSE, TAG, FOCUS, OPAFADEIN, OPAFADEOUT };
|
enum { NONE, OPEN, MOVE, CLOSE, TAG, FOCUS, OPAFADEIN, OPAFADEOUT, OVERVIEW };
|
||||||
enum { UNFOLD, FOLD, INVALIDFOLD };
|
enum { UNFOLD, FOLD, INVALIDFOLD };
|
||||||
enum { PREV, NEXT };
|
enum { PREV, NEXT };
|
||||||
enum { STATE_UNSPECIFIED = 0, STATE_ENABLED, STATE_DISABLED };
|
enum { STATE_UNSPECIFIED = 0, STATE_ENABLED, STATE_DISABLED };
|
||||||
|
|
@ -279,6 +279,7 @@ struct dwl_animation {
|
||||||
bool tagouting;
|
bool tagouting;
|
||||||
bool begin_fade_in;
|
bool begin_fade_in;
|
||||||
bool tag_from_rule;
|
bool tag_from_rule;
|
||||||
|
bool overining;
|
||||||
uint32_t time_started;
|
uint32_t time_started;
|
||||||
uint32_t duration;
|
uint32_t duration;
|
||||||
struct wlr_box initial;
|
struct wlr_box initial;
|
||||||
|
|
@ -320,6 +321,7 @@ struct Client {
|
||||||
struct wlr_scene_rect *splitindicator[4];
|
struct wlr_scene_rect *splitindicator[4];
|
||||||
struct wlr_scene_shadow *shadow;
|
struct wlr_scene_shadow *shadow;
|
||||||
struct wlr_scene_tree *scene_surface;
|
struct wlr_scene_tree *scene_surface;
|
||||||
|
struct wlr_scene_tree *overview_scene_surface;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_list flink;
|
struct wl_list flink;
|
||||||
struct wl_list fadeout_link;
|
struct wl_list fadeout_link;
|
||||||
|
|
@ -873,6 +875,7 @@ scroller_node_create(struct TagScrollerState *st, Client *c);
|
||||||
static void update_scroller_state(Monitor *m);
|
static void update_scroller_state(Monitor *m);
|
||||||
Client *scroll_get_stack_tail_client(Client *c);
|
Client *scroll_get_stack_tail_client(Client *c);
|
||||||
static DwindleNode *dwindle_find_leaf(DwindleNode *node, Client *c);
|
static DwindleNode *dwindle_find_leaf(DwindleNode *node, Client *c);
|
||||||
|
static void overview_backup_surface(Client *c);
|
||||||
|
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/bind_declare.h"
|
#include "dispatch/bind_declare.h"
|
||||||
|
|
@ -1078,6 +1081,7 @@ static struct wl_event_source *sync_keymap;
|
||||||
#include "layout/arrange.h"
|
#include "layout/arrange.h"
|
||||||
#include "layout/dwindle.h"
|
#include "layout/dwindle.h"
|
||||||
#include "layout/horizontal.h"
|
#include "layout/horizontal.h"
|
||||||
|
#include "layout/overview.h"
|
||||||
#include "layout/scroll.h"
|
#include "layout/scroll.h"
|
||||||
#include "layout/vertical.h"
|
#include "layout/vertical.h"
|
||||||
|
|
||||||
|
|
@ -4279,6 +4283,7 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx,
|
||||||
void init_client_properties(Client *c) {
|
void init_client_properties(Client *c) {
|
||||||
c->grid_col_per = 1.0f;
|
c->grid_col_per = 1.0f;
|
||||||
c->grid_row_per = 1.0f;
|
c->grid_row_per = 1.0f;
|
||||||
|
c->overview_scene_surface = NULL;
|
||||||
c->drop_direction = UNDIR;
|
c->drop_direction = UNDIR;
|
||||||
c->enable_drop_area_draw = false;
|
c->enable_drop_area_draw = false;
|
||||||
c->isfocusing = false;
|
c->isfocusing = false;
|
||||||
|
|
@ -4399,6 +4404,7 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
// init client geom
|
// init client geom
|
||||||
c->geom.width += 2 * c->bw;
|
c->geom.width += 2 * c->bw;
|
||||||
c->geom.height += 2 * c->bw;
|
c->geom.height += 2 * c->bw;
|
||||||
|
c->overview_backup_geom = c->geom;
|
||||||
|
|
||||||
/* Handle unmanaged clients first so we can return prior create borders
|
/* Handle unmanaged clients first so we can return prior create borders
|
||||||
*/
|
*/
|
||||||
|
|
@ -4484,10 +4490,15 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
// apply buffer effects of client
|
// apply buffer effects of client
|
||||||
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
|
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
|
||||||
iter_xdg_scene_buffers, c);
|
iter_xdg_scene_buffers, c);
|
||||||
|
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
||||||
|
|
||||||
// set border color
|
// set border color
|
||||||
setborder_color(c);
|
setborder_color(c);
|
||||||
|
|
||||||
|
if (c->mon->isoverview && config.ov_no_resize) {
|
||||||
|
overview_backup_surface(c);
|
||||||
|
}
|
||||||
|
|
||||||
// make sure the animation is open type
|
// make sure the animation is open type
|
||||||
c->is_pending_open_animation = true;
|
c->is_pending_open_animation = true;
|
||||||
resize(c, c->geom, 0);
|
resize(c, c->geom, 0);
|
||||||
|
|
@ -4854,7 +4865,8 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
||||||
|
|
||||||
if (config.sloppyfocus && !start_drag_window && c && time && c->scene &&
|
if (config.sloppyfocus && !start_drag_window && c && time && c->scene &&
|
||||||
c->scene->node.enabled && !c->animation.tagining &&
|
c->scene->node.enabled && !c->animation.tagining &&
|
||||||
(surface != seat->pointer_state.focused_surface) &&
|
(surface != seat->pointer_state.focused_surface ||
|
||||||
|
(selmon && selmon->isoverview && selmon->sel != c)) &&
|
||||||
!client_is_unmanaged(c) && VISIBLEON(c, c->mon))
|
!client_is_unmanaged(c) && VISIBLEON(c, c->mon))
|
||||||
focusclient(c, 0);
|
focusclient(c, 0);
|
||||||
|
|
||||||
|
|
@ -6061,6 +6073,23 @@ uint32_t want_restore_fullscreen(Client *target_client) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void overview_backup_surface(Client *c) {
|
||||||
|
struct wlr_box clip_box;
|
||||||
|
clip_box.x = 0;
|
||||||
|
clip_box.y = 0;
|
||||||
|
clip_box.width = c->geom.width - 2 * config.borderpx;
|
||||||
|
clip_box.height = c->geom.height - 2 * config.borderpx;
|
||||||
|
|
||||||
|
c->overview_scene_surface = c->scene_surface;
|
||||||
|
wlr_scene_node_set_enabled(&c->scene_surface->node, true);
|
||||||
|
wlr_scene_node_set_position(&c->scene_surface->node, 0, 0);
|
||||||
|
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box);
|
||||||
|
c->scene_surface =
|
||||||
|
wlr_scene_tree_snapshot(&c->scene_surface->node, c->scene);
|
||||||
|
wlr_scene_node_set_enabled(&c->overview_scene_surface->node, false);
|
||||||
|
wlr_scene_node_set_enabled(&c->scene_surface->node, true);
|
||||||
|
}
|
||||||
|
|
||||||
// 普通视图切换到overview时保存窗口的旧状态
|
// 普通视图切换到overview时保存窗口的旧状态
|
||||||
void overview_backup(Client *c) {
|
void overview_backup(Client *c) {
|
||||||
c->overview_isfloatingbak = c->isfloating;
|
c->overview_isfloatingbak = c->isfloating;
|
||||||
|
|
@ -6075,6 +6104,11 @@ void overview_backup(Client *c) {
|
||||||
if (c->isfloating) {
|
if (c->isfloating) {
|
||||||
c->isfloating = 0;
|
c->isfloating = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.ov_no_resize) {
|
||||||
|
overview_backup_surface(c);
|
||||||
|
}
|
||||||
|
|
||||||
if (c->isfullscreen || c->ismaximizescreen) {
|
if (c->isfullscreen || c->ismaximizescreen) {
|
||||||
client_pending_fullscreen_state(c, 0); // 清除窗口全屏标志
|
client_pending_fullscreen_state(c, 0); // 清除窗口全屏标志
|
||||||
client_pending_maximized_state(c, 0);
|
client_pending_maximized_state(c, 0);
|
||||||
|
|
@ -6098,6 +6132,12 @@ void overview_restore(Client *c, const Arg *arg) {
|
||||||
c->animation.tagining = false;
|
c->animation.tagining = false;
|
||||||
c->is_restoring_from_ov = (arg->ui & c->tags & TAGMASK) == 0 ? true : false;
|
c->is_restoring_from_ov = (arg->ui & c->tags & TAGMASK) == 0 ? true : false;
|
||||||
|
|
||||||
|
if (c->overview_scene_surface) {
|
||||||
|
wlr_scene_node_destroy(&c->scene_surface->node);
|
||||||
|
c->scene_surface = c->overview_scene_surface;
|
||||||
|
c->overview_scene_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (c->isfloating) {
|
if (c->isfloating) {
|
||||||
// XRaiseWindow(dpy, c->win); // 提升悬浮窗口到顶层
|
// XRaiseWindow(dpy, c->win); // 提升悬浮窗口到顶层
|
||||||
resize(c, c->overview_backup_geom, 0);
|
resize(c, c->overview_backup_geom, 0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue