mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-03 06:46:38 -04:00
Merge branch 'mangowm:main' into main
This commit is contained in:
commit
76ad12e51c
13 changed files with 621 additions and 117 deletions
|
|
@ -294,9 +294,8 @@ static inline uint32_t client_set_size(Client *c, uint32_t width,
|
|||
uint32_t height) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
|
||||
struct wlr_surface_state *state =
|
||||
&c->surface.xwayland->surface->current;
|
||||
struct wlr_xwayland_surface *surface = c->surface.xwayland;
|
||||
struct wlr_surface_state *state = &surface->surface->current;
|
||||
|
||||
if ((int32_t)c->geom.width - 2 * (int32_t)c->bw ==
|
||||
(int32_t)state->width &&
|
||||
|
|
@ -309,6 +308,22 @@ static inline uint32_t client_set_size(Client *c, uint32_t width,
|
|||
return 0;
|
||||
}
|
||||
|
||||
xcb_size_hints_t *size_hints = surface->size_hints;
|
||||
int32_t width = c->geom.width - 2 * c->bw;
|
||||
int32_t height = c->geom.height - 2 * c->bw;
|
||||
|
||||
if (c->mon && c->mon->isoverview && size_hints &&
|
||||
c->geom.width - 2 * (int32_t)c->bw < size_hints->min_width &&
|
||||
c->geom.height - 2 * (int32_t)c->bw < size_hints->min_height)
|
||||
return 0;
|
||||
|
||||
if (size_hints &&
|
||||
c->geom.width - 2 * (int32_t)c->bw < size_hints->min_width)
|
||||
width = size_hints->min_width;
|
||||
if (size_hints &&
|
||||
c->geom.height - 2 * (int32_t)c->bw < size_hints->min_height)
|
||||
height = size_hints->min_height;
|
||||
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw,
|
||||
c->geom.y + c->bw, width, height);
|
||||
return 1;
|
||||
|
|
@ -350,7 +365,7 @@ static inline void client_set_maximized(Client *c, bool maximized) {
|
|||
static inline void client_set_tiled(Client *c, uint32_t edges) {
|
||||
struct wlr_xdg_toplevel *toplevel;
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c) && c->force_maximize) {
|
||||
if (client_is_x11(c) && c->force_fakemaximize) {
|
||||
wlr_xwayland_surface_set_maximized(c->surface.xwayland,
|
||||
edges != WLR_EDGE_NONE,
|
||||
edges != WLR_EDGE_NONE);
|
||||
|
|
@ -365,7 +380,7 @@ static inline void client_set_tiled(Client *c, uint32_t edges) {
|
|||
wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges);
|
||||
}
|
||||
|
||||
if (c->force_maximize) {
|
||||
if (c->force_fakemaximize) {
|
||||
wlr_xdg_toplevel_set_maximized(toplevel, edges != WLR_EDGE_NONE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ typedef struct {
|
|||
int32_t no_force_center;
|
||||
int32_t isterm;
|
||||
int32_t allow_csd;
|
||||
int32_t force_maximize;
|
||||
int32_t force_fakemaximize;
|
||||
int32_t force_tiled_state;
|
||||
int32_t force_tearing;
|
||||
int32_t noswallow;
|
||||
|
|
@ -2059,7 +2059,7 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
rule->indleinhibit_when_focus = -1;
|
||||
rule->isterm = -1;
|
||||
rule->allow_csd = -1;
|
||||
rule->force_maximize = -1;
|
||||
rule->force_fakemaximize = -1;
|
||||
rule->force_tiled_state = -1;
|
||||
rule->force_tearing = -1;
|
||||
rule->noswallow = -1;
|
||||
|
|
@ -2173,8 +2173,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
rule->isterm = atoi(val);
|
||||
} else if (strcmp(key, "allow_csd") == 0) {
|
||||
rule->allow_csd = atoi(val);
|
||||
} else if (strcmp(key, "force_maximize") == 0) {
|
||||
rule->force_maximize = atoi(val);
|
||||
} else if (strcmp(key, "force_fakemaximize") == 0) {
|
||||
rule->force_fakemaximize = atoi(val);
|
||||
} else if (strcmp(key, "force_tiled_state") == 0) {
|
||||
rule->force_tiled_state = atoi(val);
|
||||
} else if (strcmp(key, "force_tearing") == 0) {
|
||||
|
|
@ -3214,7 +3214,7 @@ void override_config(void) {
|
|||
config.accel_profile = CLAMP_INT(config.accel_profile, 0, 2);
|
||||
config.accel_speed = CLAMP_FLOAT(config.accel_speed, -1.0f, 1.0f);
|
||||
config.scroll_method = CLAMP_INT(config.scroll_method, 0, 4);
|
||||
config.scroll_button = CLAMP_INT(config.scroll_button, 272, 276);
|
||||
config.scroll_button = CLAMP_INT(config.scroll_button, 272, 279);
|
||||
config.click_method = CLAMP_INT(config.click_method, 0, 2);
|
||||
config.send_events_mode = CLAMP_INT(config.send_events_mode, 0, 2);
|
||||
config.button_map = CLAMP_INT(config.button_map, 0, 1);
|
||||
|
|
@ -3264,7 +3264,7 @@ void set_value_default() {
|
|||
config.animation_fade_in = 1;
|
||||
config.animation_fade_out = 1;
|
||||
config.tag_animation_direction = HORIZONTAL;
|
||||
config.zoom_initial_ratio = 0.3f;
|
||||
config.zoom_initial_ratio = 0.4f;
|
||||
config.zoom_end_ratio = 0.8f;
|
||||
config.fadein_begin_opacity = 0.5f;
|
||||
config.fadeout_begin_opacity = 0.5f;
|
||||
|
|
|
|||
|
|
@ -380,7 +380,11 @@ int32_t moveresize(const Arg *arg) {
|
|||
/* Float the window and tell motionnotify to grab it */
|
||||
if (grabc->isfloating == 0 && arg->ui == CurMove) {
|
||||
grabc->drag_to_tile = true;
|
||||
exit_scroller_stack(grabc);
|
||||
setfloating(grabc, 1);
|
||||
grabc->old_stack_inner_per = 0.0f;
|
||||
grabc->old_master_inner_per = 0.0f;
|
||||
set_size_per(grabc->mon, grabc);
|
||||
}
|
||||
|
||||
switch (cursor_mode = arg->ui) {
|
||||
|
|
@ -552,7 +556,7 @@ int32_t restore_minimized(const Arg *arg) {
|
|||
|
||||
if (selmon && selmon->sel && selmon->sel->is_in_scratchpad &&
|
||||
selmon->sel->is_scratchpad_show) {
|
||||
selmon->sel->isminimized = 0;
|
||||
client_pending_minimized_state(selmon->sel, 0);
|
||||
selmon->sel->is_scratchpad_show = 0;
|
||||
selmon->sel->is_in_scratchpad = 0;
|
||||
selmon->sel->isnamedscratchpad = 0;
|
||||
|
|
@ -863,7 +867,6 @@ int32_t spawn_shell(const Arg *arg) {
|
|||
}
|
||||
|
||||
int32_t spawn(const Arg *arg) {
|
||||
|
||||
if (!arg->v)
|
||||
return 0;
|
||||
|
||||
|
|
@ -876,28 +879,21 @@ int32_t spawn(const Arg *arg) {
|
|||
dup2(STDERR_FILENO, STDOUT_FILENO);
|
||||
setsid();
|
||||
|
||||
// 2. 解析参数
|
||||
char *argv[64];
|
||||
int32_t argc = 0;
|
||||
char *token = strtok((char *)arg->v, " ");
|
||||
while (token != NULL && argc < 63) {
|
||||
wordexp_t p;
|
||||
if (wordexp(token, &p, 0) == 0) {
|
||||
argv[argc++] = p.we_wordv[0];
|
||||
} else {
|
||||
argv[argc++] = token;
|
||||
}
|
||||
token = strtok(NULL, " ");
|
||||
// 2. 对整个参数字符串进行单词展开
|
||||
wordexp_t p;
|
||||
if (wordexp(arg->v, &p, 0) != 0) {
|
||||
wlr_log(WLR_DEBUG, "mango: wordexp failed for '%s'\n", arg->v);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
|
||||
// 3. 执行命令
|
||||
execvp(argv[0], argv);
|
||||
// 3. 执行命令(p.we_wordv 已经是 argv 数组)
|
||||
execvp(p.we_wordv[0], p.we_wordv);
|
||||
|
||||
// 4. execvp 失败时:打印错误并直接退出(避免 coredump)
|
||||
wlr_log(WLR_DEBUG, "mango: execvp '%s' failed: %s\n", argv[0],
|
||||
// 4. execvp 失败时:打印错误,释放 wordexp 资源,然后退出
|
||||
wlr_log(WLR_DEBUG, "mango: execvp '%s' failed: %s\n", p.we_wordv[0],
|
||||
strerror(errno));
|
||||
_exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作
|
||||
wordfree(&p); // 释放 wordexp 分配的内存
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
91
src/mango.c
91
src/mango.c
|
|
@ -391,7 +391,7 @@ struct Client {
|
|||
struct dwl_opacity_animation opacity_animation;
|
||||
int32_t isterm, noswallow;
|
||||
int32_t allow_csd;
|
||||
int32_t force_maximize;
|
||||
int32_t force_fakemaximize;
|
||||
int32_t force_tiled_state;
|
||||
pid_t pid;
|
||||
Client *swallowing, *swallowedby;
|
||||
|
|
@ -807,6 +807,10 @@ 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);
|
||||
static void client_pending_fullscreen_state(Client *c, int32_t isfullscreen);
|
||||
static void client_pending_maximized_state(Client *c, int32_t ismaximized);
|
||||
static void client_pending_minimized_state(Client *c, int32_t isminimized);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
#include "dispatch/bind_declare.h"
|
||||
#include "layout/layout.h"
|
||||
|
|
@ -1064,11 +1068,33 @@ void clear_fullscreen_flag(Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
void client_pending_fullscreen_state(Client *c, int32_t isfullscreen) {
|
||||
c->isfullscreen = isfullscreen;
|
||||
|
||||
if (c->foreign_toplevel && !c->iskilling)
|
||||
wlr_foreign_toplevel_handle_v1_set_fullscreen(c->foreign_toplevel,
|
||||
isfullscreen);
|
||||
}
|
||||
|
||||
void client_pending_maximized_state(Client *c, int32_t ismaximized) {
|
||||
c->ismaximizescreen = ismaximized;
|
||||
if (c->foreign_toplevel && !c->iskilling)
|
||||
wlr_foreign_toplevel_handle_v1_set_maximized(c->foreign_toplevel,
|
||||
ismaximized);
|
||||
}
|
||||
|
||||
void client_pending_minimized_state(Client *c, int32_t isminimized) {
|
||||
c->isminimized = isminimized;
|
||||
if (c->foreign_toplevel && !c->iskilling)
|
||||
wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel,
|
||||
isminimized);
|
||||
}
|
||||
|
||||
void show_scratchpad(Client *c) {
|
||||
c->is_scratchpad_show = 1;
|
||||
if (c->isfullscreen || c->ismaximizescreen) {
|
||||
c->isfullscreen = 0; // 清除窗口全屏标志
|
||||
c->ismaximizescreen = 0;
|
||||
client_pending_fullscreen_state(c, 0);
|
||||
client_pending_maximized_state(c, 0);
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
}
|
||||
|
||||
|
|
@ -1107,9 +1133,6 @@ void swallow(Client *c, Client *w) {
|
|||
c->bw = w->bw;
|
||||
c->isfloating = w->isfloating;
|
||||
c->isurgent = w->isurgent;
|
||||
c->isfullscreen = w->isfullscreen;
|
||||
c->ismaximizescreen = w->ismaximizescreen;
|
||||
c->isminimized = w->isminimized;
|
||||
c->is_in_scratchpad = w->is_in_scratchpad;
|
||||
c->is_scratchpad_show = w->is_scratchpad_show;
|
||||
c->tags = w->tags;
|
||||
|
|
@ -1121,6 +1144,7 @@ void swallow(Client *c, Client *w) {
|
|||
c->scroller_proportion = w->scroller_proportion;
|
||||
c->next_in_stack = w->next_in_stack;
|
||||
c->prev_in_stack = w->prev_in_stack;
|
||||
|
||||
if (w->next_in_stack)
|
||||
w->next_in_stack->prev_in_stack = c;
|
||||
if (w->prev_in_stack)
|
||||
|
|
@ -1139,11 +1163,9 @@ void swallow(Client *c, Client *w) {
|
|||
if (!c->foreign_toplevel && c->mon)
|
||||
add_foreign_toplevel(c);
|
||||
|
||||
if (c->isminimized && c->foreign_toplevel) {
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel,
|
||||
false);
|
||||
wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true);
|
||||
}
|
||||
client_pending_fullscreen_state(c, w->isfullscreen);
|
||||
client_pending_maximized_state(c, w->ismaximizescreen);
|
||||
client_pending_minimized_state(c, w->isminimized);
|
||||
}
|
||||
|
||||
bool switch_scratchpad_client_state(Client *c) {
|
||||
|
|
@ -1326,7 +1348,7 @@ void toggle_hotarea(int32_t x_root, int32_t y_root) {
|
|||
static void apply_rule_properties(Client *c, const ConfigWinRule *r) {
|
||||
APPLY_INT_PROP(c, r, isterm);
|
||||
APPLY_INT_PROP(c, r, allow_csd);
|
||||
APPLY_INT_PROP(c, r, force_maximize);
|
||||
APPLY_INT_PROP(c, r, force_fakemaximize);
|
||||
APPLY_INT_PROP(c, r, force_tiled_state);
|
||||
APPLY_INT_PROP(c, r, force_tearing);
|
||||
APPLY_INT_PROP(c, r, noswallow);
|
||||
|
|
@ -4081,7 +4103,7 @@ void init_client_properties(Client *c) {
|
|||
c->old_master_mfact_per = 0.0f;
|
||||
c->isterm = 0;
|
||||
c->allow_csd = 0;
|
||||
c->force_maximize = 0;
|
||||
c->force_fakemaximize = 0;
|
||||
c->force_tiled_state = 1;
|
||||
c->force_tearing = 0;
|
||||
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||
|
|
@ -4239,7 +4261,7 @@ void maximizenotify(struct wl_listener *listener, void *data) {
|
|||
|
||||
void unminimize(Client *c) {
|
||||
if (c && c->is_in_scratchpad && c->is_scratchpad_show) {
|
||||
c->isminimized = 0;
|
||||
client_pending_minimized_state(c, 0);
|
||||
c->is_scratchpad_show = 0;
|
||||
c->is_in_scratchpad = 0;
|
||||
c->isnamedscratchpad = 0;
|
||||
|
|
@ -4267,13 +4289,12 @@ void set_minimized(Client *c) {
|
|||
c->oldtags = c->mon->tagset[c->mon->seltags];
|
||||
c->mini_restore_tag = c->tags;
|
||||
c->tags = 0;
|
||||
c->isminimized = 1;
|
||||
client_pending_minimized_state(c, 1);
|
||||
c->is_in_scratchpad = 1;
|
||||
c->is_scratchpad_show = 0;
|
||||
focusclient(focustop(selmon), 1);
|
||||
arrange(c->mon, false, false);
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false);
|
||||
wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true);
|
||||
wl_list_remove(&c->link); // 从原来位置移除
|
||||
wl_list_insert(clients.prev, &c->link); // 插入尾部
|
||||
}
|
||||
|
|
@ -5050,11 +5071,11 @@ setfloating(Client *c, int32_t floating) {
|
|||
if (floating == 1 && c != grabc) {
|
||||
|
||||
if (c->isfullscreen) {
|
||||
c->isfullscreen = 0;
|
||||
client_pending_fullscreen_state(c, 0);
|
||||
client_set_fullscreen(c, 0);
|
||||
}
|
||||
|
||||
c->ismaximizescreen = 0;
|
||||
client_pending_maximized_state(c, 0);
|
||||
exit_scroller_stack(c);
|
||||
|
||||
// 重新计算居中的坐标
|
||||
|
|
@ -5120,7 +5141,7 @@ setfloating(Client *c, int32_t floating) {
|
|||
save_old_size_per(c->mon);
|
||||
}
|
||||
|
||||
if (!c->force_maximize)
|
||||
if (!c->force_fakemaximize)
|
||||
client_set_maximized(c, false);
|
||||
|
||||
if (!c->isfloating || c->force_tiled_state) {
|
||||
|
|
@ -5179,12 +5200,12 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
|||
return;
|
||||
|
||||
int32_t old_maximizescreen_state = c->ismaximizescreen;
|
||||
c->ismaximizescreen = maximizescreen;
|
||||
client_pending_maximized_state(c, maximizescreen);
|
||||
|
||||
if (maximizescreen) {
|
||||
|
||||
if (c->isfullscreen) {
|
||||
c->isfullscreen = 0;
|
||||
client_pending_fullscreen_state(c, 0);
|
||||
client_set_fullscreen(c, 0);
|
||||
}
|
||||
|
||||
|
|
@ -5197,10 +5218,8 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
|||
wlr_scene_node_raise_to_top(&c->scene->node);
|
||||
if (!is_scroller_layout(c->mon) || c->isfloating)
|
||||
resize(c, maximizescreen_box, 0);
|
||||
c->ismaximizescreen = 1;
|
||||
} else {
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
c->ismaximizescreen = 0;
|
||||
if (c->isfloating)
|
||||
setfloating(c, 1);
|
||||
}
|
||||
|
|
@ -5215,9 +5234,9 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
|||
save_old_size_per(c->mon);
|
||||
}
|
||||
|
||||
if (!c->force_maximize && !c->ismaximizescreen) {
|
||||
if (!c->force_fakemaximize && !c->ismaximizescreen) {
|
||||
client_set_maximized(c, false);
|
||||
} else if (!c->force_maximize && c->ismaximizescreen) {
|
||||
} else if (!c->force_fakemaximize && c->ismaximizescreen) {
|
||||
client_set_maximized(c, true);
|
||||
}
|
||||
|
||||
|
|
@ -5248,14 +5267,15 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
|
|||
c->isfullscreen = fullscreen;
|
||||
|
||||
client_set_fullscreen(c, fullscreen);
|
||||
client_pending_fullscreen_state(c, fullscreen);
|
||||
|
||||
if (fullscreen) {
|
||||
|
||||
if (c->ismaximizescreen && !c->force_maximize) {
|
||||
if (c->ismaximizescreen && !c->force_fakemaximize) {
|
||||
client_set_maximized(c, false);
|
||||
}
|
||||
|
||||
c->ismaximizescreen = 0;
|
||||
client_pending_maximized_state(c, 0);
|
||||
|
||||
exit_scroller_stack(c);
|
||||
c->isfakefullscreen = 0;
|
||||
|
|
@ -5264,10 +5284,8 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
|
|||
wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层
|
||||
if (!is_scroller_layout(c->mon) || c->isfloating)
|
||||
resize(c, c->mon->m, 1);
|
||||
c->isfullscreen = 1;
|
||||
} else {
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
c->isfullscreen = 0;
|
||||
if (c->isfloating)
|
||||
setfloating(c, 1);
|
||||
}
|
||||
|
|
@ -5459,8 +5477,7 @@ void show_hide_client(Client *c) {
|
|||
c->tags = c->oldtags;
|
||||
arrange(c->mon, false, false);
|
||||
}
|
||||
c->isminimized = 0;
|
||||
wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false);
|
||||
client_pending_minimized_state(c, 0);
|
||||
focusclient(c, 1);
|
||||
wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true);
|
||||
}
|
||||
|
|
@ -5884,8 +5901,8 @@ void overview_backup(Client *c) {
|
|||
c->isfloating = 0;
|
||||
}
|
||||
if (c->isfullscreen || c->ismaximizescreen) {
|
||||
c->isfullscreen = 0; // 清除窗口全屏标志
|
||||
c->ismaximizescreen = 0;
|
||||
client_pending_fullscreen_state(c, 0); // 清除窗口全屏标志
|
||||
client_pending_maximized_state(c, 0);
|
||||
}
|
||||
c->bw = c->isnoborder ? 0 : config.borderpx;
|
||||
|
||||
|
|
@ -5915,8 +5932,8 @@ void overview_restore(Client *c, const Arg *arg) {
|
|||
} else if (want_restore_fullscreen(c) && c->isfullscreen) {
|
||||
setfullscreen(c, 1);
|
||||
} else {
|
||||
c->isfullscreen = 0;
|
||||
c->ismaximizescreen = 0;
|
||||
client_pending_fullscreen_state(c, 0);
|
||||
client_pending_maximized_state(c, 0);
|
||||
setfullscreen(c, false);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -6489,13 +6506,11 @@ void activatex11(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
|
||||
if (c->isminimized) {
|
||||
c->isminimized = 0;
|
||||
client_pending_minimized_state(c, 0);
|
||||
c->tags = c->mini_restore_tag;
|
||||
c->is_scratchpad_show = 0;
|
||||
c->is_in_scratchpad = 0;
|
||||
c->isnamedscratchpad = 0;
|
||||
wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel,
|
||||
false);
|
||||
setborder_color(c);
|
||||
if (VISIBLEON(c, c->mon)) {
|
||||
need_arrange = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue