mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-23 05:35:53 -04:00
Merge branch 'mangowm:main' into main
This commit is contained in:
commit
05ff5844fb
8 changed files with 479 additions and 273 deletions
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
||||||
days-before-issue-stale: -1
|
days-before-issue-stale: -1
|
||||||
# 手动标记后,14 天后关闭
|
# 手动标记后,14 天后关闭
|
||||||
days-before-issue-close: 7
|
days-before-issue-close: 7
|
||||||
# 使用的标签(必须和你手动添加的标签一致)
|
# 使用的标签
|
||||||
stale-issue-label: "stale"
|
stale-issue-label: "stale"
|
||||||
# 自动关闭时自动加上的标签
|
# 自动关闭时自动加上的标签
|
||||||
close-issue-label: "automatic-closing"
|
close-issue-label: "automatic-closing"
|
||||||
|
|
|
||||||
|
|
@ -61,4 +61,7 @@
|
||||||
inspired by dwl but aiming to be more feature-rich.")
|
inspired by dwl but aiming to be more feature-rich.")
|
||||||
(license gpl3)))
|
(license gpl3)))
|
||||||
|
|
||||||
|
(define-deprecated-package mangowc
|
||||||
|
mangowm-git)
|
||||||
|
|
||||||
mangowm-git
|
mangowm-git
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,8 @@ typedef struct {
|
||||||
int32_t ignore_maximize;
|
int32_t ignore_maximize;
|
||||||
int32_t ignore_minimize;
|
int32_t ignore_minimize;
|
||||||
int32_t isnosizehint;
|
int32_t isnosizehint;
|
||||||
const char *monitor;
|
int32_t indleinhibit_when_focus;
|
||||||
|
char *monitor;
|
||||||
int32_t offsetx;
|
int32_t offsetx;
|
||||||
int32_t offsety;
|
int32_t offsety;
|
||||||
int32_t width;
|
int32_t width;
|
||||||
|
|
@ -111,6 +112,7 @@ typedef struct {
|
||||||
int32_t width, height; // Monitor resolution
|
int32_t width, height; // Monitor resolution
|
||||||
float refresh; // Refresh rate
|
float refresh; // Refresh rate
|
||||||
int32_t vrr; // variable refresh rate
|
int32_t vrr; // variable refresh rate
|
||||||
|
int32_t custom; // enable custom mode
|
||||||
} ConfigMonitorRule;
|
} ConfigMonitorRule;
|
||||||
|
|
||||||
// 修改后的宏定义
|
// 修改后的宏定义
|
||||||
|
|
@ -354,6 +356,8 @@ typedef struct {
|
||||||
int32_t single_scratchpad;
|
int32_t single_scratchpad;
|
||||||
int32_t xwayland_persistence;
|
int32_t xwayland_persistence;
|
||||||
int32_t syncobj_enable;
|
int32_t syncobj_enable;
|
||||||
|
float drag_tile_refresh_interval;
|
||||||
|
float drag_floating_refresh_interval;
|
||||||
int32_t allow_tearing;
|
int32_t allow_tearing;
|
||||||
int32_t allow_shortcuts_inhibit;
|
int32_t allow_shortcuts_inhibit;
|
||||||
int32_t allow_lock_transparent;
|
int32_t allow_lock_transparent;
|
||||||
|
|
@ -370,6 +374,9 @@ typedef int32_t (*FuncType)(const Arg *);
|
||||||
Config config;
|
Config config;
|
||||||
|
|
||||||
bool parse_config_file(Config *config, const char *file_path, bool must_exist);
|
bool parse_config_file(Config *config, const char *file_path, bool must_exist);
|
||||||
|
bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
|
||||||
|
struct wlr_output_state *state, int vrr, int custom);
|
||||||
|
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule);
|
||||||
|
|
||||||
// Helper function to trim whitespace from start and end of a string
|
// Helper function to trim whitespace from start and end of a string
|
||||||
void trim_whitespace(char *str) {
|
void trim_whitespace(char *str) {
|
||||||
|
|
@ -945,6 +952,7 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
|
||||||
(*arg).f = atof(arg_value);
|
(*arg).f = atof(arg_value);
|
||||||
} else if (strcmp(func_name, "switch_proportion_preset") == 0) {
|
} else if (strcmp(func_name, "switch_proportion_preset") == 0) {
|
||||||
func = switch_proportion_preset;
|
func = switch_proportion_preset;
|
||||||
|
(*arg).i = parse_circle_direction(arg_value);
|
||||||
} else if (strcmp(func_name, "viewtoleft") == 0) {
|
} else if (strcmp(func_name, "viewtoleft") == 0) {
|
||||||
func = viewtoleft;
|
func = viewtoleft;
|
||||||
(*arg).i = atoi(arg_value);
|
(*arg).i = atoi(arg_value);
|
||||||
|
|
@ -1393,6 +1401,10 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
config->xwayland_persistence = atoi(value);
|
config->xwayland_persistence = atoi(value);
|
||||||
} else if (strcmp(key, "syncobj_enable") == 0) {
|
} else if (strcmp(key, "syncobj_enable") == 0) {
|
||||||
config->syncobj_enable = atoi(value);
|
config->syncobj_enable = atoi(value);
|
||||||
|
} else if (strcmp(key, "drag_tile_refresh_interval") == 0) {
|
||||||
|
config->drag_tile_refresh_interval = atof(value);
|
||||||
|
} else if (strcmp(key, "drag_floating_refresh_interval") == 0) {
|
||||||
|
config->drag_floating_refresh_interval = atof(value);
|
||||||
} else if (strcmp(key, "allow_tearing") == 0) {
|
} else if (strcmp(key, "allow_tearing") == 0) {
|
||||||
config->allow_tearing = atoi(value);
|
config->allow_tearing = atoi(value);
|
||||||
} else if (strcmp(key, "allow_shortcuts_inhibit") == 0) {
|
} else if (strcmp(key, "allow_shortcuts_inhibit") == 0) {
|
||||||
|
|
@ -1795,6 +1807,7 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->height = -1;
|
rule->height = -1;
|
||||||
rule->refresh = 0.0f;
|
rule->refresh = 0.0f;
|
||||||
rule->vrr = 0;
|
rule->vrr = 0;
|
||||||
|
rule->custom = 0;
|
||||||
|
|
||||||
bool parse_error = false;
|
bool parse_error = false;
|
||||||
char *token = strtok(value, ",");
|
char *token = strtok(value, ",");
|
||||||
|
|
@ -1832,6 +1845,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->refresh = CLAMP_FLOAT(atof(val), 0.001f, 1000.0f);
|
rule->refresh = CLAMP_FLOAT(atof(val), 0.001f, 1000.0f);
|
||||||
} else if (strcmp(key, "vrr") == 0) {
|
} else if (strcmp(key, "vrr") == 0) {
|
||||||
rule->vrr = CLAMP_INT(atoi(val), 0, 1);
|
rule->vrr = CLAMP_INT(atoi(val), 0, 1);
|
||||||
|
} else if (strcmp(key, "custom") == 0) {
|
||||||
|
rule->custom = CLAMP_INT(atoi(val), 0, 1);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
||||||
|
|
@ -2022,6 +2037,7 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->ignore_maximize = -1;
|
rule->ignore_maximize = -1;
|
||||||
rule->ignore_minimize = -1;
|
rule->ignore_minimize = -1;
|
||||||
rule->isnosizehint = -1;
|
rule->isnosizehint = -1;
|
||||||
|
rule->indleinhibit_when_focus = -1;
|
||||||
rule->isterm = -1;
|
rule->isterm = -1;
|
||||||
rule->allow_csd = -1;
|
rule->allow_csd = -1;
|
||||||
rule->force_maximize = -1;
|
rule->force_maximize = -1;
|
||||||
|
|
@ -2132,6 +2148,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->ignore_minimize = atoi(val);
|
rule->ignore_minimize = atoi(val);
|
||||||
} else if (strcmp(key, "isnosizehint") == 0) {
|
} else if (strcmp(key, "isnosizehint") == 0) {
|
||||||
rule->isnosizehint = atoi(val);
|
rule->isnosizehint = atoi(val);
|
||||||
|
} else if (strcmp(key, "indleinhibit_when_focus") == 0) {
|
||||||
|
rule->indleinhibit_when_focus = atoi(val);
|
||||||
} else if (strcmp(key, "isterm") == 0) {
|
} else if (strcmp(key, "isterm") == 0) {
|
||||||
rule->isterm = atoi(val);
|
rule->isterm = atoi(val);
|
||||||
} else if (strcmp(key, "allow_csd") == 0) {
|
} else if (strcmp(key, "allow_csd") == 0) {
|
||||||
|
|
@ -3137,6 +3155,13 @@ void override_config(void) {
|
||||||
// 杂项设置
|
// 杂项设置
|
||||||
xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1);
|
||||||
syncobj_enable = CLAMP_INT(config.syncobj_enable, 0, 1);
|
syncobj_enable = CLAMP_INT(config.syncobj_enable, 0, 1);
|
||||||
|
drag_tile_refresh_interval =
|
||||||
|
CLAMP_FLOAT(config.drag_tile_refresh_interval, 1.0f, 16.0f);
|
||||||
|
drag_floating_refresh_interval =
|
||||||
|
CLAMP_FLOAT(config.drag_floating_refresh_interval, 1.0f, 16.0f);
|
||||||
|
drag_tile_to_tile = CLAMP_INT(config.drag_tile_to_tile, 0, 1);
|
||||||
|
drag_floating_refresh_interval =
|
||||||
|
CLAMP_FLOAT(config.drag_floating_refresh_interval, 0.0f, 1000.0f);
|
||||||
allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2);
|
allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2);
|
||||||
allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1);
|
allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1);
|
||||||
allow_lock_transparent = CLAMP_INT(config.allow_lock_transparent, 0, 1);
|
allow_lock_transparent = CLAMP_INT(config.allow_lock_transparent, 0, 1);
|
||||||
|
|
@ -3325,6 +3350,8 @@ void set_value_default() {
|
||||||
config.single_scratchpad = single_scratchpad;
|
config.single_scratchpad = single_scratchpad;
|
||||||
config.xwayland_persistence = xwayland_persistence;
|
config.xwayland_persistence = xwayland_persistence;
|
||||||
config.syncobj_enable = syncobj_enable;
|
config.syncobj_enable = syncobj_enable;
|
||||||
|
config.drag_tile_refresh_interval = drag_tile_refresh_interval;
|
||||||
|
config.drag_floating_refresh_interval = drag_floating_refresh_interval;
|
||||||
config.allow_tearing = allow_tearing;
|
config.allow_tearing = allow_tearing;
|
||||||
config.allow_shortcuts_inhibit = allow_shortcuts_inhibit;
|
config.allow_shortcuts_inhibit = allow_shortcuts_inhibit;
|
||||||
config.allow_lock_transparent = allow_lock_transparent;
|
config.allow_lock_transparent = allow_lock_transparent;
|
||||||
|
|
@ -3551,17 +3578,15 @@ void reset_blur_params(void) {
|
||||||
void reapply_monitor_rules(void) {
|
void reapply_monitor_rules(void) {
|
||||||
ConfigMonitorRule *mr;
|
ConfigMonitorRule *mr;
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
int32_t ji, vrr;
|
int32_t ji, vrr, custom;
|
||||||
int32_t mx, my;
|
int32_t mx, my;
|
||||||
struct wlr_output_state state;
|
struct wlr_output_state state;
|
||||||
struct wlr_output_mode *internal_mode = NULL;
|
|
||||||
wlr_output_state_init(&state);
|
|
||||||
bool match_rule = false;
|
|
||||||
|
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
if (!m->wlr_output->enabled) {
|
if (!m->wlr_output->enabled)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
wlr_output_state_init(&state);
|
||||||
|
|
||||||
for (ji = 0; ji < config.monitor_rules_count; ji++) {
|
for (ji = 0; ji < config.monitor_rules_count; ji++) {
|
||||||
if (config.monitor_rules_count < 1)
|
if (config.monitor_rules_count < 1)
|
||||||
|
|
@ -3569,78 +3594,29 @@ void reapply_monitor_rules(void) {
|
||||||
|
|
||||||
mr = &config.monitor_rules[ji];
|
mr = &config.monitor_rules[ji];
|
||||||
|
|
||||||
// 检查是否匹配的变量
|
if (monitor_matches_rule(m, mr)) {
|
||||||
match_rule = true;
|
|
||||||
|
|
||||||
// 检查四个标识字段的匹配
|
|
||||||
if (mr->name != NULL) {
|
|
||||||
if (!regex_match(mr->name, m->wlr_output->name)) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mr->make != NULL) {
|
|
||||||
if (m->wlr_output->make == NULL ||
|
|
||||||
strcmp(mr->make, m->wlr_output->make) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mr->model != NULL) {
|
|
||||||
if (m->wlr_output->model == NULL ||
|
|
||||||
strcmp(mr->model, m->wlr_output->model) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mr->serial != NULL) {
|
|
||||||
if (m->wlr_output->serial == NULL ||
|
|
||||||
strcmp(mr->serial, m->wlr_output->serial) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 只有当所有指定的标识都匹配时才应用规则
|
|
||||||
if (match_rule) {
|
|
||||||
mx = mr->x == INT32_MAX ? m->m.x : mr->x;
|
mx = mr->x == INT32_MAX ? m->m.x : mr->x;
|
||||||
my = mr->y == INT32_MAX ? m->m.y : mr->y;
|
my = mr->y == INT32_MAX ? m->m.y : mr->y;
|
||||||
vrr = mr->vrr >= 0 ? mr->vrr : 0;
|
vrr = mr->vrr >= 0 ? mr->vrr : 0;
|
||||||
|
custom = mr->custom >= 0 ? mr->custom : 0;
|
||||||
|
|
||||||
if (mr->width > 0 && mr->height > 0 && mr->refresh > 0) {
|
(void)apply_rule_to_state(m, mr, &state, vrr, custom);
|
||||||
internal_mode = get_nearest_output_mode(
|
|
||||||
m->wlr_output, mr->width, mr->height, mr->refresh);
|
|
||||||
if (internal_mode) {
|
|
||||||
wlr_output_state_set_mode(&state, internal_mode);
|
|
||||||
} else if (wlr_output_is_headless(m->wlr_output)) {
|
|
||||||
wlr_output_state_set_custom_mode(
|
|
||||||
&state, mr->width, mr->height,
|
|
||||||
(int32_t)roundf(mr->refresh * 1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vrr) {
|
|
||||||
enable_adaptive_sync(m, &state);
|
|
||||||
} else {
|
|
||||||
wlr_output_state_set_adaptive_sync_enabled(&state, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_output_state_set_scale(&state, mr->scale);
|
|
||||||
wlr_output_state_set_transform(&state, mr->rr);
|
|
||||||
wlr_output_layout_add(output_layout, m->wlr_output, mx, my);
|
wlr_output_layout_add(output_layout, m->wlr_output, mx, my);
|
||||||
|
wlr_output_commit_state(m->wlr_output, &state);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_commit_state(m->wlr_output, &state);
|
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
updatemons(NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
updatemons(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reapply_cursor_style(void) {
|
void reapply_cursor_style(void) {
|
||||||
if (hide_source) {
|
if (hide_cursor_source) {
|
||||||
wl_event_source_timer_update(hide_source, 0);
|
wl_event_source_timer_update(hide_cursor_source, 0);
|
||||||
wl_event_source_remove(hide_source);
|
wl_event_source_remove(hide_cursor_source);
|
||||||
hide_source = NULL;
|
hide_cursor_source = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_cursor_unset_image(cursor);
|
wlr_cursor_unset_image(cursor);
|
||||||
|
|
@ -3671,12 +3647,13 @@ void reapply_cursor_style(void) {
|
||||||
|
|
||||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr");
|
wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr");
|
||||||
|
|
||||||
hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
|
hide_cursor_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
|
||||||
hidecursor, cursor);
|
hidecursor, cursor);
|
||||||
if (cursor_hidden) {
|
if (cursor_hidden) {
|
||||||
wlr_cursor_unset_image(cursor);
|
wlr_cursor_unset_image(cursor);
|
||||||
} else {
|
} else {
|
||||||
wl_event_source_timer_update(hide_source, cursor_hide_timeout * 1000);
|
wl_event_source_timer_update(hide_cursor_source,
|
||||||
|
cursor_hide_timeout * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ int32_t drag_warp_cursor = 1;
|
||||||
int32_t xwayland_persistence = 1; /* xwayland persistence */
|
int32_t xwayland_persistence = 1; /* xwayland persistence */
|
||||||
int32_t syncobj_enable = 0;
|
int32_t syncobj_enable = 0;
|
||||||
int32_t allow_lock_transparent = 0;
|
int32_t allow_lock_transparent = 0;
|
||||||
double drag_tile_refresh_interval = 16.0;
|
double drag_tile_refresh_interval = 8.0;
|
||||||
double drag_floating_refresh_interval = 8.0;
|
double drag_floating_refresh_interval = 8.0;
|
||||||
int32_t allow_tearing = TEARING_DISABLED;
|
int32_t allow_tearing = TEARING_DISABLED;
|
||||||
int32_t allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
int32_t allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,9 @@ int32_t exchange_client(const Arg *arg) {
|
||||||
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
|
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exchange_two_client(c, direction_select(arg));
|
Client *tc = direction_select(arg);
|
||||||
|
tc = get_focused_stack_client(tc);
|
||||||
|
exchange_two_client(c, tc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1054,13 +1056,28 @@ int32_t switch_proportion_preset(const Arg *arg) {
|
||||||
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
||||||
if (config.scroller_proportion_preset[i] ==
|
if (config.scroller_proportion_preset[i] ==
|
||||||
tc->scroller_proportion) {
|
tc->scroller_proportion) {
|
||||||
if (i == config.scroller_proportion_preset_count - 1) {
|
|
||||||
target_proportion = config.scroller_proportion_preset[0];
|
if (arg->i == NEXT) {
|
||||||
break;
|
if (i == config.scroller_proportion_preset_count - 1) {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[0];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[i + 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
target_proportion =
|
if (i == 0) {
|
||||||
config.scroller_proportion_preset[i + 1];
|
target_proportion =
|
||||||
break;
|
config.scroller_proportion_preset
|
||||||
|
[config.scroller_proportion_preset_count - 1];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
target_proportion =
|
||||||
|
config.scroller_proportion_preset[i - 1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1419,6 +1436,7 @@ int32_t toggleview(const Arg *arg) {
|
||||||
|
|
||||||
uint32_t newtagset;
|
uint32_t newtagset;
|
||||||
uint32_t target;
|
uint32_t target;
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
target = arg->ui == 0 ? ~0 & TAGMASK : arg->ui;
|
target = arg->ui == 0 ? ~0 & TAGMASK : arg->ui;
|
||||||
|
|
||||||
|
|
@ -1427,6 +1445,11 @@ int32_t toggleview(const Arg *arg) {
|
||||||
if (newtagset) {
|
if (newtagset) {
|
||||||
selmon->tagset[selmon->seltags] = newtagset;
|
selmon->tagset[selmon->seltags] = newtagset;
|
||||||
focusclient(focustop(selmon), 1);
|
focusclient(focustop(selmon), 1);
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, selmon) && ISTILED(c)) {
|
||||||
|
set_size_per(selmon, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
arrange(selmon, false, false);
|
arrange(selmon, false, false);
|
||||||
}
|
}
|
||||||
printstatus();
|
printstatus();
|
||||||
|
|
@ -1751,28 +1774,19 @@ int32_t scroller_stack(const Arg *arg) {
|
||||||
if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon))
|
if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (c && (!client_only_in_one_tag(c) || c->isglobal || c->isunglobal))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
bool is_horizontal_layout =
|
bool is_horizontal_layout =
|
||||||
c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER ? true
|
c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER ? true
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
Client *target_client = find_client_by_direction(c, arg, false, true);
|
Client *target_client = find_client_by_direction(c, arg, false, true);
|
||||||
|
|
||||||
if (target_client && (!client_only_in_one_tag(target_client) ||
|
|
||||||
target_client->isglobal || target_client->isunglobal))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (target_client) {
|
if (target_client) {
|
||||||
stack_head = get_scroll_stack_head(target_client);
|
stack_head = get_scroll_stack_head(target_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c) {
|
source_stack_head = get_scroll_stack_head(c);
|
||||||
source_stack_head = get_scroll_stack_head(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack_head == source_stack_head) {
|
if (source_stack_head == stack_head) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1820,6 +1834,10 @@ int32_t scroller_stack(const Arg *arg) {
|
||||||
|
|
||||||
if (!target_client || target_client->mon != c->mon) {
|
if (!target_client || target_client->mon != c->mon) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
c->isglobal = target_client->isglobal = 0;
|
||||||
|
c->isunglobal = target_client->isglobal = 0;
|
||||||
|
c->tags = target_client->tags = get_tags_first_tag(target_client->tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_scroller_stack(c);
|
exit_scroller_stack(c);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,31 @@
|
||||||
|
void save_old_size_per(Monitor *m) {
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
c->old_master_inner_per = c->master_inner_per;
|
||||||
|
c->old_stack_inner_per = c->stack_inner_per;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void restore_size_per(Monitor *m, Client *c) {
|
void restore_size_per(Monitor *m, Client *c) {
|
||||||
Client *fc = NULL;
|
Client *fc = NULL;
|
||||||
double total_master_inner_per = 0;
|
|
||||||
double total_stack_inner_per = 0;
|
|
||||||
|
|
||||||
if (!m || !c)
|
if (!m || !c)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
if (VISIBLEON(fc, m) && ISTILED(fc)) {
|
||||||
|
fc->old_ismaster = fc->ismaster;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c->old_master_inner_per = c->master_inner_per;
|
||||||
|
c->old_stack_inner_per = c->stack_inner_per;
|
||||||
|
|
||||||
|
pre_caculate_before_arrange(m, false, false, true);
|
||||||
|
|
||||||
const Layout *current_layout = m->pertag->ltidxs[m->pertag->curtag];
|
const Layout *current_layout = m->pertag->ltidxs[m->pertag->curtag];
|
||||||
|
|
||||||
if (current_layout->id == SCROLLER ||
|
if (current_layout->id == SCROLLER ||
|
||||||
|
|
@ -15,7 +35,7 @@ void restore_size_per(Monitor *m, Client *c) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_layout->id == CENTER_TILE || c->ismaster) {
|
if (current_layout->id == CENTER_TILE) {
|
||||||
wl_list_for_each(fc, &clients, link) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc) && !c->ismaster) {
|
if (VISIBLEON(fc, m) && ISTILED(fc) && !c->ismaster) {
|
||||||
set_size_per(m, fc);
|
set_size_per(m, fc);
|
||||||
|
|
@ -24,19 +44,36 @@ void restore_size_per(Monitor *m, Client *c) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_for_each(fc, &clients, link) {
|
// it is possible that the current floating window is moved to another tag,
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
// but the tag has not executed save_old_size_per
|
||||||
if (fc->ismaster) {
|
// so it must be judged whether their old size values are initial values
|
||||||
total_master_inner_per += fc->master_inner_per;
|
|
||||||
} else {
|
if (!c->ismaster && c->old_stack_inner_per < 1.0 &&
|
||||||
total_stack_inner_per += fc->stack_inner_per;
|
c->old_stack_inner_per > 0.0f && c->stack_inner_per < 1.0 &&
|
||||||
}
|
c->stack_inner_per > 0.0f) {
|
||||||
}
|
c->stack_inner_per = (1.0 - c->stack_inner_per) *
|
||||||
|
c->old_stack_inner_per /
|
||||||
|
(1.0 - c->old_stack_inner_per);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c->ismaster && total_stack_inner_per) {
|
if (c->ismaster && c->old_master_inner_per < 1.0 &&
|
||||||
c->stack_inner_per = total_stack_inner_per * c->stack_inner_per /
|
c->old_master_inner_per > 0.0f && c->master_inner_per < 1.0 &&
|
||||||
(1 - c->stack_inner_per);
|
c->master_inner_per > 0.0f) {
|
||||||
|
c->master_inner_per = (1.0 - c->master_inner_per) *
|
||||||
|
c->old_master_inner_per /
|
||||||
|
(1.0 - c->old_master_inner_per);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_for_each(fc, &clients, link) {
|
||||||
|
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c && !fc->ismaster &&
|
||||||
|
fc->old_ismaster && fc->old_stack_inner_per < 1.0 &&
|
||||||
|
fc->old_stack_inner_per > 0.0f && fc->stack_inner_per < 1.0 &&
|
||||||
|
fc->stack_inner_per > 0.0f) {
|
||||||
|
fc->stack_inner_per = (1.0 - fc->stack_inner_per) *
|
||||||
|
fc->old_stack_inner_per /
|
||||||
|
(1.0 - fc->old_stack_inner_per);
|
||||||
|
fc->old_ismaster = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +89,7 @@ void set_size_per(Monitor *m, Client *c) {
|
||||||
wl_list_for_each(fc, &clients, link) {
|
wl_list_for_each(fc, &clients, link) {
|
||||||
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
||||||
if (current_layout->id == CENTER_TILE &&
|
if (current_layout->id == CENTER_TILE &&
|
||||||
!(fc->isleftstack ^ c->isleftstack))
|
(fc->isleftstack ^ c->isleftstack))
|
||||||
continue;
|
continue;
|
||||||
c->master_mfact_per = fc->master_mfact_per;
|
c->master_mfact_per = fc->master_mfact_per;
|
||||||
c->master_inner_per = fc->master_inner_per;
|
c->master_inner_per = fc->master_inner_per;
|
||||||
|
|
@ -90,8 +127,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!begin_find_nextnext && VISIBLEON(tc, grabc->mon) &&
|
if (!begin_find_nextnext && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
next = tc;
|
next = tc;
|
||||||
begin_find_nextnext = true;
|
begin_find_nextnext = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -107,8 +143,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!begin_find_prevprev && VISIBLEON(tc, grabc->mon) &&
|
if (!begin_find_prevprev && VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
prev = tc;
|
prev = tc;
|
||||||
begin_find_prevprev = true;
|
begin_find_prevprev = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -244,6 +279,23 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用到所有平铺窗口
|
// 应用到所有平铺窗口
|
||||||
wl_list_for_each(tc, &clients, link) {
|
wl_list_for_each(tc, &clients, link) {
|
||||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
|
|
||||||
|
if (!isdrag && tc != grabc) {
|
||||||
|
if (!tc->ismaster && new_stack_inner_per != 1.0f &&
|
||||||
|
grabc->old_stack_inner_per != 1.0f &&
|
||||||
|
(type != CENTER_TILE ||
|
||||||
|
!(grabc->isleftstack ^ tc->isleftstack)))
|
||||||
|
tc->stack_inner_per = (1 - new_stack_inner_per) /
|
||||||
|
(1 - grabc->old_stack_inner_per) *
|
||||||
|
tc->stack_inner_per;
|
||||||
|
if (tc->ismaster && new_master_inner_per != 1.0f &&
|
||||||
|
grabc->old_master_inner_per != 1.0f)
|
||||||
|
tc->master_inner_per =
|
||||||
|
(1.0f - new_master_inner_per) /
|
||||||
|
(1.0f - grabc->old_master_inner_per) *
|
||||||
|
tc->master_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
tc->master_mfact_per = new_master_mfact_per;
|
tc->master_mfact_per = new_master_mfact_per;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -276,8 +328,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
for (node = grabc->link.next; node != &clients; node = node->next) {
|
for (node = grabc->link.next; node != &clients; node = node->next) {
|
||||||
tc = wl_container_of(node, tc, link);
|
tc = wl_container_of(node, tc, link);
|
||||||
|
|
||||||
if (VISIBLEON(tc, grabc->mon) &&
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
next = tc;
|
next = tc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -287,8 +338,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
for (node = grabc->link.prev; node != &clients; node = node->prev) {
|
for (node = grabc->link.prev; node != &clients; node = node->prev) {
|
||||||
tc = wl_container_of(node, tc, link);
|
tc = wl_container_of(node, tc, link);
|
||||||
|
|
||||||
if (VISIBLEON(tc, grabc->mon) &&
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
ISTILED(tc)) { // 根据你的实际字段名调整
|
|
||||||
prev = tc;
|
prev = tc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -401,6 +451,20 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用到所有平铺窗口
|
// 应用到所有平铺窗口
|
||||||
wl_list_for_each(tc, &clients, link) {
|
wl_list_for_each(tc, &clients, link) {
|
||||||
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) {
|
||||||
|
if (!isdrag && tc != grabc && type != CENTER_TILE) {
|
||||||
|
if (!tc->ismaster && new_stack_inner_per != 1.0f &&
|
||||||
|
grabc->old_stack_inner_per != 1.0f)
|
||||||
|
tc->stack_inner_per = (1 - new_stack_inner_per) /
|
||||||
|
(1 - grabc->old_stack_inner_per) *
|
||||||
|
tc->stack_inner_per;
|
||||||
|
if (tc->ismaster && new_master_inner_per != 1.0f &&
|
||||||
|
grabc->old_master_inner_per != 1.0f)
|
||||||
|
tc->master_inner_per =
|
||||||
|
(1.0f - new_master_inner_per) /
|
||||||
|
(1.0f - grabc->old_master_inner_per) *
|
||||||
|
tc->master_inner_per;
|
||||||
|
}
|
||||||
|
|
||||||
tc->master_mfact_per = new_master_mfact_per;
|
tc->master_mfact_per = new_master_mfact_per;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -423,6 +487,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
|
|
||||||
void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
int32_t offsety, uint32_t time, bool isvertical) {
|
int32_t offsety, uint32_t time, bool isvertical) {
|
||||||
|
Client *tc = NULL;
|
||||||
float delta_x, delta_y;
|
float delta_x, delta_y;
|
||||||
float new_scroller_proportion;
|
float new_scroller_proportion;
|
||||||
float new_stack_proportion;
|
float new_stack_proportion;
|
||||||
|
|
@ -583,12 +648,22 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
// 应用限制,确保比例在合理范围内
|
// 应用限制,确保比例在合理范围内
|
||||||
new_scroller_proportion =
|
new_scroller_proportion =
|
||||||
fmaxf(0.1f, fminf(1.0f, new_scroller_proportion));
|
fmaxf(0.1f, fminf(1.0f, new_scroller_proportion));
|
||||||
new_stack_proportion = fmaxf(0.1f, fminf(1.0f, new_stack_proportion));
|
new_stack_proportion = fmaxf(0.1f, fminf(0.9f, new_stack_proportion));
|
||||||
|
|
||||||
grabc->stack_proportion = new_stack_proportion;
|
grabc->stack_proportion = new_stack_proportion;
|
||||||
|
|
||||||
stack_head->scroller_proportion = new_scroller_proportion;
|
stack_head->scroller_proportion = new_scroller_proportion;
|
||||||
|
|
||||||
|
wl_list_for_each(tc, &clients, link) {
|
||||||
|
if (!isdrag && new_stack_proportion != 1.0f &&
|
||||||
|
grabc->old_stack_proportion != 1.0f && tc != grabc &&
|
||||||
|
ISTILED(tc) && get_scroll_stack_head(tc) == stack_head) {
|
||||||
|
tc->stack_proportion = (1.0f - new_stack_proportion) /
|
||||||
|
(1.0f - grabc->old_stack_proportion) *
|
||||||
|
tc->stack_proportion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!isdrag) {
|
if (!isdrag) {
|
||||||
arrange(grabc->mon, false, false);
|
arrange(grabc->mon, false, false);
|
||||||
return;
|
return;
|
||||||
|
|
@ -631,6 +706,18 @@ void resize_tile_client(Client *grabc, bool isdrag, int32_t offsetx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there are no calculation omissions,
|
||||||
|
these two functions will never be triggered.
|
||||||
|
Just in case to facilitate the final investigation*/
|
||||||
|
|
||||||
|
void check_size_per_valid(Client *c) {
|
||||||
|
if (c->ismaster) {
|
||||||
|
assert(c->master_inner_per > 0.0f && c->master_inner_per <= 1.0f);
|
||||||
|
} else {
|
||||||
|
assert(c->stack_inner_per > 0.0f && c->stack_inner_per <= 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
double total_left_stack_hight_percent,
|
double total_left_stack_hight_percent,
|
||||||
double total_right_stack_hight_percent,
|
double total_right_stack_hight_percent,
|
||||||
|
|
@ -646,6 +733,7 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
|
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
|
||||||
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
||||||
c->ismaster = true;
|
c->ismaster = true;
|
||||||
c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
|
c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
|
||||||
|
|
@ -661,17 +749,20 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
: 1.0f;
|
: 1.0f;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
check_size_per_valid(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||||
|
|
||||||
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
||||||
c->ismaster = true;
|
c->ismaster = true;
|
||||||
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
||||||
c->stack_inner_per =
|
c->stack_inner_per =
|
||||||
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2) : 1.0f;
|
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2.0f)
|
||||||
|
: 1.0f;
|
||||||
} else {
|
} else {
|
||||||
c->stack_inner_per =
|
c->stack_inner_per =
|
||||||
stack_num > 1 ? 2.0f / stack_num : 1.0f;
|
stack_num > 1 ? 2.0f / stack_num : 1.0f;
|
||||||
|
|
@ -700,13 +791,15 @@ void reset_size_per_mon(Monitor *m, int32_t tile_cilent_num,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
check_size_per_valid(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 17
|
void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
||||||
arrange(Monitor *m, bool want_animation, bool from_view) {
|
bool from_view, bool only_caculate) {
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
double total_stack_inner_percent = 0;
|
double total_stack_inner_percent = 0;
|
||||||
double total_master_inner_percent = 0;
|
double total_master_inner_percent = 0;
|
||||||
|
|
@ -795,14 +888,17 @@ arrange(Monitor *m, bool want_animation, bool from_view) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_arrange_visible(m, c, want_animation);
|
if (!only_caculate)
|
||||||
|
set_arrange_visible(m, c, want_animation);
|
||||||
} else {
|
} else {
|
||||||
set_arrange_hidden(m, c, want_animation);
|
if (!only_caculate)
|
||||||
|
set_arrange_hidden(m, c, want_animation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->mon == m && c->ismaximizescreen && !c->animation.tagouted &&
|
if (!only_caculate && c->mon == m && c->ismaximizescreen &&
|
||||||
!c->animation.tagouting && VISIBLEON(c, m)) {
|
!c->animation.tagouted && !c->animation.tagouting &&
|
||||||
|
VISIBLEON(c, m)) {
|
||||||
reset_maximizescreen_size(c);
|
reset_maximizescreen_size(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -811,6 +907,12 @@ arrange(Monitor *m, bool want_animation, bool from_view) {
|
||||||
m, m->visible_tiling_clients, total_left_stack_hight_percent,
|
m, m->visible_tiling_clients, total_left_stack_hight_percent,
|
||||||
total_right_stack_hight_percent, total_stack_inner_percent,
|
total_right_stack_hight_percent, total_stack_inner_percent,
|
||||||
total_master_inner_percent, master_num, stack_num);
|
total_master_inner_percent, master_num, stack_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void // 17
|
||||||
|
arrange(Monitor *m, bool want_animation, bool from_view) {
|
||||||
|
|
||||||
|
pre_caculate_before_arrange(m, want_animation, from_view, false);
|
||||||
|
|
||||||
if (m->isoverview) {
|
if (m->isoverview) {
|
||||||
overviewlayout.arrange(m);
|
overviewlayout.arrange(m);
|
||||||
|
|
|
||||||
406
src/mango.c
406
src/mango.c
|
|
@ -347,7 +347,7 @@ struct Client {
|
||||||
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
|
struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel;
|
||||||
int32_t isfloating, isurgent, isfullscreen, isfakefullscreen,
|
int32_t isfloating, isurgent, isfullscreen, isfakefullscreen,
|
||||||
need_float_size_reduce, isminimized, isoverlay, isnosizehint,
|
need_float_size_reduce, isminimized, isoverlay, isnosizehint,
|
||||||
ignore_maximize, ignore_minimize;
|
ignore_maximize, ignore_minimize, indleinhibit_when_focus;
|
||||||
int32_t ismaximizescreen;
|
int32_t ismaximizescreen;
|
||||||
int32_t overview_backup_bw;
|
int32_t overview_backup_bw;
|
||||||
int32_t fullscreen_backup_x, fullscreen_backup_y, fullscreen_backup_w,
|
int32_t fullscreen_backup_x, fullscreen_backup_y, fullscreen_backup_w,
|
||||||
|
|
@ -412,6 +412,7 @@ struct Client {
|
||||||
double old_master_mfact_per, old_master_inner_per, old_stack_inner_per;
|
double old_master_mfact_per, old_master_inner_per, old_stack_inner_per;
|
||||||
double old_scroller_pproportion;
|
double old_scroller_pproportion;
|
||||||
bool ismaster;
|
bool ismaster;
|
||||||
|
bool old_ismaster;
|
||||||
bool cursor_in_upper_half, cursor_in_left_half;
|
bool cursor_in_upper_half, cursor_in_left_half;
|
||||||
bool isleftstack;
|
bool isleftstack;
|
||||||
int32_t tearing_hint;
|
int32_t tearing_hint;
|
||||||
|
|
@ -488,7 +489,6 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct wlr_xdg_popup *wlr_popup;
|
struct wlr_xdg_popup *wlr_popup;
|
||||||
uint32_t type;
|
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener commit;
|
struct wl_listener commit;
|
||||||
struct wl_listener reposition;
|
struct wl_listener reposition;
|
||||||
|
|
@ -800,7 +800,12 @@ static void monitor_stop_skip_frame_timer(Monitor *m);
|
||||||
static int monitor_skip_frame_timeout_callback(void *data);
|
static int monitor_skip_frame_timeout_callback(void *data);
|
||||||
static Monitor *get_monitor_nearest_to(int32_t lx, int32_t ly);
|
static Monitor *get_monitor_nearest_to(int32_t lx, int32_t ly);
|
||||||
static bool match_monitor_spec(char *spec, Monitor *m);
|
static bool match_monitor_spec(char *spec, Monitor *m);
|
||||||
|
static void last_cursor_surface_destroy(struct wl_listener *listener,
|
||||||
|
void *data);
|
||||||
|
static int32_t keep_idle_inhibit(void *data);
|
||||||
|
static void check_keep_idle_inhibit(Client *c);
|
||||||
|
static void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
||||||
|
bool from_view, bool only_caculate);
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/bind_declare.h"
|
#include "dispatch/bind_declare.h"
|
||||||
#include "layout/layout.h"
|
#include "layout/layout.h"
|
||||||
|
|
@ -896,7 +901,8 @@ struct dvec2 *baked_points_focus;
|
||||||
struct dvec2 *baked_points_opafadein;
|
struct dvec2 *baked_points_opafadein;
|
||||||
struct dvec2 *baked_points_opafadeout;
|
struct dvec2 *baked_points_opafadeout;
|
||||||
|
|
||||||
static struct wl_event_source *hide_source;
|
static struct wl_event_source *hide_cursor_source;
|
||||||
|
static struct wl_event_source *keep_idle_inhibit_source;
|
||||||
static bool cursor_hidden = false;
|
static bool cursor_hidden = false;
|
||||||
static bool tag_combo = false;
|
static bool tag_combo = false;
|
||||||
static const char *cli_config_path = NULL;
|
static const char *cli_config_path = NULL;
|
||||||
|
|
@ -964,6 +970,8 @@ static struct wl_listener new_session_lock = {.notify = locksession};
|
||||||
static struct wl_listener drm_lease_request = {.notify = requestdrmlease};
|
static struct wl_listener drm_lease_request = {.notify = requestdrmlease};
|
||||||
static struct wl_listener keyboard_shortcuts_inhibit_new_inhibitor = {
|
static struct wl_listener keyboard_shortcuts_inhibit_new_inhibitor = {
|
||||||
.notify = handle_keyboard_shortcuts_inhibit_new_inhibitor};
|
.notify = handle_keyboard_shortcuts_inhibit_new_inhibitor};
|
||||||
|
static struct wl_listener last_cursor_surface_destroy_listener = {
|
||||||
|
.notify = last_cursor_surface_destroy};
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
static void fix_xwayland_unmanaged_coordinate(Client *c);
|
static void fix_xwayland_unmanaged_coordinate(Client *c);
|
||||||
|
|
@ -1331,6 +1339,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) {
|
||||||
APPLY_INT_PROP(c, r, ignore_maximize);
|
APPLY_INT_PROP(c, r, ignore_maximize);
|
||||||
APPLY_INT_PROP(c, r, ignore_minimize);
|
APPLY_INT_PROP(c, r, ignore_minimize);
|
||||||
APPLY_INT_PROP(c, r, isnosizehint);
|
APPLY_INT_PROP(c, r, isnosizehint);
|
||||||
|
APPLY_INT_PROP(c, r, indleinhibit_when_focus);
|
||||||
APPLY_INT_PROP(c, r, isunglobal);
|
APPLY_INT_PROP(c, r, isunglobal);
|
||||||
APPLY_INT_PROP(c, r, noblur);
|
APPLY_INT_PROP(c, r, noblur);
|
||||||
APPLY_INT_PROP(c, r, allow_shortcuts_inhibit);
|
APPLY_INT_PROP(c, r, allow_shortcuts_inhibit);
|
||||||
|
|
@ -1435,7 +1444,7 @@ void applyrules(Client *c) {
|
||||||
|
|
||||||
// set monitor of client
|
// set monitor of client
|
||||||
wl_list_for_each(m, &mons, link) {
|
wl_list_for_each(m, &mons, link) {
|
||||||
if (regex_match(r->monitor, m->wlr_output->name)) {
|
if (match_monitor_spec(r->monitor, m)) {
|
||||||
mon = m;
|
mon = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1690,9 +1699,10 @@ void focuslayer(LayerSurface *l) {
|
||||||
client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
|
client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_exclusive_layer(Monitor *m) {
|
void reset_exclusive_layers_focus(Monitor *m) {
|
||||||
LayerSurface *l = NULL;
|
LayerSurface *l = NULL;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
bool neet_change_focus_to_client = false;
|
||||||
uint32_t layers_above_shell[] = {
|
uint32_t layers_above_shell[] = {
|
||||||
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
|
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
|
||||||
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||||
|
|
@ -1703,28 +1713,47 @@ void reset_exclusive_layer(Monitor *m) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < (int32_t)LENGTH(layers_above_shell); i++) {
|
for (i = 0; i < (int32_t)LENGTH(layers_above_shell); i++) {
|
||||||
wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) {
|
wl_list_for_each(l, &m->layers[layers_above_shell[i]], link) {
|
||||||
if (l == exclusive_focus &&
|
if (l == exclusive_focus &&
|
||||||
l->layer_surface->current.keyboard_interactive !=
|
l->layer_surface->current.keyboard_interactive !=
|
||||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
|
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
|
||||||
|
|
||||||
exclusive_focus = NULL;
|
exclusive_focus = NULL;
|
||||||
|
|
||||||
|
neet_change_focus_to_client = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->layer_surface->surface ==
|
||||||
|
seat->keyboard_state.focused_surface &&
|
||||||
|
l->being_unmapped) {
|
||||||
|
neet_change_focus_to_client = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (l->layer_surface->current.keyboard_interactive ==
|
if (l->layer_surface->current.keyboard_interactive ==
|
||||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
|
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE &&
|
||||||
l->layer_surface->surface ==
|
l->layer_surface->surface ==
|
||||||
seat->keyboard_state.focused_surface)
|
seat->keyboard_state.focused_surface) {
|
||||||
focusclient(focustop(selmon), 1);
|
neet_change_focus_to_client = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (locked ||
|
if (locked ||
|
||||||
l->layer_surface->current.keyboard_interactive !=
|
l->layer_surface->current.keyboard_interactive !=
|
||||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE ||
|
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE ||
|
||||||
!l->mapped || l == exclusive_focus)
|
l->being_unmapped)
|
||||||
continue;
|
continue;
|
||||||
/* Deactivate the focused client. */
|
/* Deactivate the focused client. */
|
||||||
exclusive_focus = l;
|
exclusive_focus = l;
|
||||||
focuslayer(l);
|
neet_change_focus_to_client = false;
|
||||||
|
if (l->layer_surface->surface !=
|
||||||
|
seat->keyboard_state.focused_surface)
|
||||||
|
focuslayer(l);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (neet_change_focus_to_client) {
|
||||||
|
focusclient(focustop(selmon), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrangelayers(Monitor *m) {
|
void arrangelayers(Monitor *m) {
|
||||||
|
|
@ -1746,9 +1775,6 @@ void arrangelayers(Monitor *m) {
|
||||||
/* Arrange non-exlusive surfaces from top->bottom */
|
/* Arrange non-exlusive surfaces from top->bottom */
|
||||||
for (i = 3; i >= 0; i--)
|
for (i = 3; i >= 0; i--)
|
||||||
arrangelayer(m, &m->layers[i], &usable_area, 0);
|
arrangelayer(m, &m->layers[i], &usable_area, 0);
|
||||||
|
|
||||||
/* Find topmost keyboard interactive layer, if such a layer exists */
|
|
||||||
reset_exclusive_layer(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void // 鼠标滚轮事件
|
void // 鼠标滚轮事件
|
||||||
|
|
@ -2133,6 +2159,11 @@ void checkidleinhibitor(struct wlr_surface *exclude) {
|
||||||
wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited);
|
wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void last_cursor_surface_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
last_cursor.surface = NULL;
|
||||||
|
wl_list_remove(&listener->link);
|
||||||
|
}
|
||||||
|
|
||||||
void setcursorshape(struct wl_listener *listener, void *data) {
|
void setcursorshape(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
|
struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
|
||||||
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
|
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
|
||||||
|
|
@ -2141,6 +2172,11 @@ void setcursorshape(struct wl_listener *listener, void *data) {
|
||||||
* actually has pointer focus first. If so, we can tell the cursor to
|
* actually has pointer focus first. If so, we can tell the cursor to
|
||||||
* use the provided cursor shape. */
|
* use the provided cursor shape. */
|
||||||
if (event->seat_client == seat->pointer_state.focused_client) {
|
if (event->seat_client == seat->pointer_state.focused_client) {
|
||||||
|
/* Remove surface destroy listener if active */
|
||||||
|
if (last_cursor.surface &&
|
||||||
|
last_cursor_surface_destroy_listener.link.prev != NULL)
|
||||||
|
wl_list_remove(&last_cursor_surface_destroy_listener.link);
|
||||||
|
|
||||||
last_cursor.shape = event->shape;
|
last_cursor.shape = event->shape;
|
||||||
last_cursor.surface = NULL;
|
last_cursor.surface = NULL;
|
||||||
if (!cursor_hidden)
|
if (!cursor_hidden)
|
||||||
|
|
@ -2384,13 +2420,7 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
// 刷新布局,让窗口能感应到exclude_zone变化以及设置独占表面
|
// 刷新布局,让窗口能感应到exclude_zone变化以及设置独占表面
|
||||||
arrangelayers(l->mon);
|
arrangelayers(l->mon);
|
||||||
|
reset_exclusive_layers_focus(l->mon);
|
||||||
// 按需交互layer需要像正常窗口一样抢占非独占layer的焦点
|
|
||||||
if (!exclusive_focus &&
|
|
||||||
l->layer_surface->current.keyboard_interactive ==
|
|
||||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
|
|
||||||
focuslayer(l);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -2410,7 +2440,12 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
l->layer_surface->current = l->layer_surface->pending;
|
l->layer_surface->current = l->layer_surface->pending;
|
||||||
arrangelayers(l->mon);
|
arrangelayers(l->mon);
|
||||||
l->layer_surface->current = old_state;
|
l->layer_surface->current = old_state;
|
||||||
|
// 按需交互layer只在map之前设置焦点
|
||||||
|
if (!exclusive_focus &&
|
||||||
|
l->layer_surface->current.keyboard_interactive ==
|
||||||
|
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) {
|
||||||
|
focuslayer(l);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2455,28 +2490,31 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
layer_flush_blur_background(l);
|
layer_flush_blur_background(l);
|
||||||
|
|
||||||
if (layer_surface == exclusive_focus &&
|
|
||||||
layer_surface->current.keyboard_interactive !=
|
|
||||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
|
|
||||||
exclusive_focus = NULL;
|
|
||||||
|
|
||||||
if (layer_surface->current.committed == 0 &&
|
if (layer_surface->current.committed == 0 &&
|
||||||
l->mapped == layer_surface->surface->mapped)
|
l->mapped == layer_surface->surface->mapped)
|
||||||
return;
|
return;
|
||||||
l->mapped = layer_surface->surface->mapped;
|
l->mapped = layer_surface->surface->mapped;
|
||||||
|
|
||||||
if (scene_layer != l->scene->node.parent) {
|
if (layer_surface->current.committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) {
|
||||||
wlr_scene_node_reparent(&l->scene->node, scene_layer);
|
if (scene_layer != l->scene->node.parent) {
|
||||||
wl_list_remove(&l->link);
|
wlr_scene_node_reparent(&l->scene->node, scene_layer);
|
||||||
wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link);
|
wl_list_remove(&l->link);
|
||||||
wlr_scene_node_reparent(
|
wl_list_insert(&l->mon->layers[layer_surface->current.layer],
|
||||||
&l->popups->node,
|
&l->link);
|
||||||
(layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
wlr_scene_node_reparent(
|
||||||
? layers[LyrTop]
|
&l->popups->node,
|
||||||
: scene_layer));
|
(layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
||||||
|
? layers[LyrTop]
|
||||||
|
: scene_layer));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arrangelayers(l->mon);
|
arrangelayers(l->mon);
|
||||||
|
|
||||||
|
if (layer_surface->current.committed &
|
||||||
|
WLR_LAYER_SURFACE_V1_STATE_KEYBOARD_INTERACTIVITY) {
|
||||||
|
reset_exclusive_layers_focus(l->mon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void commitnotify(struct wl_listener *listener, void *data) {
|
void commitnotify(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -2552,37 +2590,49 @@ void destroydecoration(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&c->set_decoration_mode.link);
|
wl_list_remove(&c->set_decoration_mode.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void popup_unconstrain(Popup *popup) {
|
static bool popup_unconstrain(Popup *popup) {
|
||||||
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
struct wlr_xdg_popup *wlr_popup = popup->wlr_popup;
|
||||||
|
Client *c = NULL;
|
||||||
|
LayerSurface *l = NULL;
|
||||||
|
int32_t type = -1;
|
||||||
|
|
||||||
if (!wlr_popup || !wlr_popup->parent) {
|
if (!wlr_popup || !wlr_popup->parent) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_scene_node *parent_node = wlr_popup->parent->data;
|
struct wlr_scene_node *parent_node = wlr_popup->parent->data;
|
||||||
if (!parent_node) {
|
if (!parent_node) {
|
||||||
wlr_log(WLR_ERROR, "Popup parent has no scene node");
|
wlr_log(WLR_ERROR, "Popup parent has no scene node");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
int parent_lx, parent_ly;
|
|
||||||
wlr_scene_node_coords(parent_node, &parent_lx, &parent_ly);
|
|
||||||
|
|
||||||
struct wlr_box *scheduled = &wlr_popup->scheduled.geometry;
|
type = toplevel_from_wlr_surface(wlr_popup->base->surface, &c, &l);
|
||||||
int popup_lx = parent_lx + scheduled->x;
|
if ((l && !l->mon) || (c && !c->mon)) {
|
||||||
int popup_ly = parent_ly + scheduled->y;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Monitor *mon = get_monitor_nearest_to(popup_lx, popup_ly);
|
struct wlr_box usable = type == LayerShell ? l->mon->m : c->mon->w;
|
||||||
|
|
||||||
struct wlr_box usable = popup->type == LayerShell ? mon->m : mon->w;
|
int lx, ly;
|
||||||
|
struct wlr_box constraint_box;
|
||||||
|
|
||||||
struct wlr_box constraint_box = {
|
if (type == LayerShell) {
|
||||||
.x = usable.x - parent_lx,
|
wlr_scene_node_coords(&l->scene_layer->tree->node, &lx, &ly);
|
||||||
.y = usable.y - parent_ly,
|
constraint_box.x = usable.x - lx;
|
||||||
.width = usable.width,
|
constraint_box.y = usable.y - ly;
|
||||||
.height = usable.height,
|
constraint_box.width = usable.width;
|
||||||
};
|
constraint_box.height = usable.height;
|
||||||
|
} else {
|
||||||
|
constraint_box.x =
|
||||||
|
usable.x - (c->geom.x + c->bw - c->surface.xdg->current.geometry.x);
|
||||||
|
constraint_box.y =
|
||||||
|
usable.y - (c->geom.y + c->bw - c->surface.xdg->current.geometry.y);
|
||||||
|
constraint_box.width = usable.width;
|
||||||
|
constraint_box.height = usable.height;
|
||||||
|
}
|
||||||
|
|
||||||
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &constraint_box);
|
wlr_xdg_popup_unconstrain_from_box(wlr_popup, &constraint_box);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroypopup(struct wl_listener *listener, void *data) {
|
static void destroypopup(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -2596,44 +2646,40 @@ static void commitpopup(struct wl_listener *listener, void *data) {
|
||||||
Popup *popup = wl_container_of(listener, popup, commit);
|
Popup *popup = wl_container_of(listener, popup, commit);
|
||||||
|
|
||||||
struct wlr_surface *surface = data;
|
struct wlr_surface *surface = data;
|
||||||
struct wlr_xdg_popup *wkr_popup =
|
bool should_destroy = false;
|
||||||
|
struct wlr_xdg_popup *wlr_popup =
|
||||||
wlr_xdg_popup_try_from_wlr_surface(surface);
|
wlr_xdg_popup_try_from_wlr_surface(surface);
|
||||||
|
|
||||||
Client *c = NULL;
|
if (!wlr_popup->base->initial_commit)
|
||||||
LayerSurface *l = NULL;
|
return;
|
||||||
int32_t type = -1;
|
|
||||||
|
|
||||||
if (!wkr_popup || !wkr_popup->base->initial_commit)
|
if (!wlr_popup->parent || !wlr_popup->parent->data) {
|
||||||
goto commitpopup_listen_free;
|
should_destroy = true;
|
||||||
|
goto cleanup_popup_commit;
|
||||||
type = toplevel_from_wlr_surface(wkr_popup->base->surface, &c, &l);
|
|
||||||
if (!wkr_popup->parent || !wkr_popup->parent->data || type < 0) {
|
|
||||||
wlr_xdg_popup_destroy(wkr_popup);
|
|
||||||
goto commitpopup_listen_free;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_scene_node_raise_to_top(wkr_popup->parent->data);
|
wlr_scene_node_raise_to_top(wlr_popup->parent->data);
|
||||||
|
|
||||||
wkr_popup->base->surface->data =
|
wlr_popup->base->surface->data =
|
||||||
wlr_scene_xdg_surface_create(wkr_popup->parent->data, wkr_popup->base);
|
wlr_scene_xdg_surface_create(wlr_popup->parent->data, wlr_popup->base);
|
||||||
if ((l && !l->mon) || (c && !c->mon)) {
|
|
||||||
wlr_xdg_popup_destroy(wkr_popup);
|
|
||||||
goto commitpopup_listen_free;
|
|
||||||
}
|
|
||||||
|
|
||||||
popup->type = type;
|
popup->wlr_popup = wlr_popup;
|
||||||
popup->wlr_popup = wkr_popup;
|
|
||||||
|
|
||||||
popup_unconstrain(popup);
|
should_destroy = popup_unconstrain(popup);
|
||||||
|
|
||||||
|
cleanup_popup_commit:
|
||||||
|
|
||||||
commitpopup_listen_free:
|
|
||||||
wl_list_remove(&popup->commit.link);
|
wl_list_remove(&popup->commit.link);
|
||||||
popup->commit.notify = NULL;
|
popup->commit.notify = NULL;
|
||||||
|
|
||||||
|
if (should_destroy) {
|
||||||
|
wlr_xdg_popup_destroy(wlr_popup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void repositionpopup(struct wl_listener *listener, void *data) {
|
static void repositionpopup(struct wl_listener *listener, void *data) {
|
||||||
Popup *popup = wl_container_of(listener, popup, reposition);
|
Popup *popup = wl_container_of(listener, popup, reposition);
|
||||||
popup_unconstrain(popup);
|
(void)popup_unconstrain(popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void createpopup(struct wl_listener *listener, void *data) {
|
static void createpopup(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -2846,18 +2892,59 @@ void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule) {
|
||||||
|
if (rule->name != NULL && !regex_match(rule->name, m->wlr_output->name))
|
||||||
|
return false;
|
||||||
|
if (rule->make != NULL && (m->wlr_output->make == NULL ||
|
||||||
|
strcmp(rule->make, m->wlr_output->make) != 0))
|
||||||
|
return false;
|
||||||
|
if (rule->model != NULL && (m->wlr_output->model == NULL ||
|
||||||
|
strcmp(rule->model, m->wlr_output->model) != 0))
|
||||||
|
return false;
|
||||||
|
if (rule->serial != NULL &&
|
||||||
|
(m->wlr_output->serial == NULL ||
|
||||||
|
strcmp(rule->serial, m->wlr_output->serial) != 0))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 将规则中的显示参数应用到 wlr_output_state 中,返回是否设置了自定义模式 */
|
||||||
|
bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
|
||||||
|
struct wlr_output_state *state, int vrr, int custom) {
|
||||||
|
bool mode_set = false;
|
||||||
|
if (rule->width > 0 && rule->height > 0 && rule->refresh > 0) {
|
||||||
|
struct wlr_output_mode *internal_mode = get_nearest_output_mode(
|
||||||
|
m->wlr_output, rule->width, rule->height, rule->refresh);
|
||||||
|
if (internal_mode) {
|
||||||
|
wlr_output_state_set_mode(state, internal_mode);
|
||||||
|
mode_set = true;
|
||||||
|
} else if (custom || wlr_output_is_headless(m->wlr_output)) {
|
||||||
|
wlr_output_state_set_custom_mode(
|
||||||
|
state, rule->width, rule->height,
|
||||||
|
(int32_t)roundf(rule->refresh * 1000));
|
||||||
|
mode_set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vrr) {
|
||||||
|
enable_adaptive_sync(m, state);
|
||||||
|
} else {
|
||||||
|
wlr_output_state_set_adaptive_sync_enabled(state, false);
|
||||||
|
}
|
||||||
|
wlr_output_state_set_scale(state, rule->scale);
|
||||||
|
wlr_output_state_set_transform(state, rule->rr);
|
||||||
|
return mode_set;
|
||||||
|
}
|
||||||
|
|
||||||
void createmon(struct wl_listener *listener, void *data) {
|
void createmon(struct wl_listener *listener, void *data) {
|
||||||
/* This event is raised by the backend when a new output (aka a display or
|
/* This event is raised by the backend when a new output (aka a display or
|
||||||
* monitor) becomes available. */
|
* monitor) becomes available. */
|
||||||
struct wlr_output *wlr_output = data;
|
struct wlr_output *wlr_output = data;
|
||||||
const ConfigMonitorRule *r;
|
const ConfigMonitorRule *r;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int32_t ji, vrr;
|
int32_t ji, vrr, custom;
|
||||||
struct wlr_output_state state;
|
struct wlr_output_state state;
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
struct wlr_output_mode *internal_mode = NULL;
|
|
||||||
bool custom_monitor_mode = false;
|
bool custom_monitor_mode = false;
|
||||||
bool match_rule = false;
|
|
||||||
|
|
||||||
if (!wlr_output_init_render(wlr_output, alloc, drw))
|
if (!wlr_output_init_render(wlr_output, alloc, drw))
|
||||||
return;
|
return;
|
||||||
|
|
@ -2887,7 +2974,6 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
for (i = 0; i < LENGTH(m->layers); i++)
|
for (i = 0; i < LENGTH(m->layers); i++)
|
||||||
wl_list_init(&m->layers[i]);
|
wl_list_init(&m->layers[i]);
|
||||||
|
|
||||||
wlr_output_state_init(&state);
|
|
||||||
/* Initialize monitor state using configured rules */
|
/* Initialize monitor state using configured rules */
|
||||||
m->gappih = gappih;
|
m->gappih = gappih;
|
||||||
m->gappiv = gappiv;
|
m->gappiv = gappiv;
|
||||||
|
|
@ -2900,6 +2986,8 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
m->m.y = INT32_MAX;
|
m->m.y = INT32_MAX;
|
||||||
float scale = 1;
|
float scale = 1;
|
||||||
enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL;
|
enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
|
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_scale(&state, scale);
|
wlr_output_state_set_scale(&state, scale);
|
||||||
wlr_output_state_set_transform(&state, rr);
|
wlr_output_state_set_transform(&state, rr);
|
||||||
|
|
||||||
|
|
@ -2909,74 +2997,21 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
r = &config.monitor_rules[ji];
|
r = &config.monitor_rules[ji];
|
||||||
|
|
||||||
// 检查是否匹配的变量
|
if (monitor_matches_rule(m, r)) {
|
||||||
match_rule = true;
|
|
||||||
|
|
||||||
// 检查四个标识字段的匹配
|
|
||||||
if (r->name != NULL) {
|
|
||||||
if (!regex_match(r->name, m->wlr_output->name)) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->make != NULL) {
|
|
||||||
if (m->wlr_output->make == NULL ||
|
|
||||||
strcmp(r->make, m->wlr_output->make) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->model != NULL) {
|
|
||||||
if (m->wlr_output->model == NULL ||
|
|
||||||
strcmp(r->model, m->wlr_output->model) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->serial != NULL) {
|
|
||||||
if (m->wlr_output->serial == NULL ||
|
|
||||||
strcmp(r->serial, m->wlr_output->serial) != 0) {
|
|
||||||
match_rule = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match_rule) {
|
|
||||||
m->m.x = r->x == INT32_MAX ? INT32_MAX : r->x;
|
m->m.x = r->x == INT32_MAX ? INT32_MAX : r->x;
|
||||||
m->m.y = r->y == INT32_MAX ? INT32_MAX : r->y;
|
m->m.y = r->y == INT32_MAX ? INT32_MAX : r->y;
|
||||||
vrr = r->vrr >= 0 ? r->vrr : 0;
|
vrr = r->vrr >= 0 ? r->vrr : 0;
|
||||||
|
custom = r->custom >= 0 ? r->custom : 0;
|
||||||
scale = r->scale;
|
scale = r->scale;
|
||||||
rr = r->rr;
|
rr = r->rr;
|
||||||
|
|
||||||
if (r->width > 0 && r->height > 0 && r->refresh > 0) {
|
if (apply_rule_to_state(m, r, &state, vrr, custom)) {
|
||||||
internal_mode = get_nearest_output_mode(m->wlr_output, r->width,
|
custom_monitor_mode = true;
|
||||||
r->height, r->refresh);
|
|
||||||
if (internal_mode) {
|
|
||||||
custom_monitor_mode = true;
|
|
||||||
wlr_output_state_set_mode(&state, internal_mode);
|
|
||||||
} else if (wlr_output_is_headless(m->wlr_output)) {
|
|
||||||
custom_monitor_mode = true;
|
|
||||||
wlr_output_state_set_custom_mode(
|
|
||||||
&state, r->width, r->height,
|
|
||||||
(int32_t)roundf(r->refresh * 1000));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
break; // 只应用第一个匹配规则
|
||||||
if (vrr) {
|
|
||||||
enable_adaptive_sync(m, &state);
|
|
||||||
} else {
|
|
||||||
wlr_output_state_set_adaptive_sync_enabled(&state, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_output_state_set_scale(&state, r->scale);
|
|
||||||
wlr_output_state_set_transform(&state, r->rr);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The mode is a tuple of (width, height, refresh rate), and each
|
|
||||||
* monitor supports only a specific set of modes. We just pick the
|
|
||||||
* monitor's preferred mode; a more sophisticated compositor would let
|
|
||||||
* the user configure it. */
|
|
||||||
if (!custom_monitor_mode)
|
if (!custom_monitor_mode)
|
||||||
wlr_output_state_set_mode(&state,
|
wlr_output_state_set_mode(&state,
|
||||||
wlr_output_preferred_mode(wlr_output));
|
wlr_output_preferred_mode(wlr_output));
|
||||||
|
|
@ -3335,8 +3370,7 @@ void destroylocksurface(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
if (lock_surface->surface != seat->keyboard_state.focused_surface) {
|
if (lock_surface->surface != seat->keyboard_state.focused_surface) {
|
||||||
if (exclusive_focus && !locked) {
|
if (exclusive_focus && !locked) {
|
||||||
exclusive_focus = NULL;
|
reset_exclusive_layers_focus(m);
|
||||||
reset_exclusive_layer(m);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3345,9 +3379,7 @@ void destroylocksurface(struct wl_listener *listener, void *data) {
|
||||||
surface = wl_container_of(cur_lock->surfaces.next, surface, link);
|
surface = wl_container_of(cur_lock->surfaces.next, surface, link);
|
||||||
client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
|
client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
|
||||||
} else if (!locked) {
|
} else if (!locked) {
|
||||||
exclusive_focus = NULL;
|
reset_exclusive_layers_focus(selmon);
|
||||||
reset_exclusive_layer(selmon);
|
|
||||||
focusclient(focustop(selmon), 1);
|
|
||||||
} else {
|
} else {
|
||||||
wlr_seat_keyboard_clear_focus(seat);
|
wlr_seat_keyboard_clear_focus(seat);
|
||||||
}
|
}
|
||||||
|
|
@ -3452,6 +3484,8 @@ void focusclient(Client *c, int32_t lift) {
|
||||||
selmon->sel = c;
|
selmon->sel = c;
|
||||||
c->isfocusing = true;
|
c->isfocusing = true;
|
||||||
|
|
||||||
|
check_keep_idle_inhibit(c);
|
||||||
|
|
||||||
if (last_focus_client && !last_focus_client->iskilling &&
|
if (last_focus_client && !last_focus_client->iskilling &&
|
||||||
last_focus_client != c) {
|
last_focus_client != c) {
|
||||||
last_focus_client->isfocusing = false;
|
last_focus_client->isfocusing = false;
|
||||||
|
|
@ -3953,6 +3987,7 @@ void init_client_properties(Client *c) {
|
||||||
c->swallowing = NULL;
|
c->swallowing = NULL;
|
||||||
c->swallowedby = NULL;
|
c->swallowedby = NULL;
|
||||||
c->ismaster = 0;
|
c->ismaster = 0;
|
||||||
|
c->old_ismaster = 0;
|
||||||
c->isleftstack = 0;
|
c->isleftstack = 0;
|
||||||
c->ismaximizescreen = 0;
|
c->ismaximizescreen = 0;
|
||||||
c->isfullscreen = 0;
|
c->isfullscreen = 0;
|
||||||
|
|
@ -3993,12 +4028,16 @@ void init_client_properties(Client *c) {
|
||||||
c->master_mfact_per = 0.0f;
|
c->master_mfact_per = 0.0f;
|
||||||
c->master_inner_per = 0.0f;
|
c->master_inner_per = 0.0f;
|
||||||
c->stack_inner_per = 0.0f;
|
c->stack_inner_per = 0.0f;
|
||||||
|
c->old_stack_inner_per = 1.0f;
|
||||||
|
c->old_master_inner_per = 1.0f;
|
||||||
|
c->old_master_mfact_per = 1.0f;
|
||||||
c->isterm = 0;
|
c->isterm = 0;
|
||||||
c->allow_csd = 0;
|
c->allow_csd = 0;
|
||||||
c->force_maximize = 0;
|
c->force_maximize = 0;
|
||||||
c->force_tiled_state = 1;
|
c->force_tiled_state = 1;
|
||||||
c->force_tearing = 0;
|
c->force_tearing = 0;
|
||||||
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||||
|
c->indleinhibit_when_focus = 0;
|
||||||
c->scroller_proportion_single = 0.0f;
|
c->scroller_proportion_single = 0.0f;
|
||||||
c->float_geom.width = 0;
|
c->float_geom.width = 0;
|
||||||
c->float_geom.height = 0;
|
c->float_geom.height = 0;
|
||||||
|
|
@ -4794,6 +4833,11 @@ void exchange_two_client(Client *c1, Client *c2) {
|
||||||
} else {
|
} else {
|
||||||
arrange(c1->mon, false, false);
|
arrange(c1->mon, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In order to facilitate repeated exchanges for get_focused_stack_client
|
||||||
|
// set c2 focus order behind c1
|
||||||
|
wl_list_remove(&c2->flink);
|
||||||
|
wl_list_insert(&c1->flink, &c2->flink);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_activation_env() {
|
void set_activation_env() {
|
||||||
|
|
@ -4918,10 +4962,21 @@ void setcursor(struct wl_listener *listener, void *data) {
|
||||||
* hardware cursor on the output that it's currently on and continue to
|
* hardware cursor on the output that it's currently on and continue to
|
||||||
* do so as the cursor moves between outputs. */
|
* do so as the cursor moves between outputs. */
|
||||||
if (event->seat_client == seat->pointer_state.focused_client) {
|
if (event->seat_client == seat->pointer_state.focused_client) {
|
||||||
|
/* Clear previous surface destroy listener if any */
|
||||||
|
if (last_cursor.surface &&
|
||||||
|
last_cursor_surface_destroy_listener.link.prev != NULL)
|
||||||
|
wl_list_remove(&last_cursor_surface_destroy_listener.link);
|
||||||
|
|
||||||
last_cursor.shape = 0;
|
last_cursor.shape = 0;
|
||||||
last_cursor.surface = event->surface;
|
last_cursor.surface = event->surface;
|
||||||
last_cursor.hotspot_x = event->hotspot_x;
|
last_cursor.hotspot_x = event->hotspot_x;
|
||||||
last_cursor.hotspot_y = event->hotspot_y;
|
last_cursor.hotspot_y = event->hotspot_y;
|
||||||
|
|
||||||
|
/* Track surface destruction to avoid dangling pointer */
|
||||||
|
if (event->surface)
|
||||||
|
wl_signal_add(&event->surface->events.destroy,
|
||||||
|
&last_cursor_surface_destroy_listener);
|
||||||
|
|
||||||
if (!cursor_hidden)
|
if (!cursor_hidden)
|
||||||
wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x,
|
wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x,
|
||||||
event->hotspot_y);
|
event->hotspot_y);
|
||||||
|
|
@ -5007,6 +5062,10 @@ setfloating(Client *c, int32_t floating) {
|
||||||
restore_size_per(c->mon, c);
|
restore_size_per(c->mon, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->isfloating && !old_floating_state) {
|
||||||
|
save_old_size_per(c->mon);
|
||||||
|
}
|
||||||
|
|
||||||
if (!c->force_maximize)
|
if (!c->force_maximize)
|
||||||
client_set_maximized(c, false);
|
client_set_maximized(c, false);
|
||||||
|
|
||||||
|
|
@ -5093,6 +5152,10 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
||||||
restore_size_per(c->mon, c);
|
restore_size_per(c->mon, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->ismaximizescreen && !old_maximizescreen_state) {
|
||||||
|
save_old_size_per(c->mon);
|
||||||
|
}
|
||||||
|
|
||||||
if (!c->force_maximize && !c->ismaximizescreen) {
|
if (!c->force_maximize && !c->ismaximizescreen) {
|
||||||
client_set_maximized(c, false);
|
client_set_maximized(c, false);
|
||||||
} else if (!c->force_maximize && c->ismaximizescreen) {
|
} else if (!c->force_maximize && c->ismaximizescreen) {
|
||||||
|
|
@ -5164,6 +5227,10 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
|
||||||
restore_size_per(c->mon, c);
|
restore_size_per(c->mon, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->isfullscreen && !old_fullscreen_state) {
|
||||||
|
save_old_size_per(c->mon);
|
||||||
|
}
|
||||||
|
|
||||||
arrange(c->mon, false, false);
|
arrange(c->mon, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5523,6 +5590,9 @@ void setup(void) {
|
||||||
idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy);
|
idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy);
|
||||||
wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &new_idle_inhibitor);
|
wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &new_idle_inhibitor);
|
||||||
|
|
||||||
|
keep_idle_inhibit_source = wl_event_loop_add_timer(
|
||||||
|
wl_display_get_event_loop(dpy), keep_idle_inhibit, NULL);
|
||||||
|
|
||||||
layer_shell = wlr_layer_shell_v1_create(dpy, 4);
|
layer_shell = wlr_layer_shell_v1_create(dpy, 4);
|
||||||
wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface);
|
wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface);
|
||||||
|
|
||||||
|
|
@ -5590,8 +5660,8 @@ void setup(void) {
|
||||||
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
|
cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1);
|
||||||
wl_signal_add(&cursor_shape_mgr->events.request_set_shape,
|
wl_signal_add(&cursor_shape_mgr->events.request_set_shape,
|
||||||
&request_set_cursor_shape);
|
&request_set_cursor_shape);
|
||||||
hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
|
hide_cursor_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
|
||||||
hidecursor, cursor);
|
hidecursor, cursor);
|
||||||
/*
|
/*
|
||||||
* Configures a seat, which is a single "seat" at which a user sits and
|
* Configures a seat, which is a single "seat" at which a user sits and
|
||||||
* operates the computer. This conceptually includes up to one keyboard,
|
* operates the computer. This conceptually includes up to one keyboard,
|
||||||
|
|
@ -5619,6 +5689,8 @@ void setup(void) {
|
||||||
LISTEN_STATIC(&cursor->events.hold_end, hold_end);
|
LISTEN_STATIC(&cursor->events.hold_end, hold_end);
|
||||||
|
|
||||||
seat = wlr_seat_create(dpy, "seat0");
|
seat = wlr_seat_create(dpy, "seat0");
|
||||||
|
|
||||||
|
wl_list_init(&last_cursor_surface_destroy_listener.link);
|
||||||
wl_signal_add(&seat->events.request_set_cursor, &request_cursor);
|
wl_signal_add(&seat->events.request_set_cursor, &request_cursor);
|
||||||
wl_signal_add(&seat->events.request_set_selection, &request_set_sel);
|
wl_signal_add(&seat->events.request_set_selection, &request_set_sel);
|
||||||
wl_signal_add(&seat->events.request_set_primary_selection,
|
wl_signal_add(&seat->events.request_set_primary_selection,
|
||||||
|
|
@ -5808,7 +5880,8 @@ void overview_restore(Client *c, const Arg *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlecursoractivity(void) {
|
void handlecursoractivity(void) {
|
||||||
wl_event_source_timer_update(hide_source, cursor_hide_timeout * 1000);
|
wl_event_source_timer_update(hide_cursor_source,
|
||||||
|
cursor_hide_timeout * 1000);
|
||||||
|
|
||||||
if (!cursor_hidden)
|
if (!cursor_hidden)
|
||||||
return;
|
return;
|
||||||
|
|
@ -5818,7 +5891,7 @@ void handlecursoractivity(void) {
|
||||||
if (last_cursor.shape)
|
if (last_cursor.shape)
|
||||||
wlr_cursor_set_xcursor(cursor, cursor_mgr,
|
wlr_cursor_set_xcursor(cursor, cursor_mgr,
|
||||||
wlr_cursor_shape_v1_name(last_cursor.shape));
|
wlr_cursor_shape_v1_name(last_cursor.shape));
|
||||||
else
|
else if (last_cursor.surface)
|
||||||
wlr_cursor_set_surface(cursor, last_cursor.surface,
|
wlr_cursor_set_surface(cursor, last_cursor.surface,
|
||||||
last_cursor.hotspot_x, last_cursor.hotspot_y);
|
last_cursor.hotspot_x, last_cursor.hotspot_y);
|
||||||
}
|
}
|
||||||
|
|
@ -5829,6 +5902,36 @@ int32_t hidecursor(void *data) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_keep_idle_inhibit(Client *c) {
|
||||||
|
if (c && c->indleinhibit_when_focus && keep_idle_inhibit_source) {
|
||||||
|
wl_event_source_timer_update(keep_idle_inhibit_source, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t keep_idle_inhibit(void *data) {
|
||||||
|
|
||||||
|
if (!idle_inhibit_mgr) {
|
||||||
|
wl_event_source_timer_update(keep_idle_inhibit_source, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session && !session->active) {
|
||||||
|
wl_event_source_timer_update(keep_idle_inhibit_source, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selmon || !selmon->sel || !selmon->sel->indleinhibit_when_focus) {
|
||||||
|
wl_event_source_timer_update(keep_idle_inhibit_source, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seat && idle_notifier) {
|
||||||
|
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||||
|
wl_event_source_timer_update(keep_idle_inhibit_source, 1000);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void unlocksession(struct wl_listener *listener, void *data) {
|
void unlocksession(struct wl_listener *listener, void *data) {
|
||||||
SessionLock *lock = wl_container_of(listener, lock, unlock);
|
SessionLock *lock = wl_container_of(listener, lock, unlock);
|
||||||
destroylock(lock, 1);
|
destroylock(lock, 1);
|
||||||
|
|
@ -5843,17 +5946,20 @@ void unmaplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
init_fadeout_layers(l);
|
init_fadeout_layers(l);
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&l->scene->node, false);
|
wlr_scene_node_set_enabled(&l->scene->node, false);
|
||||||
|
|
||||||
if (l == exclusive_focus)
|
if (l == exclusive_focus)
|
||||||
exclusive_focus = NULL;
|
exclusive_focus = NULL;
|
||||||
|
|
||||||
if (l->layer_surface->output && (l->mon = l->layer_surface->output->data))
|
if (l->layer_surface->output && (l->mon = l->layer_surface->output->data))
|
||||||
arrangelayers(l->mon);
|
arrangelayers(l->mon);
|
||||||
if (l->layer_surface->surface == seat->keyboard_state.focused_surface)
|
|
||||||
focusclient(focustop(selmon), 1);
|
reset_exclusive_layers_focus(l->mon);
|
||||||
|
|
||||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||||
l->being_unmapped = false;
|
|
||||||
layer_flush_blur_background(l);
|
layer_flush_blur_background(l);
|
||||||
wlr_scene_node_destroy(&l->shadow->node);
|
wlr_scene_node_destroy(&l->shadow->node);
|
||||||
l->shadow = NULL;
|
l->shadow = NULL;
|
||||||
|
l->being_unmapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmapnotify(struct wl_listener *listener, void *data) {
|
void unmapnotify(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue