mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-03 06:46:38 -04:00
Merge branch 'main' into spelling_fix
This commit is contained in:
commit
da3830df0f
7 changed files with 319 additions and 85 deletions
13
README.md
13
README.md
|
|
@ -24,18 +24,7 @@ This project's development is based on [dwl](https://codeberg.org/dwl/dwl/).
|
||||||
- Hycov-like overview
|
- Hycov-like overview
|
||||||
- Window effects from scenefx (blur, shadow, corner radius, opacity)
|
- Window effects from scenefx (blur, shadow, corner radius, opacity)
|
||||||
|
|
||||||
Master-Stack Layout
|
https://github.com/user-attachments/assets/bb83004a-0563-4b48-ad89-6461a9b78b1f
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/a9d4776e-b50b-48fb-94ce-651d8a749b8a
|
|
||||||
|
|
||||||
Scroller Layout
|
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/c9bf9415-fad1-4400-bcdc-3ad2d76de85a
|
|
||||||
|
|
||||||
Layer animation
|
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0
|
|
||||||
|
|
||||||
|
|
||||||
# Our discord
|
# Our discord
|
||||||
[mangowc](https://discord.gg/CPjbDxesh5)
|
[mangowc](https://discord.gg/CPjbDxesh5)
|
||||||
|
|
|
||||||
|
|
@ -240,12 +240,11 @@ bind=CTRL+ALT,Left,resizewin,-50,+0
|
||||||
bind=CTRL+ALT,Right,resizewin,+50,+0
|
bind=CTRL+ALT,Right,resizewin,+50,+0
|
||||||
|
|
||||||
# Mouse Button Bindings
|
# Mouse Button Bindings
|
||||||
# NONE mode key only work in ov mode
|
# btn_left and btn_right can't bind none mod key
|
||||||
mousebind=SUPER,btn_left,moveresize,curmove
|
mousebind=SUPER,btn_left,moveresize,curmove
|
||||||
mousebind=NONE,btn_middle,togglemaximizescreen,0
|
mousebind=NONE,btn_middle,togglemaximizescreen,0
|
||||||
mousebind=SUPER,btn_right,moveresize,curresize
|
mousebind=SUPER,btn_right,moveresize,curresize
|
||||||
mousebind=NONE,btn_left,toggleoverview,1
|
|
||||||
mousebind=NONE,btn_right,killclient,0
|
|
||||||
|
|
||||||
# Axis Bindings
|
# Axis Bindings
|
||||||
axisbind=SUPER,UP,viewtoleft_have_client
|
axisbind=SUPER,UP,viewtoleft_have_client
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
project('mango', ['c', 'cpp'],
|
project('mango', ['c', 'cpp'],
|
||||||
version : '0.12.0',
|
version : '0.12.1',
|
||||||
)
|
)
|
||||||
|
|
||||||
subdir('protocols')
|
subdir('protocols')
|
||||||
|
|
|
||||||
46
mmsg/mmsg.c
46
mmsg/mmsg.c
|
|
@ -500,12 +500,48 @@ static const struct wl_registry_listener registry_listener = {
|
||||||
|
|
||||||
static void usage(void) {
|
static void usage(void) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage:"
|
"mmsg - MangoWC IPC\n"
|
||||||
"\t%s [-OTLq]\n"
|
"\n"
|
||||||
"\t%s [-o <output>] -s [-t <tags>] [-l <layout>] [-c <tags>] [-d "
|
"SYNOPSIS:\n"
|
||||||
|
"\tmmsg [-OTLq]\n"
|
||||||
|
"\tmmsg [-o <output>] -s [-t <tags>] [-l <layout>] [-c <tags>] [-d "
|
||||||
"<cmd>,<arg1>,<arg2>,<arg3>,<arg4>,<arg5>]\n"
|
"<cmd>,<arg1>,<arg2>,<arg3>,<arg4>,<arg5>]\n"
|
||||||
"\t%s [-o <output>] (-g | -w) [-OotlcvmfxekbA]\n",
|
"\tmmsg [-o <output>] (-g | -w) [-OotlcvmfxekbA]\n"
|
||||||
argv0, argv0, argv0);
|
"\n"
|
||||||
|
"OPERATION MODES:\n"
|
||||||
|
"\t-g Get values (tags, layout, focused client)\n"
|
||||||
|
"\t-s Set values (switch tags, layouts)\n"
|
||||||
|
"\t-w Watch mode (stream events)\n"
|
||||||
|
"\n"
|
||||||
|
"GENERAL OPTIONS:\n"
|
||||||
|
"\t-O Get all output (monitor) information\n"
|
||||||
|
"\t-T Get number of tags\n"
|
||||||
|
"\t-L Get all available layouts\n"
|
||||||
|
"\t-q Quit MangoWC\n"
|
||||||
|
"\t-o <output> Select output (monitor)\n"
|
||||||
|
"\n"
|
||||||
|
"GET OPTIONS (used with -g or -w):\n"
|
||||||
|
"\t-O Get output name\n"
|
||||||
|
"\t-o Get output (monitor) focus information\n"
|
||||||
|
"\t-t Get selected tags\n"
|
||||||
|
"\t-l Get current layout\n"
|
||||||
|
"\t-c Get title and appid of focused clients\n"
|
||||||
|
"\t-v Get visibility of statusbar\n"
|
||||||
|
"\t-m Get fullscreen status\n"
|
||||||
|
"\t-f Get floating status\n"
|
||||||
|
"\t-x Get focused client geometry\n"
|
||||||
|
"\t-e Get name of last focused layer\n"
|
||||||
|
"\t-k Get current keyboard layout\n"
|
||||||
|
"\t-b Get current keybind mode\n"
|
||||||
|
"\t-A Get scale factor of monitor\n"
|
||||||
|
"\n"
|
||||||
|
"SET OPTIONS (used with -s):\n"
|
||||||
|
"\t-o <output> Select output (monitor)\n"
|
||||||
|
"\t-t <tags> Set selected tags (can be used with [+-^.] "
|
||||||
|
"modifiers)\n"
|
||||||
|
"\t-l <layout> Set current layout\n"
|
||||||
|
"\t-c <tags> Get title and appid of focused client\n"
|
||||||
|
"\t-d <cmd>,<args...> Dispatch internal command (max 5 args)\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ typedef struct {
|
||||||
int32_t isterm;
|
int32_t isterm;
|
||||||
int32_t allow_csd;
|
int32_t allow_csd;
|
||||||
int32_t force_maximize;
|
int32_t force_maximize;
|
||||||
|
int32_t force_tiled_state;
|
||||||
int32_t force_tearing;
|
int32_t force_tearing;
|
||||||
int32_t noswallow;
|
int32_t noswallow;
|
||||||
int32_t noblur;
|
int32_t noblur;
|
||||||
|
|
@ -101,13 +102,14 @@ typedef struct {
|
||||||
} ConfigWinRule;
|
} ConfigWinRule;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name; // Monitor name
|
const char *name; // Monitor name
|
||||||
int32_t rr; // Rotate and flip (assume integer)
|
char *make, *model, *serial; // may be NULL
|
||||||
float scale; // Monitor scale factor
|
int32_t rr; // Rotate and flip (assume integer)
|
||||||
int32_t x, y; // Monitor position
|
float scale; // Monitor scale factor
|
||||||
int32_t width, height; // Monitor resolution
|
int32_t x, y; // Monitor position
|
||||||
float refresh; // Refresh rate
|
int32_t width, height; // Monitor resolution
|
||||||
int32_t vrr; // variable refresh rate
|
float refresh; // Refresh rate
|
||||||
|
int32_t vrr; // variable refresh rate
|
||||||
} ConfigMonitorRule;
|
} ConfigMonitorRule;
|
||||||
|
|
||||||
// 修改后的宏定义
|
// 修改后的宏定义
|
||||||
|
|
@ -157,6 +159,9 @@ typedef struct {
|
||||||
int32_t id;
|
int32_t id;
|
||||||
char *layout_name;
|
char *layout_name;
|
||||||
char *monitor_name;
|
char *monitor_name;
|
||||||
|
char *monitor_make;
|
||||||
|
char *monitor_model;
|
||||||
|
char *monitor_serial;
|
||||||
float mfact;
|
float mfact;
|
||||||
int32_t nmaster;
|
int32_t nmaster;
|
||||||
int32_t no_render_border;
|
int32_t no_render_border;
|
||||||
|
|
@ -362,7 +367,7 @@ typedef struct {
|
||||||
typedef int32_t (*FuncType)(const Arg *);
|
typedef int32_t (*FuncType)(const Arg *);
|
||||||
Config config;
|
Config config;
|
||||||
|
|
||||||
void parse_config_file(Config *config, const char *file_path);
|
bool parse_config_file(Config *config, const char *file_path, bool must_exist);
|
||||||
|
|
||||||
// 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) {
|
||||||
|
|
@ -1774,6 +1779,9 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
|
|
||||||
// 设置默认值
|
// 设置默认值
|
||||||
rule->name = NULL;
|
rule->name = NULL;
|
||||||
|
rule->make = NULL;
|
||||||
|
rule->model = NULL;
|
||||||
|
rule->serial = NULL;
|
||||||
rule->rr = 0;
|
rule->rr = 0;
|
||||||
rule->scale = 1.0f;
|
rule->scale = 1.0f;
|
||||||
rule->x = INT32_MAX;
|
rule->x = INT32_MAX;
|
||||||
|
|
@ -1797,6 +1805,12 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
|
|
||||||
if (strcmp(key, "name") == 0) {
|
if (strcmp(key, "name") == 0) {
|
||||||
rule->name = strdup(val);
|
rule->name = strdup(val);
|
||||||
|
} else if (strcmp(key, "make") == 0) {
|
||||||
|
rule->make = strdup(val);
|
||||||
|
} else if (strcmp(key, "model") == 0) {
|
||||||
|
rule->model = strdup(val);
|
||||||
|
} else if (strcmp(key, "serial") == 0) {
|
||||||
|
rule->serial = strdup(val);
|
||||||
} else if (strcmp(key, "rr") == 0) {
|
} else if (strcmp(key, "rr") == 0) {
|
||||||
rule->rr = CLAMP_INT(atoi(val), 0, 7);
|
rule->rr = CLAMP_INT(atoi(val), 0, 7);
|
||||||
} else if (strcmp(key, "scale") == 0) {
|
} else if (strcmp(key, "scale") == 0) {
|
||||||
|
|
@ -1845,6 +1859,9 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->id = 0;
|
rule->id = 0;
|
||||||
rule->layout_name = NULL;
|
rule->layout_name = NULL;
|
||||||
rule->monitor_name = NULL;
|
rule->monitor_name = NULL;
|
||||||
|
rule->monitor_make = NULL;
|
||||||
|
rule->monitor_model = NULL;
|
||||||
|
rule->monitor_serial = NULL;
|
||||||
rule->nmaster = 0;
|
rule->nmaster = 0;
|
||||||
rule->mfact = 0.0f;
|
rule->mfact = 0.0f;
|
||||||
rule->no_render_border = 0;
|
rule->no_render_border = 0;
|
||||||
|
|
@ -1868,6 +1885,12 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->layout_name = strdup(val);
|
rule->layout_name = strdup(val);
|
||||||
} else if (strcmp(key, "monitor_name") == 0) {
|
} else if (strcmp(key, "monitor_name") == 0) {
|
||||||
rule->monitor_name = strdup(val);
|
rule->monitor_name = strdup(val);
|
||||||
|
} else if (strcmp(key, "monitor_make") == 0) {
|
||||||
|
rule->monitor_make = strdup(val);
|
||||||
|
} else if (strcmp(key, "monitor_model") == 0) {
|
||||||
|
rule->monitor_model = strdup(val);
|
||||||
|
} else if (strcmp(key, "monitor_serial") == 0) {
|
||||||
|
rule->monitor_serial = strdup(val);
|
||||||
} else if (strcmp(key, "no_render_border") == 0) {
|
} else if (strcmp(key, "no_render_border") == 0) {
|
||||||
rule->no_render_border = CLAMP_INT(atoi(val), 0, 1);
|
rule->no_render_border = CLAMP_INT(atoi(val), 0, 1);
|
||||||
} else if (strcmp(key, "no_hide") == 0) {
|
} else if (strcmp(key, "no_hide") == 0) {
|
||||||
|
|
@ -1989,6 +2012,7 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->isterm = -1;
|
rule->isterm = -1;
|
||||||
rule->allow_csd = -1;
|
rule->allow_csd = -1;
|
||||||
rule->force_maximize = -1;
|
rule->force_maximize = -1;
|
||||||
|
rule->force_tiled_state = -1;
|
||||||
rule->force_tearing = -1;
|
rule->force_tearing = -1;
|
||||||
rule->noswallow = -1;
|
rule->noswallow = -1;
|
||||||
rule->noblur = -1;
|
rule->noblur = -1;
|
||||||
|
|
@ -2101,6 +2125,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
rule->allow_csd = atoi(val);
|
rule->allow_csd = atoi(val);
|
||||||
} else if (strcmp(key, "force_maximize") == 0) {
|
} else if (strcmp(key, "force_maximize") == 0) {
|
||||||
rule->force_maximize = atoi(val);
|
rule->force_maximize = atoi(val);
|
||||||
|
} else if (strcmp(key, "force_tiled_state") == 0) {
|
||||||
|
rule->force_tiled_state = atoi(val);
|
||||||
} else if (strcmp(key, "force_tearing") == 0) {
|
} else if (strcmp(key, "force_tearing") == 0) {
|
||||||
rule->force_tearing = atoi(val);
|
rule->force_tearing = atoi(val);
|
||||||
} else if (strcmp(key, "noswallow") == 0) {
|
} else if (strcmp(key, "noswallow") == 0) {
|
||||||
|
|
@ -2359,6 +2385,17 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
binding->arg.v = NULL;
|
binding->arg.v = NULL;
|
||||||
binding->arg.v2 = NULL;
|
binding->arg.v2 = NULL;
|
||||||
binding->arg.v3 = NULL;
|
binding->arg.v3 = NULL;
|
||||||
|
|
||||||
|
// TODO: remove this in next version
|
||||||
|
if (binding->mod == 0 &&
|
||||||
|
(binding->button == BTN_LEFT || binding->button == BTN_RIGHT)) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m \033[31m%s\033[33m can't "
|
||||||
|
"bind to \033[31m%s\033[33m mod key\n",
|
||||||
|
button_str, mod_str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
binding->func =
|
binding->func =
|
||||||
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
parse_func_name(func_name, &binding->arg, arg_value, arg_value2,
|
||||||
arg_value3, arg_value4, arg_value5);
|
arg_value3, arg_value4, arg_value5);
|
||||||
|
|
@ -2376,6 +2413,7 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
free(binding->arg.v3);
|
free(binding->arg.v3);
|
||||||
binding->arg.v3 = NULL;
|
binding->arg.v3 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!binding->func)
|
if (!binding->func)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
||||||
|
|
@ -2610,8 +2648,10 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
config->gesture_bindings_count++;
|
config->gesture_bindings_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (strncmp(key, "source-optional", 15) == 0) {
|
||||||
|
parse_config_file(config, value, false);
|
||||||
} else if (strncmp(key, "source", 6) == 0) {
|
} else if (strncmp(key, "source", 6) == 0) {
|
||||||
parse_config_file(config, value);
|
parse_config_file(config, value, true);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown keyword: "
|
"\033[1m\033[31m[ERROR]:\033[33m Unknown keyword: "
|
||||||
|
|
@ -2639,7 +2679,7 @@ bool parse_config_line(Config *config, const char *line) {
|
||||||
return parse_option(config, key, value);
|
return parse_option(config, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_config_file(Config *config, const char *file_path) {
|
bool parse_config_file(Config *config, const char *file_path, bool must_exist) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
char full_path[1024];
|
char full_path[1024];
|
||||||
|
|
||||||
|
|
@ -2658,7 +2698,7 @@ void parse_config_file(Config *config, const char *file_path) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\033[1m\033[31m[ERROR]:\033[33m HOME environment "
|
"\033[1m\033[31m[ERROR]:\033[33m HOME environment "
|
||||||
"variable not set.\n");
|
"variable not set.\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
snprintf(full_path, sizeof(full_path), "%s/.config/mango/%s", home,
|
snprintf(full_path, sizeof(full_path), "%s/.config/mango/%s", home,
|
||||||
file_path + 1);
|
file_path + 1);
|
||||||
|
|
@ -2673,7 +2713,7 @@ void parse_config_file(Config *config, const char *file_path) {
|
||||||
if (!home) {
|
if (!home) {
|
||||||
fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m HOME environment "
|
fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m HOME environment "
|
||||||
"variable not set.\n");
|
"variable not set.\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
snprintf(full_path, sizeof(full_path), "%s%s", home, file_path + 1);
|
snprintf(full_path, sizeof(full_path), "%s%s", home, file_path + 1);
|
||||||
file = fopen(full_path, "r");
|
file = fopen(full_path, "r");
|
||||||
|
|
@ -2684,23 +2724,29 @@ void parse_config_file(Config *config, const char *file_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
fprintf(stderr,
|
if (must_exist) {
|
||||||
"\033[1;31m\033[1;33m[ERROR]:\033[0m Failed to open "
|
fprintf(stderr,
|
||||||
"config file: %s\n",
|
"\033[1;31m\033[1;33m[ERROR]:\033[0m Failed to open "
|
||||||
file_path);
|
"config file: %s\n",
|
||||||
return;
|
file_path);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char line[512];
|
char line[512];
|
||||||
bool parse_correct = true;
|
bool parse_correct = true;
|
||||||
|
bool parse_line_correct = true;
|
||||||
uint32_t line_count = 0;
|
uint32_t line_count = 0;
|
||||||
while (fgets(line, sizeof(line), file)) {
|
while (fgets(line, sizeof(line), file)) {
|
||||||
line_count++;
|
line_count++;
|
||||||
if (line[0] == '#' || line[0] == '\n') {
|
if (line[0] == '#' || line[0] == '\n') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
parse_correct = parse_config_line(config, line);
|
parse_line_correct = parse_config_line(config, line);
|
||||||
if (!parse_correct) {
|
if (!parse_line_correct) {
|
||||||
|
parse_correct = false;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\033[1;31m╰─\033[1;33m[Index]\033[0m "
|
"\033[1;31m╰─\033[1;33m[Index]\033[0m "
|
||||||
"\033[1;36m%s\033[0m:\033[1;35m%d\033[0m\n"
|
"\033[1;36m%s\033[0m:\033[1;35m%d\033[0m\n"
|
||||||
|
|
@ -2710,6 +2756,7 @@ void parse_config_file(Config *config, const char *file_path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
return parse_correct;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_circle_layout(Config *config) {
|
void free_circle_layout(Config *config) {
|
||||||
|
|
@ -2904,6 +2951,12 @@ void free_config(void) {
|
||||||
free((void *)config.tag_rules[i].layout_name);
|
free((void *)config.tag_rules[i].layout_name);
|
||||||
if (config.tag_rules[i].monitor_name)
|
if (config.tag_rules[i].monitor_name)
|
||||||
free((void *)config.tag_rules[i].monitor_name);
|
free((void *)config.tag_rules[i].monitor_name);
|
||||||
|
if (config.tag_rules[i].monitor_make)
|
||||||
|
free((void *)config.tag_rules[i].monitor_make);
|
||||||
|
if (config.tag_rules[i].monitor_model)
|
||||||
|
free((void *)config.tag_rules[i].monitor_model);
|
||||||
|
if (config.tag_rules[i].monitor_serial)
|
||||||
|
free((void *)config.tag_rules[i].monitor_serial);
|
||||||
}
|
}
|
||||||
free(config.tag_rules);
|
free(config.tag_rules);
|
||||||
config.tag_rules = NULL;
|
config.tag_rules = NULL;
|
||||||
|
|
@ -2915,6 +2968,12 @@ void free_config(void) {
|
||||||
for (int32_t i = 0; i < config.monitor_rules_count; i++) {
|
for (int32_t i = 0; i < config.monitor_rules_count; i++) {
|
||||||
if (config.monitor_rules[i].name)
|
if (config.monitor_rules[i].name)
|
||||||
free((void *)config.monitor_rules[i].name);
|
free((void *)config.monitor_rules[i].name);
|
||||||
|
if (config.monitor_rules[i].make)
|
||||||
|
free((void *)config.monitor_rules[i].make);
|
||||||
|
if (config.monitor_rules[i].model)
|
||||||
|
free((void *)config.monitor_rules[i].model);
|
||||||
|
if (config.monitor_rules[i].serial)
|
||||||
|
free((void *)config.monitor_rules[i].serial);
|
||||||
}
|
}
|
||||||
free(config.monitor_rules);
|
free(config.monitor_rules);
|
||||||
config.monitor_rules = NULL;
|
config.monitor_rules = NULL;
|
||||||
|
|
@ -3369,7 +3428,7 @@ void set_default_key_bindings(Config *config) {
|
||||||
config->key_bindings_count += default_key_bindings_count;
|
config->key_bindings_count += default_key_bindings_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_config(void) {
|
bool parse_config(void) {
|
||||||
|
|
||||||
char filename[1024];
|
char filename[1024];
|
||||||
|
|
||||||
|
|
@ -3422,7 +3481,7 @@ void parse_config(void) {
|
||||||
const char *homedir = getenv("HOME");
|
const char *homedir = getenv("HOME");
|
||||||
if (!homedir) {
|
if (!homedir) {
|
||||||
// 如果获取失败,则无法继续
|
// 如果获取失败,则无法继续
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
// 构建日志文件路径
|
// 构建日志文件路径
|
||||||
snprintf(filename, sizeof(filename), "%s/.config/mango/config.conf",
|
snprintf(filename, sizeof(filename), "%s/.config/mango/config.conf",
|
||||||
|
|
@ -3436,10 +3495,12 @@ void parse_config(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool parse_correct = true;
|
||||||
set_value_default();
|
set_value_default();
|
||||||
parse_config_file(&config, filename);
|
parse_correct = parse_config_file(&config, filename, true);
|
||||||
set_default_key_bindings(&config);
|
set_default_key_bindings(&config);
|
||||||
override_config();
|
override_config();
|
||||||
|
return parse_correct;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_blur_params(void) {
|
void reset_blur_params(void) {
|
||||||
|
|
@ -3477,6 +3538,7 @@ void reapply_monitor_rules(void) {
|
||||||
struct wlr_output_state state;
|
struct wlr_output_state state;
|
||||||
struct wlr_output_mode *internal_mode = NULL;
|
struct wlr_output_mode *internal_mode = NULL;
|
||||||
wlr_output_state_init(&state);
|
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) {
|
||||||
|
|
@ -3488,8 +3550,40 @@ void reapply_monitor_rules(void) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mr = &config.monitor_rules[ji];
|
mr = &config.monitor_rules[ji];
|
||||||
if (regex_match(mr->name, m->wlr_output->name)) {
|
|
||||||
|
|
||||||
|
// 检查是否匹配的变量
|
||||||
|
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;
|
||||||
|
|
@ -3623,6 +3717,7 @@ void parse_tagrule(Monitor *m) {
|
||||||
int32_t i, jk;
|
int32_t i, jk;
|
||||||
ConfigTagRule tr;
|
ConfigTagRule tr;
|
||||||
Client *c = NULL;
|
Client *c = NULL;
|
||||||
|
bool match_rule = false;
|
||||||
|
|
||||||
for (i = 0; i <= LENGTH(tags); i++) {
|
for (i = 0; i <= LENGTH(tags); i++) {
|
||||||
m->pertag->nmasters[i] = default_nmaster;
|
m->pertag->nmasters[i] = default_nmaster;
|
||||||
|
|
@ -3633,9 +3728,36 @@ void parse_tagrule(Monitor *m) {
|
||||||
|
|
||||||
tr = config.tag_rules[i];
|
tr = config.tag_rules[i];
|
||||||
|
|
||||||
if (config.tag_rules_count > 0 &&
|
match_rule = true;
|
||||||
(!tr.monitor_name ||
|
|
||||||
regex_match(tr.monitor_name, m->wlr_output->name))) {
|
if (tr.monitor_name != NULL) {
|
||||||
|
if (!regex_match(tr.monitor_name, m->wlr_output->name)) {
|
||||||
|
match_rule = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tr.monitor_make != NULL) {
|
||||||
|
if (m->wlr_output->make == NULL ||
|
||||||
|
strcmp(tr.monitor_make, m->wlr_output->make) != 0) {
|
||||||
|
match_rule = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tr.monitor_model != NULL) {
|
||||||
|
if (m->wlr_output->model == NULL ||
|
||||||
|
strcmp(tr.monitor_model, m->wlr_output->model) != 0) {
|
||||||
|
match_rule = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tr.monitor_serial != NULL) {
|
||||||
|
if (m->wlr_output->serial == NULL ||
|
||||||
|
strcmp(tr.monitor_serial, m->wlr_output->serial) != 0) {
|
||||||
|
match_rule = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.tag_rules_count > 0 && match_rule) {
|
||||||
|
|
||||||
for (jk = 0; jk < LENGTH(layouts); jk++) {
|
for (jk = 0; jk < LENGTH(layouts); jk++) {
|
||||||
if (tr.layout_name &&
|
if (tr.layout_name &&
|
||||||
|
|
|
||||||
|
|
@ -907,9 +907,7 @@ int32_t switch_keyboard_layout(const Arg *arg) {
|
||||||
uint32_t latched = keyboard->modifiers.latched;
|
uint32_t latched = keyboard->modifiers.latched;
|
||||||
uint32_t locked = keyboard->modifiers.locked;
|
uint32_t locked = keyboard->modifiers.locked;
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(keyboard, keyboard->keymap);
|
|
||||||
wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, next);
|
wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, next);
|
||||||
keyboard->modifiers.group = 0;
|
|
||||||
|
|
||||||
// 7. 更新 seat
|
// 7. 更新 seat
|
||||||
wlr_seat_set_keyboard(seat, keyboard);
|
wlr_seat_set_keyboard(seat, keyboard);
|
||||||
|
|
@ -923,10 +921,7 @@ int32_t switch_keyboard_layout(const Arg *arg) {
|
||||||
|
|
||||||
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(tkb, keyboard->keymap);
|
|
||||||
wlr_keyboard_notify_modifiers(tkb, depressed, latched, locked, next);
|
wlr_keyboard_notify_modifiers(tkb, depressed, latched, locked, next);
|
||||||
tkb->modifiers.group = 0;
|
|
||||||
|
|
||||||
// 7. 更新 seat
|
// 7. 更新 seat
|
||||||
wlr_seat_set_keyboard(seat, tkb);
|
wlr_seat_set_keyboard(seat, tkb);
|
||||||
wlr_seat_keyboard_notify_modifiers(seat, &tkb->modifiers);
|
wlr_seat_keyboard_notify_modifiers(seat, &tkb->modifiers);
|
||||||
|
|
|
||||||
159
src/mango.c
159
src/mango.c
|
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
||||||
#include "wlr/util/box.h"
|
#include "wlr/util/box.h"
|
||||||
|
#include "wlr/util/edges.h"
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
@ -390,6 +391,7 @@ struct Client {
|
||||||
int32_t isterm, noswallow;
|
int32_t isterm, noswallow;
|
||||||
int32_t allow_csd;
|
int32_t allow_csd;
|
||||||
int32_t force_maximize;
|
int32_t force_maximize;
|
||||||
|
int32_t force_tiled_state;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
Client *swallowing, *swallowedby;
|
Client *swallowing, *swallowedby;
|
||||||
bool is_clip_to_hide;
|
bool is_clip_to_hide;
|
||||||
|
|
@ -942,6 +944,8 @@ static struct wl_listener keyboard_shortcuts_inhibit_new_inhibitor = {
|
||||||
.notify = handle_keyboard_shortcuts_inhibit_new_inhibitor};
|
.notify = handle_keyboard_shortcuts_inhibit_new_inhibitor};
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
|
static void fix_xwayland_unmanaged_coordinate(Client *c);
|
||||||
|
static int32_t synckeymap(void *data);
|
||||||
static void activatex11(struct wl_listener *listener, void *data);
|
static void activatex11(struct wl_listener *listener, void *data);
|
||||||
static void configurex11(struct wl_listener *listener, void *data);
|
static void configurex11(struct wl_listener *listener, void *data);
|
||||||
static void createnotifyx11(struct wl_listener *listener, void *data);
|
static void createnotifyx11(struct wl_listener *listener, void *data);
|
||||||
|
|
@ -953,6 +957,7 @@ static void setgeometrynotify(struct wl_listener *listener, void *data);
|
||||||
static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11};
|
static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11};
|
||||||
static struct wl_listener xwayland_ready = {.notify = xwaylandready};
|
static struct wl_listener xwayland_ready = {.notify = xwaylandready};
|
||||||
static struct wlr_xwayland *xwayland;
|
static struct wlr_xwayland *xwayland;
|
||||||
|
static struct wl_event_source *sync_keymap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "animation/client.h"
|
#include "animation/client.h"
|
||||||
|
|
@ -1281,6 +1286,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) {
|
||||||
APPLY_INT_PROP(c, r, isterm);
|
APPLY_INT_PROP(c, r, isterm);
|
||||||
APPLY_INT_PROP(c, r, allow_csd);
|
APPLY_INT_PROP(c, r, allow_csd);
|
||||||
APPLY_INT_PROP(c, r, force_maximize);
|
APPLY_INT_PROP(c, r, force_maximize);
|
||||||
|
APPLY_INT_PROP(c, r, force_tiled_state);
|
||||||
APPLY_INT_PROP(c, r, force_tearing);
|
APPLY_INT_PROP(c, r, force_tearing);
|
||||||
APPLY_INT_PROP(c, r, noswallow);
|
APPLY_INT_PROP(c, r, noswallow);
|
||||||
APPLY_INT_PROP(c, r, nofocus);
|
APPLY_INT_PROP(c, r, nofocus);
|
||||||
|
|
@ -1369,6 +1375,14 @@ void applyrules(Client *c) {
|
||||||
Monitor *mon = parent && parent->mon ? parent->mon : selmon;
|
Monitor *mon = parent && parent->mon ? parent->mon : selmon;
|
||||||
|
|
||||||
c->isfloating = client_is_float_type(c) || parent;
|
c->isfloating = client_is_float_type(c) || parent;
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (c->isfloating && client_is_x11(c)) {
|
||||||
|
fix_xwayland_unmanaged_coordinate(c);
|
||||||
|
c->float_geom = c->geom;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(appid = client_get_appid(c)))
|
if (!(appid = client_get_appid(c)))
|
||||||
appid = broken;
|
appid = broken;
|
||||||
if (!(title = client_get_title(c)))
|
if (!(title = client_get_title(c)))
|
||||||
|
|
@ -1996,14 +2010,21 @@ buttonpress(struct wl_listener *listener, void *data) {
|
||||||
if (config.mouse_bindings_count < 1)
|
if (config.mouse_bindings_count < 1)
|
||||||
break;
|
break;
|
||||||
m = &config.mouse_bindings[ji];
|
m = &config.mouse_bindings[ji];
|
||||||
|
|
||||||
|
if (selmon->isoverview && event->button == BTN_LEFT && c) {
|
||||||
|
toggleoverview(&(Arg){.i = 1});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selmon->isoverview && event->button == BTN_RIGHT && c) {
|
||||||
|
pending_kill_client(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (CLEANMASK(mods) == CLEANMASK(m->mod) &&
|
if (CLEANMASK(mods) == CLEANMASK(m->mod) &&
|
||||||
event->button == m->button && m->func &&
|
event->button == m->button && m->func &&
|
||||||
(selmon->isoverview == 1 || m->button == BTN_MIDDLE) && c) {
|
(CLEANMASK(m->mod) != 0 ||
|
||||||
m->func(&m->arg);
|
(event->button != BTN_LEFT && event->button != BTN_RIGHT))) {
|
||||||
return;
|
|
||||||
} else if (CLEANMASK(mods) == CLEANMASK(m->mod) &&
|
|
||||||
event->button == m->button && m->func &&
|
|
||||||
CLEANMASK(m->mod) != 0) {
|
|
||||||
m->func(&m->arg);
|
m->func(&m->arg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2429,9 +2450,6 @@ void commitnotify(struct wl_listener *listener, void *data) {
|
||||||
setmon(c, NULL, 0,
|
setmon(c, NULL, 0,
|
||||||
true); /* Make sure to reapply rules in mapnotify() */
|
true); /* Make sure to reapply rules in mapnotify() */
|
||||||
|
|
||||||
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
|
||||||
WLR_EDGE_RIGHT);
|
|
||||||
|
|
||||||
uint32_t serial = wlr_xdg_surface_schedule_configure(c->surface.xdg);
|
uint32_t serial = wlr_xdg_surface_schedule_configure(c->surface.xdg);
|
||||||
if (serial > 0) {
|
if (serial > 0) {
|
||||||
c->configure_serial = serial;
|
c->configure_serial = serial;
|
||||||
|
|
@ -2728,6 +2746,7 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
Monitor *m = NULL;
|
Monitor *m = NULL;
|
||||||
struct wlr_output_mode *internal_mode = 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;
|
||||||
|
|
@ -2768,7 +2787,39 @@ void createmon(struct wl_listener *listener, void *data) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
r = &config.monitor_rules[ji];
|
r = &config.monitor_rules[ji];
|
||||||
if (regex_match(r->name, wlr_output->name)) {
|
|
||||||
|
// 检查是否匹配的变量
|
||||||
|
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;
|
||||||
|
|
@ -3419,7 +3470,10 @@ void requestmonstate(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
void inputdevice(struct wl_listener *listener, void *data) {
|
void inputdevice(struct wl_listener *listener, void *data) {
|
||||||
/* This event is raised by the backend when a new input device becomes
|
/* This event is raised by the backend when a new input device becomes
|
||||||
* available. */
|
* available.
|
||||||
|
* when the backend is a headless backend, this event will never be
|
||||||
|
* triggered.
|
||||||
|
*/
|
||||||
struct wlr_input_device *device = data;
|
struct wlr_input_device *device = data;
|
||||||
uint32_t caps;
|
uint32_t caps;
|
||||||
|
|
||||||
|
|
@ -3490,11 +3544,6 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym,
|
||||||
int32_t ji;
|
int32_t ji;
|
||||||
int32_t isbreak = 0;
|
int32_t isbreak = 0;
|
||||||
|
|
||||||
// not allow modifier keys to be used as a keybinding
|
|
||||||
if (keycode == 50 || keycode == 37 || keycode == 133 || keycode == 64 ||
|
|
||||||
keycode == 62 || keycode == 108 || keycode == 105 || keycode == 134)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (is_keyboard_shortcut_inhibitor(seat->keyboard_state.focused_surface)) {
|
if (is_keyboard_shortcut_inhibitor(seat->keyboard_state.focused_surface)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -3816,6 +3865,7 @@ void init_client_properties(Client *c) {
|
||||||
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_tearing = 0;
|
c->force_tearing = 0;
|
||||||
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||||
c->scroller_proportion_single = 0.0f;
|
c->scroller_proportion_single = 0.0f;
|
||||||
|
|
@ -3873,18 +3923,19 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
*/
|
*/
|
||||||
if (client_is_unmanaged(c)) {
|
if (client_is_unmanaged(c)) {
|
||||||
/* Unmanaged clients always are floating */
|
/* Unmanaged clients always are floating */
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
fix_xwayland_unmanaged_coordinate(c);
|
||||||
|
LISTEN(&c->surface.xwayland->events.set_geometry, &c->set_geometry,
|
||||||
|
setgeometrynotify);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]);
|
wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]);
|
||||||
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
||||||
if (client_wants_focus(c)) {
|
if (client_wants_focus(c)) {
|
||||||
focusclient(c, 1);
|
focusclient(c, 1);
|
||||||
exclusive_focus = c;
|
exclusive_focus = c;
|
||||||
}
|
}
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (client_is_x11(c)) {
|
|
||||||
LISTEN(&c->surface.xwayland->events.set_geometry, &c->set_geometry,
|
|
||||||
setgeometrynotify);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3930,8 +3981,10 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
applyrules(c);
|
applyrules(c);
|
||||||
|
|
||||||
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
if (!c->isfloating || c->force_tiled_state) {
|
||||||
WLR_EDGE_RIGHT);
|
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
||||||
|
WLR_EDGE_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
// apply buffer effects of client
|
// apply buffer effects of client
|
||||||
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
|
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
|
||||||
|
|
@ -4282,8 +4335,8 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
||||||
uint32_t time) {
|
uint32_t time) {
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
|
|
||||||
if (sloppyfocus && !start_drag_window && c && time &&
|
if (sloppyfocus && !start_drag_window && c && time && c->scene &&
|
||||||
c->scene->node.enabled && !c->animation.tagging_in &&
|
c->scene->node.enabled && !c->animation.tagining &&
|
||||||
(surface != seat->pointer_state.focused_surface) &&
|
(surface != seat->pointer_state.focused_surface) &&
|
||||||
!client_is_unmanaged(c) && VISIBLEON(c, c->mon))
|
!client_is_unmanaged(c) && VISIBLEON(c, c->mon))
|
||||||
focusclient(c, 0);
|
focusclient(c, 0);
|
||||||
|
|
@ -4756,6 +4809,13 @@ setfloating(Client *c, int32_t floating) {
|
||||||
if (!c->force_maximize)
|
if (!c->force_maximize)
|
||||||
client_set_maximized(c, false);
|
client_set_maximized(c, false);
|
||||||
|
|
||||||
|
if (!c->isfloating || c->force_tiled_state) {
|
||||||
|
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
||||||
|
WLR_EDGE_RIGHT);
|
||||||
|
} else {
|
||||||
|
client_set_tiled(c, WLR_EDGE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
arrange(c->mon, false, false);
|
arrange(c->mon, false, false);
|
||||||
setborder_color(c);
|
setborder_color(c);
|
||||||
printstatus();
|
printstatus();
|
||||||
|
|
@ -5177,7 +5237,7 @@ void setup(void) {
|
||||||
if (wlr_renderer_get_texture_formats(drw, WLR_BUFFER_CAP_DMABUF)) {
|
if (wlr_renderer_get_texture_formats(drw, WLR_BUFFER_CAP_DMABUF)) {
|
||||||
wlr_drm_create(dpy, drw);
|
wlr_drm_create(dpy, drw);
|
||||||
wlr_scene_set_linux_dmabuf_v1(
|
wlr_scene_set_linux_dmabuf_v1(
|
||||||
scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw));
|
scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 4, drw));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syncobj_enable && (drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 &&
|
if (syncobj_enable && (drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 &&
|
||||||
|
|
@ -5324,7 +5384,6 @@ void setup(void) {
|
||||||
&request_set_cursor_shape);
|
&request_set_cursor_shape);
|
||||||
hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
|
hide_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,
|
||||||
|
|
@ -5416,6 +5475,8 @@ void setup(void) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"failed to setup XWayland X server, continuing without it\n");
|
"failed to setup XWayland X server, continuing without it\n");
|
||||||
}
|
}
|
||||||
|
sync_keymap = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
|
||||||
|
synckeymap, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5490,6 +5551,9 @@ void overview_backup(Client *c) {
|
||||||
c->ismaximizescreen = 0;
|
c->ismaximizescreen = 0;
|
||||||
}
|
}
|
||||||
c->bw = c->isnoborder ? 0 : borderpx;
|
c->bw = c->isnoborder ? 0 : borderpx;
|
||||||
|
|
||||||
|
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
||||||
|
WLR_EDGE_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// overview切回到普通视图还原窗口的状态
|
// overview切回到普通视图还原窗口的状态
|
||||||
|
|
@ -5529,6 +5593,10 @@ void overview_restore(Client *c, const Arg *arg) {
|
||||||
!c->isfullscreen) { // 如果是在ov模式中创建的窗口,没有bw记录
|
!c->isfullscreen) { // 如果是在ov模式中创建的窗口,没有bw记录
|
||||||
c->bw = c->isnoborder ? 0 : borderpx;
|
c->bw = c->isnoborder ? 0 : borderpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c->isfloating && !c->force_tiled_state) {
|
||||||
|
client_set_tiled(c, WLR_EDGE_NONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handlecursoractivity(void) {
|
void handlecursoractivity(void) {
|
||||||
|
|
@ -5973,6 +6041,8 @@ void handle_keyboard_shortcuts_inhibit_new_inhibitor(
|
||||||
void virtualkeyboard(struct wl_listener *listener, void *data) {
|
void virtualkeyboard(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_virtual_keyboard_v1 *kb = data;
|
struct wlr_virtual_keyboard_v1 *kb = data;
|
||||||
/* virtual keyboards shouldn't share keyboard group */
|
/* virtual keyboards shouldn't share keyboard group */
|
||||||
|
wlr_seat_set_capabilities(seat,
|
||||||
|
seat->capabilities | WL_SEAT_CAPABILITY_KEYBOARD);
|
||||||
KeyboardGroup *group = createkeyboardgroup();
|
KeyboardGroup *group = createkeyboardgroup();
|
||||||
/* Set the keymap to match the group keymap */
|
/* Set the keymap to match the group keymap */
|
||||||
wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap);
|
wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap);
|
||||||
|
|
@ -5984,8 +6054,7 @@ void virtualkeyboard(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void warp_cursor(const Client *c) {
|
void warp_cursor(const Client *c) {
|
||||||
if (cursor->x < c->geom.x || cursor->x > c->geom.x + c->geom.width ||
|
if (INSIDEMON(c)) {
|
||||||
cursor->y < c->geom.y || cursor->y > c->geom.y + c->geom.height) {
|
|
||||||
wlr_cursor_warp_closest(cursor, NULL, c->geom.x + c->geom.width / 2.0,
|
wlr_cursor_warp_closest(cursor, NULL, c->geom.x + c->geom.width / 2.0,
|
||||||
c->geom.y + c->geom.height / 2.0);
|
c->geom.y + c->geom.height / 2.0);
|
||||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||||
|
|
@ -6003,7 +6072,8 @@ void warp_cursor_to_selmon(Monitor *m) {
|
||||||
void virtualpointer(struct wl_listener *listener, void *data) {
|
void virtualpointer(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
|
struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
|
||||||
struct wlr_input_device *device = &event->new_pointer->pointer.base;
|
struct wlr_input_device *device = &event->new_pointer->pointer.base;
|
||||||
|
wlr_seat_set_capabilities(seat,
|
||||||
|
seat->capabilities | WL_SEAT_CAPABILITY_POINTER);
|
||||||
wlr_cursor_attach_input_device(cursor, device);
|
wlr_cursor_attach_input_device(cursor, device);
|
||||||
if (event->suggested_output)
|
if (event->suggested_output)
|
||||||
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
|
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
|
||||||
|
|
@ -6012,6 +6082,26 @@ void virtualpointer(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
|
void fix_xwayland_unmanaged_coordinate(Client *c) {
|
||||||
|
if (!selmon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 1. 如果窗口已经在当前活动显示器内,直接返回
|
||||||
|
if (c->geom.x >= selmon->m.x && c->geom.x < selmon->m.x + selmon->m.width &&
|
||||||
|
c->geom.y >= selmon->m.y && c->geom.y < selmon->m.y + selmon->m.height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
c->geom = setclient_coordinate_center(c, selmon, c->geom, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t synckeymap(void *data) {
|
||||||
|
reset_keyboard_layout();
|
||||||
|
// we only need to sync keymap once
|
||||||
|
wlr_log(WLR_INFO, "timer to synckeymap done");
|
||||||
|
wl_event_source_timer_update(sync_keymap, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void activatex11(struct wl_listener *listener, void *data) {
|
void activatex11(struct wl_listener *listener, void *data) {
|
||||||
Client *c = wl_container_of(listener, c, activate);
|
Client *c = wl_container_of(listener, c, activate);
|
||||||
bool need_arrange = false;
|
bool need_arrange = false;
|
||||||
|
|
@ -6142,6 +6232,10 @@ void xwaylandready(struct wl_listener *listener, void *data) {
|
||||||
xwayland, xcursor->images[0]->buffer, xcursor->images[0]->width * 4,
|
xwayland, xcursor->images[0]->buffer, xcursor->images[0]->width * 4,
|
||||||
xcursor->images[0]->width, xcursor->images[0]->height,
|
xcursor->images[0]->width, xcursor->images[0]->height,
|
||||||
xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y);
|
xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y);
|
||||||
|
/* xwayland can't auto sync the keymap, so we do it manually
|
||||||
|
and we need to wait the xwayland completely inited
|
||||||
|
*/
|
||||||
|
wl_event_source_timer_update(sync_keymap, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setgeometrynotify(struct wl_listener *listener, void *data) {
|
static void setgeometrynotify(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -6168,8 +6262,7 @@ int32_t main(int32_t argc, char *argv[]) {
|
||||||
} else if (c == 'c') {
|
} else if (c == 'c') {
|
||||||
cli_config_path = optarg;
|
cli_config_path = optarg;
|
||||||
} else if (c == 'p') {
|
} else if (c == 'p') {
|
||||||
parse_config();
|
return parse_config() ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
return EXIT_SUCCESS;
|
|
||||||
} else {
|
} else {
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue