diff --git a/README.md b/README.md index 5701178..af1d297 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,8 @@ https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0 - hwdata - seatd - pcre2 +- xorg-xwayland +- libxcb ## Arch Linux The package is in the Arch User Repository and is availble for manual download [here](https://aur.archlinux.org/packages/mangowc-git) or through a AUR helper like yay: diff --git a/meson.build b/meson.build index b02e0fd..460328e 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('mango', ['c', 'cpp'], - version : '0.10.6', + version : '0.10.7', ) subdir('protocols') diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 7c76c5e..d845e2a 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -988,7 +989,31 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, (*arg).i = atoi(arg_value2); } else if (strcmp(func_name, "view") == 0) { func = bind_to_view; - (*arg).ui = 1 << (atoi(arg_value) - 1); + + uint32_t mask = 0; + char *token; + char *arg_copy = strdup(arg_value); + + if (arg_copy != NULL) { + char *saveptr = NULL; + token = strtok_r(arg_copy, "|", &saveptr); + + while (token != NULL) { + int num = atoi(token); + if (num > 0 && num <= LENGTH(tags)) { + mask |= (1 << (num - 1)); + } + token = strtok_r(NULL, "|", &saveptr); + } + + free(arg_copy); + } + + if (mask) { + (*arg).ui = mask; + } else { + (*arg).ui = atoi(arg_value); + } (*arg).i = atoi(arg_value2); } else if (strcmp(func_name, "viewcrossmon") == 0) { func = viewcrossmon; @@ -2282,10 +2307,12 @@ void parse_config_file(Config *config, const char *file_path) { if (file_path[0] == '.' && file_path[1] == '/') { // Relative path - const char *mangoconfig = getenv("MANGOCONFIG"); - if (mangoconfig && mangoconfig[0] != '\0') { - snprintf(full_path, sizeof(full_path), "%s/%s", mangoconfig, + if (cli_config_path) { + char *config_path = strdup(cli_config_path); + char *config_dir = dirname(config_path); + snprintf(full_path, sizeof(full_path), "%s/%s", config_dir, file_path + 1); + free(config_path); } else { const char *home = getenv("HOME"); if (!home) { @@ -3012,11 +3039,9 @@ void parse_config(void) { create_config_keymap(); - // 获取 MANGOCONFIG 环境变量 - const char *mangoconfig = getenv("MANGOCONFIG"); - - // 如果 MANGOCONFIG 环境变量不存在或为空,则使用 HOME 环境变量 - if (!mangoconfig || mangoconfig[0] == '\0') { + if (cli_config_path) { + snprintf(filename, sizeof(filename), "%s", cli_config_path); + } else { // 获取当前用户家目录 const char *homedir = getenv("HOME"); if (!homedir) { @@ -3033,9 +3058,6 @@ void parse_config(void) { snprintf(filename, sizeof(filename), "%s/mango/config.conf", SYSCONFDIR); } - } else { - // 使用 MANGOCONFIG 环境变量作为配置文件夹路径 - snprintf(filename, sizeof(filename), "%s/config.conf", mangoconfig); } set_value_default(); @@ -3255,6 +3277,6 @@ void reset_option(void) { int reload_config(const Arg *arg) { parse_config(); reset_option(); - printstatus(PRINT_ALL); + printstatus(); return 0; } diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 1dc29da..c167915 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -171,7 +171,7 @@ int toggle_trackpad_enable(const Arg *arg) { } int focusmon(const Arg *arg) { - Client *c = NULL, *old_selmon_sel = NULL; + Client *c = NULL; Monitor *m = NULL; if (arg->i != UNDIR) { @@ -192,7 +192,6 @@ int focusmon(const Arg *arg) { if (!m || !m->wlr_output->enabled || m == selmon) return 0; - old_selmon_sel = selmon->sel; selmon = m; if (warpcursor) { warp_cursor_to_selmon(selmon); @@ -202,12 +201,10 @@ int focusmon(const Arg *arg) { selmon->sel = NULL; wlr_seat_pointer_notify_clear_focus(seat); wlr_seat_keyboard_notify_clear_focus(seat); + focusclient(NULL, 0); } else focusclient(c, 1); - if (old_selmon_sel) { - client_set_unfocused_opacity_animation(old_selmon_sel); - } return 0; } @@ -503,7 +500,7 @@ int setlayout(const Arg *arg) { selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[jk]; clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); return 0; } } @@ -517,7 +514,7 @@ int setkeymode(const Arg *arg) { } else { keymode.isdefault = false; } - printstatus(PRINT_KEYMODE); + printstatus(); return 1; } @@ -866,7 +863,7 @@ int switch_keyboard_layout(const Arg *arg) { wlr_seat_keyboard_notify_modifiers(seat, &tkb->modifiers); } - printstatus(PRINT_KB_LAYOUT); + printstatus(); return 0; } @@ -907,7 +904,7 @@ int switch_layout(const Arg *arg) { } clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); return 0; } @@ -918,7 +915,7 @@ int switch_layout(const Arg *arg) { jk == LENGTH(layouts) - 1 ? &layouts[0] : &layouts[jk + 1]; clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); return 0; } } @@ -1260,7 +1257,7 @@ int toggletag(const Arg *arg) { focusclient(focustop(selmon), 1); arrange(selmon, false); } - printstatus(PRINT_ALL); + printstatus(); return 0; } @@ -1278,7 +1275,7 @@ int toggleview(const Arg *arg) { focusclient(focustop(selmon), 1); arrange(selmon, false); } - printstatus(PRINT_ALL); + printstatus(); return 0; } @@ -1396,7 +1393,7 @@ int comboview(const Arg *arg) { view(&(Arg){.ui = newtags}, false); } - printstatus(PRINT_ALL); + printstatus(); return 0; } diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h index 649c5f3..eda3f49 100644 --- a/src/ext-protocol/dwl-ipc.h +++ b/src/ext-protocol/dwl-ipc.h @@ -9,9 +9,8 @@ static void dwl_ipc_manager_get_output(struct wl_client *client, static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource); static void dwl_ipc_output_destroy(struct wl_resource *resource); -static void dwl_ipc_output_printstatus(Monitor *monitor, uint32_t event_mask); -static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, - uint32_t event_mask); +static void dwl_ipc_output_printstatus(Monitor *monitor); +static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output); static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, @@ -86,7 +85,7 @@ void dwl_ipc_manager_get_output(struct wl_client *client, wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy); wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); - dwl_ipc_output_printstatus_to(ipc_output, PRINT_ALL); + dwl_ipc_output_printstatus_to(ipc_output); } void dwl_ipc_manager_release(struct wl_client *client, @@ -101,15 +100,14 @@ static void dwl_ipc_output_destroy(struct wl_resource *resource) { } // 修改IPC输出函数,接受掩码参数 -void dwl_ipc_output_printstatus(Monitor *monitor, uint32_t event_mask) { +void dwl_ipc_output_printstatus(Monitor *monitor) { DwlIpcOutput *ipc_output; wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) - dwl_ipc_output_printstatus_to(ipc_output, event_mask); + dwl_ipc_output_printstatus_to(ipc_output); } // 修改主IPC输出函数,根据掩码发送相应事件 -void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, - uint32_t event_mask) { +void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { Monitor *monitor = ipc_output->mon; Client *c = NULL, *focused = NULL; struct wlr_keyboard *keyboard; @@ -117,175 +115,103 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, int tagmask, state, numclients, focused_client, tag; const char *title, *appid, *symbol; char kb_layout[32]; + focused = focustop(monitor); + zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); - // 只在需要时才获取这些数据 - if (event_mask & (PRINT_ACTIVE | PRINT_TAG | PRINT_TITLE | PRINT_APPID | - PRINT_FULLSCREEN | PRINT_FLOATING | PRINT_X | PRINT_Y | - PRINT_WIDTH | PRINT_HEIGHT)) { - focused = focustop(monitor); - } - - // 发送活动状态 - if (event_mask & PRINT_ACTIVE) { - zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); - } - - // 发送标签状态 - if (event_mask & PRINT_TAG) { - for (tag = 0; tag < LENGTH(tags); tag++) { - numclients = state = focused_client = 0; - tagmask = 1 << tag; - if ((tagmask & monitor->tagset[monitor->seltags]) != 0) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; - - if (focused) { - wl_list_for_each(c, &clients, link) { - if (c->mon != monitor) - continue; - if (!(c->tags & tagmask)) - continue; - if (c == focused) - focused_client = 1; - if (c->isurgent) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; - numclients++; - } - } - zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, - numclients, focused_client); + for (tag = 0; tag < LENGTH(tags); tag++) { + numclients = state = focused_client = 0; + tagmask = 1 << tag; + if ((tagmask & monitor->tagset[monitor->seltags]) != 0) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; + wl_list_for_each(c, &clients, link) { + if (c->mon != monitor) + continue; + if (!(c->tags & tagmask)) + continue; + if (c == focused) + focused_client = 1; + if (c->isurgent) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; + numclients++; } + zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, + numclients, focused_client); } - // 只在需要时才获取标题和应用ID - if (event_mask & (PRINT_TITLE | PRINT_APPID)) { - title = focused ? client_get_title(focused) : ""; - appid = focused ? client_get_appid(focused) : ""; + title = focused ? client_get_title(focused) : ""; + appid = focused ? client_get_appid(focused) : ""; + + if (monitor->isoverview) { + symbol = overviewlayout.symbol; + } else { + symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; } - // 获取布局符号 - if (event_mask & PRINT_LAYOUT_SYMBOL) { - if (monitor->isoverview) { - symbol = overviewlayout.symbol; - } else { - symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; - } - } + keyboard = &kb_group->wlr_group->keyboard; + current = xkb_state_serialize_layout(keyboard->xkb_state, + XKB_STATE_LAYOUT_EFFECTIVE); + get_layout_abbr(kb_layout, + xkb_keymap_layout_get_name(keyboard->keymap, current)); - // 发送布局索引 - if (event_mask & PRINT_LAYOUT) { - zdwl_ipc_output_v2_send_layout( - ipc_output->resource, - monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); - } - - // 发送标题 - if (event_mask & PRINT_TITLE) { - zdwl_ipc_output_v2_send_title(ipc_output->resource, - title ? title : broken); - } - - // 发送应用ID - if (event_mask & PRINT_APPID) { - zdwl_ipc_output_v2_send_appid(ipc_output->resource, - appid ? appid : broken); - } - - // 发送布局符号 - if (event_mask & PRINT_LAYOUT_SYMBOL) { - zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); - } - - // 发送全屏状态 - if ((event_mask & PRINT_FULLSCREEN) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { + zdwl_ipc_output_v2_send_layout( + ipc_output->resource, + monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); + zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken); + zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); + zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, focused ? focused->isfullscreen : 0); } - - // 发送浮动状态 - if ((event_mask & PRINT_FLOATING) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { zdwl_ipc_output_v2_send_floating(ipc_output->resource, focused ? focused->isfloating : 0); } - - // 发送X坐标 - if ((event_mask & PRINT_X) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) { zdwl_ipc_output_v2_send_x(ipc_output->resource, focused ? focused->geom.x : 0); } - - // 发送Y坐标 - if ((event_mask & PRINT_Y) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) { zdwl_ipc_output_v2_send_y(ipc_output->resource, focused ? focused->geom.y : 0); } - - // 发送宽度 - if ((event_mask & PRINT_WIDTH) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) { zdwl_ipc_output_v2_send_width(ipc_output->resource, focused ? focused->geom.width : 0); } - - // 发送高度 - if ((event_mask & PRINT_HEIGHT) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) { zdwl_ipc_output_v2_send_height(ipc_output->resource, focused ? focused->geom.height : 0); } - - // 发送最后图层 - if ((event_mask & PRINT_LAST_LAYER) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) { zdwl_ipc_output_v2_send_last_layer(ipc_output->resource, monitor->last_surface_ws_name); } - // 获取键盘布局(只在需要时) - if (event_mask & PRINT_KB_LAYOUT) { - keyboard = &kb_group->wlr_group->keyboard; - current = xkb_state_serialize_layout(keyboard->xkb_state, - XKB_STATE_LAYOUT_EFFECTIVE); - get_layout_abbr(kb_layout, - xkb_keymap_layout_get_name(keyboard->keymap, current)); - } - - // 发送键盘布局 - if ((event_mask & PRINT_KB_LAYOUT) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_KB_LAYOUT_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_KB_LAYOUT_SINCE_VERSION) { zdwl_ipc_output_v2_send_kb_layout(ipc_output->resource, kb_layout); } - // 发送键模式 - if ((event_mask & PRINT_KEYMODE) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_KEYMODE_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_KEYMODE_SINCE_VERSION) { zdwl_ipc_output_v2_send_keymode(ipc_output->resource, keymode.mode); } - // 发送缩放因子 - if ((event_mask & PRINT_SCALEFACTOR) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_SCALEFACTOR_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_SCALEFACTOR_SINCE_VERSION) { zdwl_ipc_output_v2_send_scalefactor(ipc_output->resource, monitor->wlr_output->scale * 100); } - // 发送帧结束标记 - if (event_mask & PRINT_FRAME) { - zdwl_ipc_output_v2_send_frame(ipc_output->resource); - } + zdwl_ipc_output_v2_send_frame(ipc_output->resource); } void dwl_ipc_output_set_client_tags(struct wl_client *client, @@ -313,7 +239,7 @@ void dwl_ipc_output_set_client_tags(struct wl_client *client, if (selmon == monitor) focusclient(focustop(monitor), 1); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); } void dwl_ipc_output_set_layout(struct wl_client *client, @@ -332,7 +258,7 @@ void dwl_ipc_output_set_layout(struct wl_client *client, monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; clear_fullscreen_and_maximized_state(monitor); arrange(monitor, false); - printstatus(PRINT_ALL); + printstatus(); } void dwl_ipc_output_set_tags(struct wl_client *client, diff --git a/src/fetch/client.h b/src/fetch/client.h index d5c0b5d..032f4ae 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -40,10 +40,21 @@ Client *get_client_by_id_or_title(const char *arg_id, const char *arg_title) { continue; } - if (!(appid = client_get_appid(c))) + if (c->swallowedby) { + appid = client_get_appid(c->swallowedby); + title = client_get_title(c->swallowedby); + } else { + appid = client_get_appid(c); + title = client_get_title(c); + } + + if (!appid) { appid = broken; - if (!(title = client_get_title(c))) + } + + if (!title) { title = broken; + } if (arg_id && strncmp(arg_id, "none", 4) == 0) arg_id = NULL; @@ -181,7 +192,9 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, int sel_x = tc->geom.x; int sel_y = tc->geom.y; long long int distance = LLONG_MAX; + long long int same_monitor_distance = LLONG_MAX; Client *tempFocusClients = NULL; + Client *tempSameMonitorFocusClients = NULL; switch (arg->i) { case UP: @@ -212,6 +225,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -244,6 +262,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -276,6 +299,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -308,6 +336,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -315,7 +348,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, } free(tempClients); // 释放内存 - return tempFocusClients; + if(tempSameMonitorFocusClients) { + return tempSameMonitorFocusClients; + } else { + return tempFocusClients; + } } Client *direction_select(const Arg *arg) { diff --git a/src/fetch/common.h b/src/fetch/common.h index c86a3fe..c96ee31 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -26,24 +26,6 @@ int isdescprocess(pid_t p, pid_t c) { return (int)c; } -char *get_autostart_path(char *autostart_path, uint32_t buf_size) { - const char *mangoconfig = getenv("MANGOCONFIG"); - - if (mangoconfig && mangoconfig[0] != '\0') { - snprintf(autostart_path, buf_size, "%s/autostart.sh", mangoconfig); - } else { - const char *homedir = getenv("HOME"); - if (!homedir) { - fprintf(stderr, "Error: HOME environment variable not set.\n"); - return NULL; - } - snprintf(autostart_path, buf_size, "%s/.config/mango/autostart.sh", - homedir); - } - - return autostart_path; -} - void get_layout_abbr(char *abbr, const char *full_name) { // 清空输出缓冲区 abbr[0] = '\0'; diff --git a/src/mango.c b/src/mango.c index 68d651d..8811c84 100644 --- a/src/mango.c +++ b/src/mango.c @@ -402,6 +402,7 @@ struct Client { int force_tearing; int allow_shortcuts_inhibit; float scroller_proportion_single; + bool isfocusing; }; typedef struct { @@ -536,7 +537,6 @@ arrange(Monitor *m, static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); -static char *get_autostart_path(char *, uint32_t); // 自启动命令执行 static void handle_print_status(struct wl_listener *listener, void *data); static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 @@ -630,7 +630,7 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, 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(uint32_t event_mask); +static void printstatus(void); static void quitsignal(int signo); static void powermgrsetmode(struct wl_listener *listener, void *data); static void rendermon(struct wl_listener *listener, void *data); @@ -852,6 +852,7 @@ struct dvec2 *baked_points_focus; static struct wl_event_source *hide_source; static bool cursor_hidden = false; static bool tag_combo = false; +static const char *cli_config_path = NULL; static KeyMode keymode = { .mode = {'d', 'e', 'f', 'a', 'u', 'l', 't', '\0'}, .isdefault = true, @@ -2168,7 +2169,7 @@ void closemon(Monitor *m) { } if (selmon) { focusclient(focustop(selmon), 1); - printstatus(PRINT_ALL); + printstatus(); } } @@ -2802,7 +2803,7 @@ void createmon(struct wl_listener *listener, void *data) { add_workspace_by_tag(i, m); } - printstatus(PRINT_ALL); + printstatus(); } void // fix for 0.5 @@ -3166,6 +3167,7 @@ void destroykeyboardgroup(struct wl_listener *listener, void *data) { void focusclient(Client *c, int lift) { Client *last_focus_client = NULL; + Monitor *um = NULL; struct wlr_surface *old_keyboard_focus_surface = seat->keyboard_state.focused_surface; @@ -3205,9 +3207,11 @@ void focusclient(Client *c, int lift) { selmon = c->mon; selmon->prevsel = selmon->sel; selmon->sel = c; + c->isfocusing = true; if (last_focus_client && !last_focus_client->iskilling && last_focus_client != c) { + last_focus_client->isfocusing = false; client_set_unfocused_opacity_animation(last_focus_client); } @@ -3230,6 +3234,15 @@ void focusclient(Client *c, int lift) { c->isurgent = 0; } + // update other monitor focus disappear + wl_list_for_each(um, &mons, link) { + if (um->wlr_output->enabled && um != selmon && um->sel && + !um->sel->iskilling && um->sel->isfocusing) { + um->sel->isfocusing = false; + client_set_unfocused_opacity_animation(um->sel); + } + } + if (c && !c->iskilling && c->foreign_toplevel) wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); @@ -3258,7 +3271,7 @@ void focusclient(Client *c, int lift) { client_activate_surface(old_keyboard_focus_surface, 0); } } - printstatus(PRINT_ALL); + printstatus(); if (!c) { @@ -3655,6 +3668,7 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int sx, } void init_client_properties(Client *c) { + c->isfocusing = false; c->ismaximizescreen = 0; c->isfullscreen = 0; c->need_float_size_reduce = 0; @@ -3808,7 +3822,7 @@ mapnotify(struct wl_listener *listener, void *data) { // make sure the animation is open type c->is_pending_open_animation = true; resize(c, c->geom, 0); - printstatus(PRINT_ALL); + printstatus(); } void maximizenotify(struct wl_listener *listener, void *data) { @@ -4008,35 +4022,18 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx, if (!surface && !seat->drag && !cursor_hidden) wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); - if (c && c->mon && !c->animation.running && - (!(c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height || - c->geom.y < c->mon->m.y) || - !ISTILED(c))) { + if (c && c->mon && !c->animation.running && (INSIDEMON(c) || !ISTILED(c))) { scroller_focus_lock = 0; } should_lock = false; - if (!scroller_focus_lock || - !(c && c->mon && - (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height || - c->geom.y < c->mon->m.y))) { - if (c && c->mon && is_scroller_layout(c->mon) && - (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height || - c->geom.y < c->mon->m.y)) { + if (!scroller_focus_lock || !(c && c->mon && !INSIDEMON(c))) { + if (c && c->mon && is_scroller_layout(c->mon) && !INSIDEMON(c)) { should_lock = true; } if (!(!edge_scroller_pointer_focus && c && c->mon && - is_scroller_layout(c->mon) && - (c->geom.x < c->mon->m.x || c->geom.y < c->mon->m.y || - c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height))) + is_scroller_layout(c->mon) && !INSIDEMON(c))) pointerfocus(c, surface, sx, sy, time); if (should_lock && c && c->mon && ISTILED(c) && c == c->mon->sel) { @@ -4164,9 +4161,7 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, } // 修改printstatus函数,接受掩码参数 -void printstatus(uint32_t event_mask) { - wl_signal_emit(&mango_print_status, (void *)(uintptr_t)event_mask); -} +void printstatus(void) { wl_signal_emit(&mango_print_status, NULL); } void powermgrsetmode(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; @@ -4385,7 +4380,6 @@ run(char *startup_cmd) { set_env(); - char autostart_temp_path[1024]; /* Add a Unix socket to the Wayland display. */ const char *socket = wl_display_add_socket_auto(dpy); if (!socket) @@ -4399,9 +4393,7 @@ run(char *startup_cmd) { /* Now that the socket exists and the backend is started, run the * startup command */ - if (!startup_cmd) - startup_cmd = get_autostart_path(autostart_temp_path, - sizeof(autostart_temp_path)); + if (startup_cmd) { int piperw[2]; if (pipe(piperw) < 0) @@ -4426,7 +4418,7 @@ run(char *startup_cmd) { if (fd_set_nonblock(STDOUT_FILENO) < 0) close(STDOUT_FILENO); - printstatus(PRINT_ALL); + printstatus(); /* At this point the outputs are initialized, choose initial selmon * based on cursor position, and set default cursor image */ @@ -4561,7 +4553,7 @@ setfloating(Client *c, int floating) { arrange(c->mon, false); setborder_color(c); - printstatus(PRINT_ALL); + printstatus(); } void reset_maximizescreen_size(Client *c) { @@ -4892,24 +4884,14 @@ void create_output(struct wlr_backend *backend, void *data) { // 修改信号处理函数,接收掩码参数 void handle_print_status(struct wl_listener *listener, void *data) { - uint32_t event_mask = (uintptr_t)data; - // 如果传入的是NULL(旧代码)或0,使用默认的所有事件 - if (!event_mask) { - event_mask = PRINT_ALL; - } - Monitor *m = NULL; wl_list_for_each(m, &mons, link) { if (!m->wlr_output->enabled) { continue; } - // 更新workspace状态(根据掩码决定是否更新) - if (event_mask & PRINT_TAG || event_mask & PRINT_ACTIVE) { - dwl_ext_workspace_printstatus(m); - } + dwl_ext_workspace_printstatus(m); - // 更新IPC输出状态(传入掩码) - dwl_ipc_output_printstatus(m, event_mask); + dwl_ipc_output_printstatus(m); } } @@ -5246,7 +5228,7 @@ void tag_client(const Arg *arg, Client *target_client) { } focusclient(target_client, 1); - printstatus(PRINT_ALL); + printstatus(); } void overview(Monitor *m) { grid(m); } @@ -5454,7 +5436,7 @@ void unmapnotify(struct wl_listener *listener, void *data) { } wlr_scene_node_destroy(&c->scene->node); - printstatus(PRINT_ALL); + printstatus(); motionnotify(0, NULL, 0, 0, 0, 0); } @@ -5602,7 +5584,7 @@ void updatetitle(struct wl_listener *listener, void *data) { if (title && c->foreign_toplevel) wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); if (c == focustop(c->mon)) - printstatus(PRINT_TITLE); + printstatus(); } void // 17 fix to 0.5 @@ -5622,7 +5604,7 @@ urgent(struct wl_listener *listener, void *data) { c->isurgent = 1; if (client_surface(c)->mapped) setborder_color(c); - printstatus(PRINT_ALL); + printstatus(); } } @@ -5639,9 +5621,9 @@ void view_in_mon(const Arg *arg, bool want_animation, Monitor *m, } if (arg->ui == UINT32_MAX) { - m->pertag->prevtag = m->tagset[m->seltags]; + m->pertag->prevtag = get_tags_first_tag_num(m->tagset[m->seltags]); m->seltags ^= 1; /* toggle sel tagset */ - m->pertag->curtag = m->tagset[m->seltags]; + m->pertag->curtag = get_tags_first_tag_num(m->tagset[m->seltags]); goto toggleseltags; } @@ -5677,7 +5659,7 @@ toggleseltags: if (changefocus) focusclient(focustop(m), 1); arrange(m, want_animation); - printstatus(PRINT_ALL); + printstatus(); } void view(const Arg *arg, bool want_animation) { @@ -5820,7 +5802,7 @@ void activatex11(struct wl_listener *listener, void *data) { arrange(c->mon, false); } - printstatus(PRINT_ALL); + printstatus(); } void configurex11(struct wl_listener *listener, void *data) { @@ -5892,7 +5874,7 @@ void sethints(struct wl_listener *listener, void *data) { return; c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); - printstatus(PRINT_ALL); + printstatus(); if (c->isurgent && surface && surface->mapped) setborder_color(c); @@ -5925,13 +5907,15 @@ int main(int argc, char *argv[]) { char *startup_cmd = NULL; int c; - while ((c = getopt(argc, argv, "s:hdv")) != -1) { + while ((c = getopt(argc, argv, "s:c:hdv")) != -1) { if (c == 's') startup_cmd = optarg; else if (c == 'd') log_level = WLR_DEBUG; else if (c == 'v') die("mango " VERSION); + else if (c == 'c') + cli_config_path = optarg; else goto usage; } @@ -5949,5 +5933,5 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; usage: - die("Usage: %s [-v] [-d] [-s startup command]", argv[0]); + die("Usage: %s [-v] [-d] [-c config file] [-s startup command]", argv[0]); }