From 549f44868b42b93fa88a41c19efc438e9fb89f83 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 16 Feb 2025 16:06:56 +0800 Subject: [PATCH] test --- dispatch.h | 33 +++ maomao.c | 173 +++++++++------ parse_config.h | 551 ++++++++++++++++++++++++++++++++++++++++++++++++ preset_config.h | 151 +++++++++++++ 4 files changed, 849 insertions(+), 59 deletions(-) create mode 100644 dispatch.h create mode 100644 parse_config.h create mode 100644 preset_config.h diff --git a/dispatch.h b/dispatch.h new file mode 100644 index 00000000..89af3f7e --- /dev/null +++ b/dispatch.h @@ -0,0 +1,33 @@ +void minized(const Arg *arg); +void restore_minized(const Arg *arg); +void toggle_scratchpad(const Arg *arg); +void focusdir(const Arg *arg); +void toggleoverview(const Arg *arg); +void set_proportion(const Arg *arg); +void switch_proportion_preset(const Arg *arg); +void zoom(const Arg *arg); +void tagtoleft(const Arg *arg); +void tagtoright(const Arg *arg); +void viewtoleft(const Arg *arg); +void viewtoright(const Arg *arg); +void viewtoleft_have_client(const Arg *arg); +void viewtoright_have_client(const Arg *arg); +void togglefloating(const Arg *arg); +void togglefullscreen(const Arg *arg); +void togglemaxmizescreen(const Arg *arg); +void togglegaps(const Arg *arg); +void tagmon(const Arg *arg); +void spawn(const Arg *arg); +void setlayout(const Arg *arg); +void switch_layout(const Arg *arg); +void setmfact(const Arg *arg); +void quit(const Arg *arg); +void moveresize(const Arg *arg); +void exchange_client(const Arg *arg); +void killclient(const Arg *arg); +void toggleglobal(const Arg *arg); +void incnmaster(const Arg *arg); +void incgaps(const Arg *arg); +void focusmon(const Arg *arg); +void focusstack(const Arg *arg); +void chvt(const Arg *arg); \ No newline at end of file diff --git a/maomao.c b/maomao.c index 64636bd1..ed9a4fbd 100644 --- a/maomao.c +++ b/maomao.c @@ -371,7 +371,6 @@ static void autostartexec(void); // 自启动命令执行 static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 static void buttonpress(struct wl_listener *listener, void *data); // 鼠标按键事件处理 -static void chvt(const Arg *arg); static void checkidleinhibitor(struct wlr_surface *exclude); static void cleanup(void); // 退出清理 static void cleanupkeyboard(struct wl_listener *listener, @@ -395,7 +394,6 @@ static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint); static void cursorframe(struct wl_listener *listener, void *data); static void cursorwarptohint(void); static void destroydecoration(struct wl_listener *listener, void *data); -static void defaultgaps(const Arg *arg); static void destroydragicon(struct wl_listener *listener, void *data); static void destroyidleinhibitor(struct wl_listener *listener, void *data); static void destroylayersurfacenotify(struct wl_listener *listener, void *data); @@ -431,26 +429,17 @@ static void dwl_ipc_output_set_tags(struct wl_client *client, static void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource); static void focusclient(Client *c, int lift); -static void focusmon(const Arg *arg); -static void focusstack(const Arg *arg); + static void setborder_color(Client *c); static Client *focustop(Monitor *m); static void fullscreennotify(struct wl_listener *listener, void *data); -static void incnmaster(const Arg *arg); -static void incgaps(const Arg *arg); -static void incigaps(const Arg *arg); + static int keyrepeat(void *data); -static void incihgaps(const Arg *arg); -static void incivgaps(const Arg *arg); -static void incogaps(const Arg *arg); -static void incohgaps(const Arg *arg); -static void incovgaps(const Arg *arg); -static void toggleglobal(const Arg *arg); + static void inputdevice(struct wl_listener *listener, void *data); static int keybinding(uint32_t mods, xkb_keysym_t sym); static void keypress(struct wl_listener *listener, void *data); static void keypressmod(struct wl_listener *listener, void *data); -static void killclient(const Arg *arg); static void locksession(struct wl_listener *listener, void *data); static void maplayersurfacenotify(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); @@ -462,8 +451,7 @@ static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, double sy, double sx_unaccel, double sy_unaccel); static void motionrelative(struct wl_listener *listener, void *data); -static void moveresize(const Arg *arg); -static void exchange_client(const Arg *arg); + static void reset_foreign_tolevel(Client *c); static void exchange_two_client(Client *c1, Client *c2); static void outputmgrapply(struct wl_listener *listener, void *data); @@ -473,7 +461,6 @@ static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); static void printstatus(void); -static void quit(const Arg *arg); static void quitsignal(int signo); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); @@ -486,29 +473,20 @@ static void setfloating(Client *c, int floating); static void setfullscreen(Client *c, int fullscreen); static void setmaxmizescreen(Client *c, int maxmizescreen); static void setgaps(int oh, int ov, int ih, int iv); -static void setlayout(const Arg *arg); -static void switch_layout(const Arg *arg); -static void setmfact(const Arg *arg); + static void setmon(Client *c, Monitor *m, unsigned int newtags); static void setpsel(struct wl_listener *listener, void *data); static void setsel(struct wl_listener *listener, void *data); static void setup(void); static void sigchld(int unused); -static void spawn(const Arg *arg); static void startdrag(struct wl_listener *listener, void *data); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); + static void setgamma(struct wl_listener *listener, void *data); static void tile(Monitor *m, unsigned int gappo, unsigned int uappi); static void overview(Monitor *m, unsigned int gappo, unsigned int gappi); static void grid(Monitor *m, unsigned int gappo, unsigned int uappi); static void scroller(Monitor *m, unsigned int gappo, unsigned int uappi); -static void togglefloating(const Arg *arg); -static void togglefullscreen(const Arg *arg); -static void togglemaxmizescreen(const Arg *arg); -static void togglegaps(const Arg *arg); -static void toggletag(const Arg *arg); -static void toggleview(const Arg *arg); + static void unlocksession(struct wl_listener *listener, void *data); static void unmaplayersurfacenotify(struct wl_listener *listener, void *data); static void unmapnotify(struct wl_listener *listener, void *data); @@ -516,36 +494,24 @@ static void updatemons(struct wl_listener *listener, void *data); static void updatetitle(struct wl_listener *listener, void *data); static void urgent(struct wl_listener *listener, void *data); static void view(const Arg *arg, bool want_animation); -static void bind_to_view(const Arg *arg); -static void viewtoleft_have_client(const Arg *arg); -static void viewtoright_have_client(const Arg *arg); -static void viewtoleft(const Arg *arg); -static void viewtoright(const Arg *arg); + static void handlesig(int signo); -static void tagtoleft(const Arg *arg); -static void tagtoright(const Arg *arg); + static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualpointer(struct wl_listener *listener, void *data); static void warp_cursor(const Client *c); static Monitor *xytomon(double x, double y); static void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny); -static void zoom(const Arg *arg); static void clear_fullscreen_flag(Client *c); -static Client *direction_select(const Arg *arg); -static void focusdir(const Arg *arg); -static void toggleoverview(const Arg *arg); -static void set_proportion(const Arg *arg); -static void switch_proportion_preset(const Arg *arg); + static void warp_cursor_to_selmon(const Monitor *m); unsigned int want_restore_fullscreen(Client *target_client); static void overview_restore(Client *c, const Arg *arg); static void overview_backup(Client *c); static int applyrulesgeom(Client *c); static void set_minized(Client *c); -static void minized(const Arg *arg); -static void restore_minized(const Arg *arg); -static void toggle_scratchpad(const Arg *arg); + static void show_scratchpad(Client *c); static void show_hide_client(Client *c); static void tag_client(const Arg *arg, Client *target_client); @@ -566,6 +532,21 @@ void apply_border(Client *c, struct wlr_box clip_box,int offset); void client_set_opacity(Client *c, double opacity); void init_baked_points(void); +Client *direction_select(const Arg *arg); +void bind_to_view(const Arg *arg); +void toggletag(const Arg *arg); +void toggleview(const Arg *arg); +void tag(const Arg *arg); +void incihgaps(const Arg *arg); +void incivgaps(const Arg *arg); +void incogaps(const Arg *arg); +void incohgaps(const Arg *arg); +void incovgaps(const Arg *arg); +void incigaps(const Arg *arg); +void defaultgaps(const Arg *arg); + +#include "dispatch.h" + /* variables */ static const char broken[] = "broken"; // static const char *cursor_image = "left_ptr"; @@ -646,6 +627,7 @@ static void associatex11(struct wl_listener *listener, void *data); static Atom getatom(xcb_connection_t *xc, const char *name); static void sethints(struct wl_listener *listener, void *data); static void xwaylandready(struct wl_listener *listener, void *data); +void free_config(void); // static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11}; // static struct wl_listener xwayland_ready = {.notify = xwaylandready}; static struct wlr_xwayland *xwayland; @@ -654,6 +636,7 @@ static Atom netatom[NetLast]; /* configuration, allows nested code to access above variables */ #include "config.h" +#include "parse_config.h" /* attempt to encapsulate suck into one file */ #include "client.h" @@ -661,6 +644,8 @@ static Atom netatom[NetLast]; #include "IM.h" #endif +Config config; + /* compile-time check if all tags fit into an unsigned int bit array. */ struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; @@ -1122,15 +1107,17 @@ int // 0.5 applyrulesgeom(Client *c) { /* rule matching */ const char *appid, *title; - const Rule *r; + ConfigWinRule *r; int hit = 0; + int i; if (!(appid = client_get_appid(c))) appid = broken; if (!(title = client_get_title(c))) title = broken; - for (r = rules; r < END(rules); r++) { + for (i = 0; i < config.window_rules_count; i++) { + r = &config.window_rules[i]; if ((!r->title || strstr(title, r->title)) && (!r->id || strstr(appid, r->id)) && r->width != 0 && r->height != 0) { c->geom.width = r->width; @@ -1149,7 +1136,8 @@ applyrules(Client *c) { /* rule matching */ const char *appid, *title; uint32_t i, newtags = 0; - const Rule *r; + int ji; + const ConfigWinRule *r; Monitor *mon = selmon, *m; c->isfloating = client_is_float_type(c); @@ -1158,7 +1146,8 @@ applyrules(Client *c) { if (!(title = client_get_title(c))) title = broken; - for (r = rules; r < END(rules); r++) { + for (ji = 0; ji < config.window_rules_count; ji++) { + r = &config.window_rules[ji]; if ((!r->title || strstr(title, r->title)) && (!r->id || strstr(appid, r->id))) { c->isfloating = r->isfloating; @@ -1544,7 +1533,8 @@ axisnotify(struct wl_listener *listener, void *data) { struct wlr_pointer_axis_event *event = data; struct wlr_keyboard *keyboard; uint32_t mods; - const Axis *a; + const AxisBinding *a; + int ji; unsigned int adir; // IDLE_NOTIFY_ACTIVITY; wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); @@ -1558,7 +1548,8 @@ axisnotify(struct wl_listener *listener, void *data) { else adir = event->delta > 0 ? AxisRight : AxisLeft; - for (a = axes; a < END(axes); a++) { + for (ji = 0; ji < config.axis_bindings_count; ji++) { + a = &config.axis_bindings[ji]; if (CLEANMASK(mods) == CLEANMASK(a->mod) && // 按键一致 adir == a->dir && a->func) { // 滚轮方向判断一致且处理函数存在 if (event->time_msec - axis_apply_time > axis_bind_apply_timeout) { @@ -1587,7 +1578,8 @@ buttonpress(struct wl_listener *listener, void *data) { struct wlr_keyboard *keyboard; uint32_t mods; Client *c; - const Button *b; + int ji; + const MouseBinding *b; struct wlr_surface *surface; wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); @@ -1609,7 +1601,8 @@ buttonpress(struct wl_listener *listener, void *data) { keyboard = wlr_seat_get_keyboard(seat); mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; - for (b = buttons; b < END(buttons); b++) { + for (ji = 0; ji < config.mouse_bindings_count; ji++) { + b = &config.mouse_bindings[ji]; if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button && b->func && (selmon->isoverview == 1 || b->button == BTN_MIDDLE) && c) { @@ -2003,8 +1996,9 @@ createmon(struct wl_listener *listener, void *data) { /* This event is raised by the backend when a new output (aka a display or * monitor) becomes available. */ struct wlr_output *wlr_output = data; - const MonitorRule *r; + const ConfigMonitorRule *r; size_t i; + int ji,jk; Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m)); m->wlr_output = wlr_output; @@ -2034,14 +2028,20 @@ createmon(struct wl_listener *listener, void *data) { } else { m->lt[0] = m->lt[1] = &layouts[0]; } - for (r = monrules; r < END(monrules); r++) { + for (ji = 0; ji < config.monitor_rules_count; ji++) { + r = &config.monitor_rules[ji]; if (!r->name || strstr(wlr_output->name, r->name)) { m->mfact = r->mfact; m->nmaster = r->nmaster; m->m.x = r->x; m->m.y = r->y; - if (r->lt) - m->lt[0] = m->lt[1] = r->lt; + if (r->layout) { + for (jk = 0; jk < LENGTH(layouts); jk++) { + if(strcmp(layouts[jk].name , r->layout) == 0) { + m->lt[0] = m->lt[1] = &layouts[jk]; + } + } + } scale = r->scale; rr = r->rr; break; @@ -2889,8 +2889,10 @@ keybinding(uint32_t mods, xkb_keysym_t sym) { * processing. */ int handled = 0; - const Key *k; - for (k = keys; k < END(keys); k++) { + const KeyBinding *k; + int i; + for (i =0; i < config.key_bindings_count; i++) { + k = &config.key_bindings[i]; if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->keysym && k->func) { k->func(&k->arg); handled = 1; @@ -3556,6 +3558,7 @@ printstatus(void) { void // 0.5 quit(const Arg *arg) { wl_display_terminate(dpy); + free_config(); } void quitsignal(int signo) { quit(NULL); } @@ -4335,11 +4338,63 @@ void signalhandler(int signalnumber) // 不调用 exit 以允许生成核心转储文件 } +void free_config(void) { + // 释放内存 + for (int i = 0; i < config.window_rules_count; i++) { + ConfigWinRule *rule = &config.window_rules[i]; + if (rule->id) free((void *)rule->id); + if (rule->title) free((void *)rule->title); + if (rule->animation_type) free((void *)rule->animation_type); + } + free(config.window_rules); + + for (int i = 0; i < config.monitor_rules_count; i++) { + ConfigMonitorRule *rule = &config.monitor_rules[i]; + if (rule->name) free((void *)rule->name); + if (rule->layout) free((void *)rule->layout); + } + free(config.monitor_rules); + + for (int i = 0; i < config.key_bindings_count; i++) { + if (config.key_bindings[i].arg.v) free((void *)config.key_bindings[i].arg.v); + } + free(config.key_bindings); + + for (int i = 0; i < config.mouse_bindings_count; i++) { + if (config.mouse_bindings[i].arg.v) free((void *)config.mouse_bindings[i].arg.v); + } + free(config.mouse_bindings); + + for (int i = 0; i < config.axis_bindings_count; i++) { + if (config.axis_bindings[i].arg.v) free((void *)config.axis_bindings[i].arg.v); + } + free(config.axis_bindings); + +} + +void parse_config(void) { + memset(&config, 0, sizeof(config)); + config.window_rules = NULL; + config.window_rules_count = 0; + config.monitor_rules = NULL; + config.monitor_rules_count = 0; + config.key_bindings = NULL; + config.key_bindings_count = 0; + config.mouse_bindings = NULL; + config.mouse_bindings_count = 0; + config.axis_bindings = NULL; + config.axis_bindings_count = 0; + + parse_config_file(&config, "/home/wrq/.config/maomao/config.conf"); +} void setup(void) { + signal(SIGSEGV, signalhandler); + parse_config(); + init_baked_points(); int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; diff --git a/parse_config.h b/parse_config.h new file mode 100644 index 00000000..1e55b993 --- /dev/null +++ b/parse_config.h @@ -0,0 +1,551 @@ +typedef struct { + const char *id; + const char *title; + unsigned int tags; + int isfloating; + int isfullscreen; + float scroller_proportion; + const char *animation_type; + int isnoborder; + int monitor; + unsigned int width; + unsigned int height; +} ConfigWinRule; + +typedef struct { + const char *name; // 显示器名称 + float mfact; // 主区域比例 + int nmaster; // 主区域窗口数量 + const char *layout; // 布局名称(字符串) + int rr; // 旋转和翻转(假设为整数) + float scale; // 显示器缩放比例 + int x, y; // 显示器位置 +} ConfigMonitorRule; + +typedef struct { + uint32_t mod; + xkb_keysym_t keysym; + void (*func)(const Arg *); + Arg arg; +} KeyBinding; + +typedef struct { + unsigned int mod; + unsigned int button; + void (*func)(const Arg *); + Arg arg; +} MouseBinding; + +typedef struct { + unsigned int mod; + unsigned int dir; + void (*func)(const Arg *); + Arg arg; +} AxisBinding; + +typedef struct { + int animations; + char animation_type[10]; + char animation_fade_in; + float zoom_initial_ratio; + float fadein_begin_opacity; + uint32_t animation_duration_move; + uint32_t animation_duration_open; + uint32_t animation_duration_tag; + double animation_curve[4]; + + int scroller_structs; + float scroller_default_proportion; + int scoller_focus_center; + float scroller_proportion_preset[3]; + + unsigned int new_is_master; + float default_mfact; + unsigned int default_nmaster; + + unsigned int hotarea_size; + unsigned int enable_hotarea; + unsigned int ov_tab_mode; + int overviewgappi; + int overviewgappo; + + unsigned int axis_bind_apply_timeout; + unsigned int focus_on_activate; + unsigned int numlockon; + int bypass_surface_visibility; + int sloppyfocus; + int warpcursor; + + int smartgaps; + unsigned int gappih; + unsigned int gappiv; + unsigned int gappoh; + unsigned int gappov; + unsigned int borderpx; + int rootcolor; + int bordercolor; + int focuscolor; + int maxmizescreencolor; + int urgentcolor; + int scratchpadcolor; + int globalcolor; + + char autostart[3][256]; + + struct { + int id; + char name[256]; + } tags[9]; + + ConfigWinRule *window_rules; + int window_rules_count; + + ConfigMonitorRule *monitor_rules; // 动态数组 + int monitor_rules_count; // 条数 + + KeyBinding *key_bindings; + int key_bindings_count; + + MouseBinding *mouse_bindings; + int mouse_bindings_count; + + AxisBinding *axis_bindings; + int axis_bindings_count; + +} Config; + +long int parse_color(const char *hex_str) { + char *endptr; + long int hex_num = strtol(hex_str, &endptr, 16); + if (*endptr != '\0') { + return -1; + } + return hex_num; +} + +uint32_t parse_mod(const char *mod_str) { + uint32_t mod = 0; + if (strstr(mod_str, "SUPER")) mod |= WLR_MODIFIER_LOGO; + if (strstr(mod_str, "CTRL")) mod |= WLR_MODIFIER_CTRL; + if (strstr(mod_str, "SHIFT")) mod |= WLR_MODIFIER_SHIFT; + if (strstr(mod_str, "ALT")) mod |= WLR_MODIFIER_ALT; + return mod; +} + +xkb_keysym_t parse_keysym(const char *keysym_str) { + return xkb_keysym_from_name(keysym_str, XKB_KEYSYM_CASE_INSENSITIVE); +} + +typedef void (*FuncType)(const Arg *); + +FuncType parse_func_name(char *func_name,Arg *arg, char *arg_value) { + + FuncType func = NULL; + (*arg).v = NULL; + + if (strcmp(func_name, "focusstack") == 0) { + func = focusstack; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "focusdir") == 0) { + func = focusdir; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "incnmaster") == 0) { + func = incnmaster; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "setmfact") == 0) { + func = setmfact; + (*arg).f = atof(arg_value); + } else if (strcmp(func_name, "zoom") == 0) { + func = zoom; + } else if (strcmp(func_name, "exchange_client") == 0) { + func = exchange_client; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "toggleglobal") == 0) { + func = toggleglobal; + } else if (strcmp(func_name, "toggleoverview") == 0) { + func = toggleoverview; + } else if (strcmp(func_name, "set_proportion") == 0) { + func = set_proportion; + (*arg).f = atof(arg_value); + } else if (strcmp(func_name, "switch_proportion_preset") == 0) { + func = switch_proportion_preset; + } else if (strcmp(func_name, "viewtoleft") == 0) { + func = viewtoleft; + } else if (strcmp(func_name, "viewtoright") == 0) { + func = viewtoright; + } else if (strcmp(func_name, "tagtoleft") == 0) { + func = tagtoleft; + } else if (strcmp(func_name, "tagtoright") == 0) { + func = tagtoright; + } else if (strcmp(func_name, "killclient") == 0) { + func = killclient; + } else if (strcmp(func_name, "setlayout") == 0) { + func = setlayout; + } else if (strcmp(func_name, "switch_layout") == 0) { + func = switch_layout; + } else if (strcmp(func_name, "togglefloating") == 0) { + func = togglefloating; + } else if (strcmp(func_name, "togglefullscreen") == 0) { + func = togglefullscreen; + } else if (strcmp(func_name, "minized") == 0) { + func = minized; + } else if (strcmp(func_name, "restore_minized") == 0) { + func = restore_minized; + } else if (strcmp(func_name, "toggle_scratchpad") == 0) { + func = toggle_scratchpad; + } else if (strcmp(func_name, "focusmon") == 0) { + func = focusmon; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "tagmon") == 0) { + func = tagmon; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "incgaps") == 0) { + func = incgaps; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "togglegaps") == 0) { + func = togglegaps; + } else if (strcmp(func_name, "chvt") == 0) { + func = chvt; + (*arg).i = atoi(arg_value); + } else if (strcmp(func_name, "spawn") == 0) { + func = spawn; + (*arg).v = strdup(arg_value); + } else if (strcmp(func_name, "quit") == 0) { + func = quit; + } else if (strcmp(func_name, "moveresize") == 0) { + func = moveresize; + (*arg).ui = atoi(arg_value); + } else if (strcmp(func_name, "togglemaxmizescreen") == 0) { + func = togglemaxmizescreen; + } else if (strcmp(func_name, "viewtoleft_have_client") == 0) { + func = viewtoleft_have_client; + } else if (strcmp(func_name, "viewtoright_have_client") == 0) { + func = viewtoright_have_client; + } else { + return NULL; + } + return func; +} + +void parse_config_line(Config *config, const char *line) { + char key[256], value[256]; + if (sscanf(line, "%[^=]=%[^\n]", key, value) != 2) { + fprintf(stderr, "Error: Invalid line format: %s\n", line); + return; + } + + if (strcmp(key, "animations") == 0) { + config->animations = atoi(value); + } else if (strcmp(key, "animation_type") == 0) { + strncpy(config->animation_type, value, sizeof(config->animation_type)); + } else if (strcmp(key, "animation_fade_in") == 0) { + config->animation_fade_in = atoi(value); + } else if (strcmp(key, "zoom_initial_ratio") == 0) { + config->zoom_initial_ratio = atof(value); + } else if (strcmp(key, "fadein_begin_opacity") == 0) { + config->fadein_begin_opacity = atof(value); + } else if (strcmp(key, "animation_duration_move") == 0) { + config->animation_duration_move = atoi(value); + } else if (strcmp(key, "animation_duration_open") == 0) { + config->animation_duration_open = atoi(value); + } else if (strcmp(key, "animation_duration_tag") == 0) { + config->animation_duration_tag = atoi(value); + } else if (strcmp(key, "animation_curve") == 0) { + if (sscanf(value, "%lf,%lf,%lf,%lf", &config->animation_curve[0], &config->animation_curve[1], &config->animation_curve[2], &config->animation_curve[3]) != 4) { + fprintf(stderr, "Error: Invalid animation_curve format: %s\n", value); + } + } else if (strcmp(key, "scroller_structs") == 0) { + config->scroller_structs = atoi(value); + } else if (strcmp(key, "scroller_default_proportion") == 0) { + config->scroller_default_proportion = atof(value); + } else if (strcmp(key, "scoller_focus_center") == 0) { + config->scoller_focus_center = atoi(value); + } else if (strcmp(key, "scroller_proportion_preset") == 0) { + if (sscanf(value, "%f,%f,%f", &config->scroller_proportion_preset[0], &config->scroller_proportion_preset[1], &config->scroller_proportion_preset[2]) != 3) { + fprintf(stderr, "Error: Invalid scroller_proportion_preset format: %s\n", value); + } + } else if (strcmp(key, "new_is_master") == 0) { + config->new_is_master = atoi(value); + } else if (strcmp(key, "default_mfact") == 0) { + config->default_mfact = atof(value); + } else if (strcmp(key, "default_nmaster") == 0) { + config->default_nmaster = atoi(value); + } else if (strcmp(key, "hotarea_size") == 0) { + config->hotarea_size = atoi(value); + } else if (strcmp(key, "enable_hotarea") == 0) { + config->enable_hotarea = atoi(value); + } else if (strcmp(key, "ov_tab_mode") == 0) { + config->ov_tab_mode = atoi(value); + } else if (strcmp(key, "overviewgappi") == 0) { + config->overviewgappi = atoi(value); + } else if (strcmp(key, "overviewgappo") == 0) { + config->overviewgappo = atoi(value); + } else if (strcmp(key, "axis_bind_apply_timeout") == 0) { + config->axis_bind_apply_timeout = atoi(value); + } else if (strcmp(key, "focus_on_activate") == 0) { + config->focus_on_activate = atoi(value); + } else if (strcmp(key, "numlockon") == 0) { + config->numlockon = atoi(value); + } else if (strcmp(key, "bypass_surface_visibility") == 0) { + config->bypass_surface_visibility = atoi(value); + } else if (strcmp(key, "sloppyfocus") == 0) { + config->sloppyfocus = atoi(value); + } else if (strcmp(key, "warpcursor") == 0) { + config->warpcursor = atoi(value); + } else if (strcmp(key, "smartgaps") == 0) { + config->smartgaps = atoi(value); + } else if (strcmp(key, "gappih") == 0) { + config->gappih = atoi(value); + } else if (strcmp(key, "gappiv") == 0) { + config->gappiv = atoi(value); + } else if (strcmp(key, "gappoh") == 0) { + config->gappoh = atoi(value); + } else if (strcmp(key, "gappov") == 0) { + config->gappov = atoi(value); + } else if (strcmp(key, "borderpx") == 0) { + config->borderpx = atoi(value); + } else if (strcmp(key, "rootcolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid rootcolor format: %s\n", value); + } else { + config->rootcolor = color; + } + } else if (strcmp(key, "bordercolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid bordercolor format: %s\n", value); + } else { + config->bordercolor = color; + } + } else if (strcmp(key, "focuscolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid focuscolor format: %s\n", value); + } else { + config->focuscolor = color; + } + } else if (strcmp(key, "maxmizescreencolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid maxmizescreencolor format: %s\n", value); + } else { + config->maxmizescreencolor = color; + } + } else if (strcmp(key, "urgentcolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid urgentcolor format: %s\n", value); + } else { + config->urgentcolor = color; + } + } else if (strcmp(key, "scratchpadcolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid scratchpadcolor format: %s\n", value); + } else { + config->scratchpadcolor = color; + } + } else if (strcmp(key, "globalcolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid globalcolor format: %s\n", value); + } else { + config->globalcolor = color; + } + } else if (strcmp(key, "autostart") == 0) { + if (sscanf(value, "%[^,],%[^,],%[^,]", config->autostart[0], config->autostart[1], config->autostart[2]) != 3) { + fprintf(stderr, "Error: Invalid autostart format: %s\n", value); + } + } else if (strcmp(key, "tags") == 0) { + int id; + char name[256]; + if (sscanf(value, "id:%d,name:%255[^\n]", &id, name) == 2) { + if (id >= 1 && id <= 9) { + config->tags[id - 1].id = id; + strncpy(config->tags[id - 1].name, name, sizeof(config->tags[id - 1].name)); + } else { + fprintf(stderr, "Error: Invalid tag id: %d\n", id); + } + } else { + fprintf(stderr, "Error: Invalid tags format: %s\n", value); + } + } else if (strcmp(key, "windowrule") == 0) { + config->window_rules = realloc(config->window_rules, (config->window_rules_count + 1) * sizeof(ConfigWinRule)); + if (!config->window_rules) { + fprintf(stderr, "Error: Failed to allocate memory for window rules\n"); + return; + } + + ConfigWinRule *rule = &config->window_rules[config->window_rules_count]; + memset(rule, 0, sizeof(ConfigWinRule)); + + char *token = strtok(value, ","); + while (token != NULL) { + char *colon = strchr(token, ':'); + if (colon != NULL) { + *colon = '\0'; + char *key = token; + char *val = colon + 1; + + if (strcmp(key, "isfloating") == 0) { + rule->isfloating = atoi(val); + } else if (strcmp(key, "title") == 0) { + rule->title = strdup(val); + } else if (strcmp(key, "appid") == 0) { + rule->id = strdup(val); + } else if (strcmp(key, "animation_type") == 0) { + rule->animation_type = strdup(val); + } else if (strcmp(key, "tags") == 0) { + rule->tags = atoi(val); + } else if (strcmp(key, "monitor") == 0) { + rule->monitor = atoi(val); + } else if (strcmp(key, "width") == 0) { + rule->width = atoi(val); + } else if (strcmp(key, "height") == 0) { + rule->height = atoi(val); + } else if (strcmp(key, "isnoborder") == 0) { + rule->isnoborder = atoi(val); + } else if (strcmp(key, "scroller_proportion") == 0) { + rule->scroller_proportion = atof(val); + } else if (strcmp(key, "isfullscreen") == 0) { + rule->isfullscreen = atoi(val); + } + } + token = strtok(NULL, ","); + } + config->window_rules_count++; + } else if (strcmp(key, "monitorrule") == 0) { + config->monitor_rules = realloc(config->monitor_rules, (config->monitor_rules_count + 1) * sizeof(ConfigMonitorRule)); + if (!config->monitor_rules) { + fprintf(stderr, "Error: Failed to allocate memory for monitor rules\n"); + return; + } + + ConfigMonitorRule *rule = &config->monitor_rules[config->monitor_rules_count]; + memset(rule, 0, sizeof(ConfigMonitorRule)); + + char layout[256], name[256]; + int parsed = sscanf(value, "%255[^,],%f,%d,%255[^,],%d,%f,%d,%d", + name, + &rule->mfact, + &rule->nmaster, + layout, + &rule->rr, + &rule->scale, + &rule->x, + &rule->y); + + if (parsed == 8) { + rule->name = strdup(name); + rule->layout = strdup(layout); + + if (!rule->name || !rule->layout) { + if (rule->name) free((void *)rule->name); + if (rule->layout) free((void *)rule->layout); + fprintf(stderr, "Error: Failed to allocate memory for monitor rule\n"); + return; + } + + config->monitor_rules_count++; + } else { + fprintf(stderr, "Error: Invalid monitorrule format: %s\n", value); + } + } else if (strncmp(key, "bind", 4) == 0) { + config->key_bindings = realloc(config->key_bindings, (config->key_bindings_count + 1) * sizeof(KeyBinding)); + if (!config->key_bindings) { + fprintf(stderr, "Error: Failed to allocate memory for key bindings\n"); + return; + } + + KeyBinding *binding = &config->key_bindings[config->key_bindings_count]; + memset(binding, 0, sizeof(KeyBinding)); + + char mod_str[256], keysym_str[256], func_name[256], arg_value[256] = "none"; + if (sscanf(value, "%[^,],%[^,],%[^,],%[^\n]", mod_str, keysym_str, func_name, arg_value) < 3) { + fprintf(stderr, "Error: Invalid bind format: %s\n", value); + return; + } + + binding->mod = parse_mod(mod_str); + binding->keysym = parse_keysym(keysym_str); + binding->arg.v = NULL; + binding->func = parse_func_name(func_name, &binding->arg, arg_value); + if (!binding->func){ + fprintf(stderr, "Error: Unknown function in bind: %s\n", func_name); + } else { + config->key_bindings_count++; + } + + } else if (strncmp(key, "mousebind", 9) == 0) { + config->mouse_bindings = realloc(config->mouse_bindings, (config->mouse_bindings_count + 1) * sizeof(MouseBinding)); + if (!config->mouse_bindings) { + fprintf(stderr, "Error: Failed to allocate memory for mouse bindings\n"); + return; + } + + MouseBinding *binding = &config->mouse_bindings[config->mouse_bindings_count]; + memset(binding, 0, sizeof(MouseBinding)); + + char mod_str[256], button_str[256], func_name[256], arg_value[256] = "none"; + if (sscanf(value, "%[^,],%[^,],%[^,],%[^\n]", mod_str, button_str, func_name, arg_value) < 3) { + fprintf(stderr, "Error: Invalid mousebind format: %s\n", value); + return; + } + + binding->mod = parse_mod(mod_str); + binding->button = atoi(button_str); + binding->arg.v = NULL; + binding->func = parse_func_name(func_name, &binding->arg, arg_value); + if (!binding->func){ + fprintf(stderr, "Error: Unknown function in mousebind: %s\n", func_name); + } else { + config->mouse_bindings_count++; + } + } else if (strncmp(key, "axisbind", 8) == 0) { + config->axis_bindings = realloc(config->axis_bindings, (config->axis_bindings_count + 1) * sizeof(AxisBinding)); + if (!config->axis_bindings) { + fprintf(stderr, "Error: Failed to allocate memory for axis bindings\n"); + return; + } + + AxisBinding *binding = &config->axis_bindings[config->axis_bindings_count]; + memset(binding, 0, sizeof(AxisBinding)); + + char mod_str[256], dir_str[256], func_name[256], arg_value[256] = "none"; + if (sscanf(value, "%[^,],%[^,],%[^,],%[^\n]", mod_str, dir_str, func_name, arg_value) < 3) { + fprintf(stderr, "Error: Invalid axisbind format: %s\n", value); + return; + } + + binding->mod = parse_mod(mod_str); + binding->dir = atoi(dir_str); + binding->arg.v = NULL; + binding->func = parse_func_name(func_name, &binding->arg, arg_value); + + if (!binding->func){ + fprintf(stderr, "Error: Unknown function in axisbind: %s\n", func_name); + } else { + config->axis_bindings_count++; + } + + } else { + fprintf(stderr, "Error: Unknown key: %s\n", key); + } +} + +void parse_config_file(Config *config, const char *file_path) { + FILE *file = fopen(file_path, "r"); + if (!file) { + perror("Error opening file"); + return; + } + + char line[512]; + while (fgets(line, sizeof(line), file)) { + if (line[0] == '#' || line[0] == '\n') continue; + parse_config_line(config, line); + } + + fclose(file); +} \ No newline at end of file diff --git a/preset_config.h b/preset_config.h new file mode 100644 index 00000000..c1f37cde --- /dev/null +++ b/preset_config.h @@ -0,0 +1,151 @@ +/* speedie's maomao config */ + +#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \ + ((hex >> 16) & 0xFF) / 255.0f, \ + ((hex >> 8) & 0xFF) / 255.0f, \ + (hex & 0xFF) / 255.0f } + +/* animaion */ +char *animation_type = "slide"; //是否启用动画 //slide,zoom +int animations = 1; //是否启用动画 +char animation_fade_in = 1; // Enable animation fade in +float zoom_initial_ratio = 0.5; //动画起始窗口比例 +float fadein_begin_opacity = 0; // Begin opac window ratio for animations +uint32_t animation_duration_move = 500; // Animation move speed +uint32_t animation_duration_open = 400; // Animation open speed +uint32_t animation_duration_tag = 300; // Animation tag speed +double animation_curve[4] = {0.46,1.0,0.29,0.99}; //动画曲线 + +/* appearance */ +unsigned int axis_bind_apply_timeout = 100; //滚轮绑定动作的触发的时间间隔 +unsigned int focus_on_activate = 1; //收到窗口激活请求是否自动跳转聚焦 +unsigned int new_is_master = 1; //新窗口是否插在头部 +unsigned int default_mfact = 0.55f; // master 窗口比例 +unsigned int default_nmaster = 1; //默认master数量 +/* logging */ +int log_level = WLR_ERROR; +unsigned int numlockon = 1; //是否打开右边小键盘 + +unsigned int ov_tab_mode = 0; // alt tab切换模式 +unsigned int hotarea_size = 10; //热区大小,10x10 +unsigned int enable_hotarea = 1; //是否启用鼠标热区 +int smartgaps = 0; /* 1 means no outer gap when there is only one window */ +int sloppyfocus = 1; /* focus follows mouse */ +unsigned int gappih = 5; /* horiz inner gap between windows */ +unsigned int gappiv = 5; /* vert inner gap between windows */ +unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ +unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ + + +int scroller_structs = 20; +float scroller_default_proportion = 0.9; +int scoller_foucs_center = 0; +float scroller_proportion_preset[] = {0.5,0.9,1.0}; + +int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */ +unsigned int borderpx = 4; /* border pixel of windows */ +float rootcolor[] = COLOR(0x323232ff); +float bordercolor[] = COLOR(0x444444ff); +float focuscolor[] = COLOR(0xc66b25ff); +float maxmizescreencolor[] = COLOR(0x89aa61ff); +float urgentcolor[] = COLOR(0xad401fff); +float scratchpadcolor[] = COLOR(0x516c93ff); +float globalcolor[] = COLOR(0xb153a7ff); +// char *cursor_theme = "Bibata-Modern-Ice"; + +int overviewgappi = 5; /* overview时 窗口与边缘 缝隙大小 */ +int overviewgappo = 30; /* overview时 窗口与窗口 缝隙大小 */ + +/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */ +float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; + +int warpcursor = 1; /* Warp cursor to focused client */ + + +/* layout(s) */ +Layout overviewlayout = { "󰃇", overview, "overview" }; + +Layout layouts[] = { //最少两个,不能删除少于两个 + /* symbol arrange function name */ + { "⬌", scroller, "scroller" }, //滚动布局 + { "󱞬", tile, "tile" }, //堆栈布局 +}; + + + +/* keyboard */ +struct xkb_rule_names xkb_rules = { + /* can specify fields: rules, model, layout, variant, options */ + /* example: + .options = "ctrl:nocaps", + */ + .options = NULL, +}; + +int repeat_rate = 25; +int repeat_delay = 600; + +/* Trackpad */ +int tap_to_click = 1; +int tap_and_drag = 1; +int drag_lock = 1; +int natural_scrolling = 0; +int disable_while_typing = 1; +int left_handed = 0; +int middle_button_emulation = 0; +/* You can choose between: +LIBINPUT_CONFIG_SCROLL_NO_SCROLL +LIBINPUT_CONFIG_SCROLL_2FG +LIBINPUT_CONFIG_SCROLL_EDGE +LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN +*/ +enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; + +/* You can choose between: +LIBINPUT_CONFIG_CLICK_METHOD_NONE +LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS +LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER +*/ +enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; + +/* You can choose between: +LIBINPUT_CONFIG_SEND_EVENTS_ENABLED +LIBINPUT_CONFIG_SEND_EVENTS_DISABLED +LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE +*/ +uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; + +/* You can choose between: +LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT +LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE +*/ +enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; +double accel_speed = 0.0; +/* You can choose between: +LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle +LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right +*/ +enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM; + +/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */ +#define MODKEY WLR_MODIFIER_ALT + +static const char *tags[] = { + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", +}; + +static const char *const autostart[] = { + "/bin/sh", + "-c", + "~/.config/maomao/autostart.sh", + NULL, + NULL, +}; \ No newline at end of file