diff --git a/IM.h b/IM.h index d44c1e6..e0b415e 100644 --- a/IM.h +++ b/IM.h @@ -1,7 +1,7 @@ #ifdef IM #include -#include #include +#include /** * The relay structure manages the relationship between text-input and @@ -19,67 +19,64 @@ // 但这个代码最初是日本人从sway那边抄过来的,sway的架构比较大,我猜会不会是考虑到会有两个input_method实例才这么定义 // 为了考虑万一以后哪个版本要扩充,就保留外层的结构 struct dwl_input_method_relay { - struct wl_list text_inputs; // dwl_text_input::link - struct wlr_input_method_v2 *input_method; // doesn't have to be present + struct wl_list text_inputs; // dwl_text_input::link + struct wlr_input_method_v2 *input_method; // doesn't have to be present - struct dwl_input_popup *popup; + struct dwl_input_popup *popup; - struct wl_listener text_input_new; + struct wl_listener text_input_new; - struct wl_listener input_method_new; - struct wl_listener input_method_commit; - struct wl_listener input_method_destroy; - struct wl_listener input_method_new_popup_surface; - struct wl_listener input_method_grab_keyboard; - struct wl_listener input_method_keyboard_grab_destroy; + struct wl_listener input_method_new; + struct wl_listener input_method_commit; + struct wl_listener input_method_destroy; + struct wl_listener input_method_new_popup_surface; + struct wl_listener input_method_grab_keyboard; + struct wl_listener input_method_keyboard_grab_destroy; }; struct dwl_text_input { - struct dwl_input_method_relay *relay; + struct dwl_input_method_relay *relay; - struct wlr_text_input_v3 *input; - // The surface getting seat's focus. Stored for when text-input cannot - // be sent an enter event immediately after getting focus, e.g. when - // there's no input method available. Cleared once text-input is entered. - struct wlr_surface *pending_focused_surface; + struct wlr_text_input_v3 *input; + // The surface getting seat's focus. Stored for when text-input cannot + // be sent an enter event immediately after getting focus, e.g. when + // there's no input method available. Cleared once text-input is entered. + struct wlr_surface *pending_focused_surface; - struct wl_list link; + struct wl_list link; - struct wl_listener pending_focused_surface_destroy; + struct wl_listener pending_focused_surface_destroy; - struct wl_listener text_input_enable; - //struct wl_listener text_input_commit; - //struct wl_listener text_input_disable; - struct wl_listener text_input_destroy; + struct wl_listener text_input_enable; + // struct wl_listener text_input_commit; + // struct wl_listener text_input_disable; + struct wl_listener text_input_destroy; }; - struct dwl_input_popup { - struct dwl_input_method_relay *relay; - struct wlr_input_popup_surface_v2 *popup_surface; + struct dwl_input_method_relay *relay; + struct wlr_input_popup_surface_v2 *popup_surface; - //struct wlr_scene_node *scene; - struct wlr_scene_tree *scene; - //struct wlr_scene_node *scene_surface; - struct wlr_scene_tree *scene_surface; + // struct wlr_scene_node *scene; + struct wlr_scene_tree *scene; + // struct wlr_scene_node *scene_surface; + struct wlr_scene_tree *scene_surface; - int x, y; - bool visible; + int x, y; + bool visible; - - struct wl_listener popup_map; - struct wl_listener popup_unmap; - struct wl_listener popup_destroy; - //struct wl_listener popup_surface_commit; - //struct wl_listener focused_surface_unmap; + struct wl_listener popup_map; + struct wl_listener popup_unmap; + struct wl_listener popup_destroy; + // struct wl_listener popup_surface_commit; + // struct wl_listener focused_surface_unmap; }; - void dwl_input_method_relay_init(struct dwl_input_method_relay *relay); // Updates currently focused surface. Surface must belong to the same // seat. void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay, - struct wlr_surface *surface); + struct wlr_surface *surface); static void handle_im_grab_keyboard(struct wl_listener *listener, void *data); static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, @@ -98,200 +95,210 @@ struct dwl_input_method_relay *input_relay; * or if event is from virtual keyboard of the same client as grab. * TODO: see https://github.com/swaywm/wlroots/issues/2322 */ -static struct wlr_input_method_keyboard_grab_v2 *keyboard_get_im_grab(Keyboard* kb) { - struct wlr_input_method_v2 *input_method = input_relay->input_method; - struct wlr_virtual_keyboard_v1 *virtual_keyboard = - wlr_input_device_get_virtual_keyboard(&kb->wlr_keyboard->base); - if (!input_method || !input_method->keyboard_grab || (virtual_keyboard && - wl_resource_get_client(virtual_keyboard->resource) == - wl_resource_get_client(input_method->keyboard_grab->resource))) { - if (!input_method){ - wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no input_method"); - } else if (!input_method->keyboard_grab){ - wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no input_method->keyboard_grab"); - } +static struct wlr_input_method_keyboard_grab_v2 * +keyboard_get_im_grab(Keyboard *kb) { + struct wlr_input_method_v2 *input_method = input_relay->input_method; + struct wlr_virtual_keyboard_v1 *virtual_keyboard = + wlr_input_device_get_virtual_keyboard(&kb->wlr_keyboard->base); + if (!input_method || !input_method->keyboard_grab || + (virtual_keyboard && + wl_resource_get_client(virtual_keyboard->resource) == + wl_resource_get_client(input_method->keyboard_grab->resource))) { + if (!input_method) { + wlr_log(WLR_DEBUG, + "keypress keyboard_get_im_grab return NULL:no input_method"); + } else if (!input_method->keyboard_grab) { + wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no " + "input_method->keyboard_grab"); + } - if (virtual_keyboard) { - wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:virtual_keyboard"); - } + if (virtual_keyboard) { + wlr_log(WLR_DEBUG, + "keypress keyboard_get_im_grab return NULL:virtual_keyboard"); + } - return NULL; - } - return input_method->keyboard_grab; + return NULL; + } + return input_method->keyboard_grab; } static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) { - struct dwl_input_method_relay *relay = wl_container_of(listener, relay, - input_method_grab_keyboard); - //wl_container_of 宏的第二个参数sample, 这里是relay,无须是已经初始化的变量,只要是返回值类型的变量就可以了,这里就是dwl_input_method_relay类型的变量 - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; + struct dwl_input_method_relay *relay = + wl_container_of(listener, relay, input_method_grab_keyboard); + // wl_container_of 宏的第二个参数sample, + // 这里是relay,无须是已经初始化的变量,只要是返回值类型的变量就可以了,这里就是dwl_input_method_relay类型的变量 + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; - // send modifier state to grab - struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(seat); - if (active_keyboard){ - wlr_log(WLR_INFO,"im_grab_keyboard"); - wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab,active_keyboard); - wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab, &active_keyboard->modifiers); - } - else - wlr_log(WLR_INFO,"im_grab_keyboard but no active keyboard"); - + // send modifier state to grab + struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(seat); + if (active_keyboard) { + wlr_log(WLR_INFO, "im_grab_keyboard"); + wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab, + active_keyboard); + wlr_input_method_keyboard_grab_v2_send_modifiers( + keyboard_grab, &active_keyboard->modifiers); + } else + wlr_log(WLR_INFO, "im_grab_keyboard but no active keyboard"); - wl_signal_add(&keyboard_grab->events.destroy, - &relay->input_method_keyboard_grab_destroy); - relay->input_method_keyboard_grab_destroy.notify = - handle_im_keyboard_grab_destroy; + wl_signal_add(&keyboard_grab->events.destroy, + &relay->input_method_keyboard_grab_destroy); + relay->input_method_keyboard_grab_destroy.notify = + handle_im_keyboard_grab_destroy; } -static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, void *data) { - struct dwl_input_method_relay *relay = wl_container_of(listener, relay, - input_method_keyboard_grab_destroy); - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; - wlr_log(WLR_DEBUG,"im_keyboard_grab_destroy"); - wl_list_remove(&relay->input_method_keyboard_grab_destroy.link); - if (keyboard_grab->keyboard) { - // send modifier state to original client - wlr_seat_keyboard_notify_modifiers(keyboard_grab->input_method->seat, - &keyboard_grab->keyboard->modifiers); - } +static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, + void *data) { + struct dwl_input_method_relay *relay = + wl_container_of(listener, relay, input_method_keyboard_grab_destroy); + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; + wlr_log(WLR_DEBUG, "im_keyboard_grab_destroy"); + wl_list_remove(&relay->input_method_keyboard_grab_destroy.link); + if (keyboard_grab->keyboard) { + // send modifier state to original client + wlr_seat_keyboard_notify_modifiers(keyboard_grab->input_method->seat, + &keyboard_grab->keyboard->modifiers); + } } - -static struct dwl_text_input *relay_get_focusable_text_input( - struct dwl_input_method_relay *relay) { - struct dwl_text_input *text_input = NULL; - wl_list_for_each(text_input, &relay->text_inputs, link) { - if (text_input->pending_focused_surface) { - return text_input; - } - } - return NULL; +static struct dwl_text_input * +relay_get_focusable_text_input(struct dwl_input_method_relay *relay) { + struct dwl_text_input *text_input = NULL; + wl_list_for_each(text_input, &relay->text_inputs, link) { + if (text_input->pending_focused_surface) { + return text_input; + } + } + return NULL; } -static struct dwl_text_input *relay_get_focused_text_input( - struct dwl_input_method_relay *relay) { - struct dwl_text_input *text_input = NULL; - wl_list_for_each(text_input, &relay->text_inputs, link) { - if (text_input->input->focused_surface) { - return text_input; - } - } - return NULL; +static struct dwl_text_input * +relay_get_focused_text_input(struct dwl_input_method_relay *relay) { + struct dwl_text_input *text_input = NULL; + wl_list_for_each(text_input, &relay->text_inputs, link) { + if (text_input->input->focused_surface) { + return text_input; + } + } + return NULL; } static void handle_im_commit(struct wl_listener *listener, void *data) { - struct wlr_input_method_v2 *context; + struct wlr_input_method_v2 *context; - struct dwl_input_method_relay *relay = wl_container_of(listener, relay, - input_method_commit); + struct dwl_input_method_relay *relay = + wl_container_of(listener, relay, input_method_commit); - struct dwl_text_input *text_input = relay_get_focused_text_input(relay); - if (!text_input) { - return; - } + struct dwl_text_input *text_input = relay_get_focused_text_input(relay); + if (!text_input) { + return; + } - context = data; - assert(context == relay->input_method); - if (context->current.preedit.text) { - wlr_text_input_v3_send_preedit_string(text_input->input, - context->current.preedit.text, - context->current.preedit.cursor_begin, - context->current.preedit.cursor_end); - wlr_log(WLR_DEBUG,"preedit_text: %s", context->current.preedit.text); - } - if (context->current.commit_text) { - wlr_text_input_v3_send_commit_string(text_input->input, - context->current.commit_text); - wlr_log(WLR_DEBUG,"commit_text: %s", context->current.commit_text); - } - if (context->current.delete.before_length - || context->current.delete.after_length) { - wlr_text_input_v3_send_delete_surrounding_text(text_input->input, - context->current.delete.before_length, - context->current.delete.after_length); - } - wlr_text_input_v3_send_done(text_input->input); + context = data; + assert(context == relay->input_method); + if (context->current.preedit.text) { + wlr_text_input_v3_send_preedit_string(text_input->input, + context->current.preedit.text, + context->current.preedit.cursor_begin, + context->current.preedit.cursor_end); + wlr_log(WLR_DEBUG, "preedit_text: %s", context->current.preedit.text); + } + if (context->current.commit_text) { + wlr_text_input_v3_send_commit_string(text_input->input, + context->current.commit_text); + wlr_log(WLR_DEBUG, "commit_text: %s", context->current.commit_text); + } + if (context->current.delete.before_length || + context->current.delete.after_length) { + wlr_text_input_v3_send_delete_surrounding_text( + text_input->input, context->current.delete.before_length, + context->current.delete.after_length); + } + wlr_text_input_v3_send_done(text_input->input); } -static void text_input_set_pending_focused_surface( - struct dwl_text_input *text_input, struct wlr_surface *surface) { - wl_list_remove(&text_input->pending_focused_surface_destroy.link); - text_input->pending_focused_surface = surface; +static void +text_input_set_pending_focused_surface(struct dwl_text_input *text_input, + struct wlr_surface *surface) { + wl_list_remove(&text_input->pending_focused_surface_destroy.link); + text_input->pending_focused_surface = surface; - if (surface) { - wl_signal_add(&surface->events.destroy, - &text_input->pending_focused_surface_destroy); - } else { - wl_list_init(&text_input->pending_focused_surface_destroy.link); - } + if (surface) { + wl_signal_add(&surface->events.destroy, + &text_input->pending_focused_surface_destroy); + } else { + wl_list_init(&text_input->pending_focused_surface_destroy.link); + } } static void handle_im_destroy(struct wl_listener *listener, void *data) { - struct dwl_text_input *text_input; + struct dwl_text_input *text_input; - struct dwl_input_method_relay *relay = wl_container_of(listener, relay, - input_method_destroy); - struct wlr_input_method_v2 *context = data; - wlr_log(WLR_INFO,"IM destroy"); - assert(context == relay->input_method); - relay->input_method = NULL; + struct dwl_input_method_relay *relay = + wl_container_of(listener, relay, input_method_destroy); + struct wlr_input_method_v2 *context = data; + wlr_log(WLR_INFO, "IM destroy"); + assert(context == relay->input_method); + relay->input_method = NULL; - text_input = relay_get_focused_text_input(relay); - if (text_input) { - // keyboard focus is still there, so keep the surface at hand in case - // the input method returns - text_input_set_pending_focused_surface(text_input, - text_input->input->focused_surface); - wlr_text_input_v3_send_leave(text_input->input); - } + text_input = relay_get_focused_text_input(relay); + if (text_input) { + // keyboard focus is still there, so keep the surface at hand in case + // the input method returns + text_input_set_pending_focused_surface(text_input, + text_input->input->focused_surface); + wlr_text_input_v3_send_leave(text_input->input); + } } static void relay_send_im_state(struct dwl_input_method_relay *relay, - struct wlr_text_input_v3 *input) { - struct wlr_input_method_v2 *input_method = relay->input_method; - if (!input_method) { - wlr_log(WLR_INFO, "Sending IM_DONE but im is gone"); - return; - } - // TODO: only send each of those if they were modified - wlr_input_method_v2_send_surrounding_text(input_method, - input->current.surrounding.text, input->current.surrounding.cursor, - input->current.surrounding.anchor); - wlr_input_method_v2_send_text_change_cause(input_method, - input->current.text_change_cause); - wlr_input_method_v2_send_content_type(input_method, - input->current.content_type.hint, input->current.content_type.purpose); - wlr_input_method_v2_send_done(input_method); - // TODO: pass intent, display popup size + struct wlr_text_input_v3 *input) { + struct wlr_input_method_v2 *input_method = relay->input_method; + if (!input_method) { + wlr_log(WLR_INFO, "Sending IM_DONE but im is gone"); + return; + } + // TODO: only send each of those if they were modified + wlr_input_method_v2_send_surrounding_text( + input_method, input->current.surrounding.text, + input->current.surrounding.cursor, input->current.surrounding.anchor); + wlr_input_method_v2_send_text_change_cause(input_method, + input->current.text_change_cause); + wlr_input_method_v2_send_content_type(input_method, + input->current.content_type.hint, + input->current.content_type.purpose); + wlr_input_method_v2_send_done(input_method); + // TODO: pass intent, display popup size } static void handle_text_input_enable(struct wl_listener *listener, void *data) { - struct dwl_text_input *text_input = wl_container_of(listener, text_input, - text_input_enable); - if (text_input->relay->input_method == NULL) { - wlr_log(WLR_INFO, "text_input_enable but input method is NULL"); - return; - } + struct dwl_text_input *text_input = + wl_container_of(listener, text_input, text_input_enable); + if (text_input->relay->input_method == NULL) { + wlr_log(WLR_INFO, "text_input_enable but input method is NULL"); + return; + } - wlr_log(WLR_INFO,"text_input_enable"); + wlr_log(WLR_INFO, "text_input_enable"); #ifdef XWAYLAND - wlr_input_method_v2_send_activate(text_input->relay->input_method); - wlr_log(WLR_INFO,"input_method activate for xwayland"); + wlr_input_method_v2_send_activate(text_input->relay->input_method); + wlr_log(WLR_INFO, "input_method activate for xwayland"); #endif - relay_send_im_state(text_input->relay, text_input->input); + relay_send_im_state(text_input->relay, text_input->input); } /* static void handle_text_input_commit(struct wl_listener *listener, */ /* void *data) { */ -/* struct dwl_text_input *text_input = wl_container_of(listener, text_input, */ +/* struct dwl_text_input *text_input = wl_container_of(listener, + * text_input, */ /* text_input_commit); */ /* if (!text_input->input->current_enabled) { */ /* wlr_log(WLR_INFO, "text_input_commit but not enabled"); */ /* return; */ /* } */ /* if (text_input->relay->input_method == NULL) { */ -/* wlr_log(WLR_INFO, "text_input_commit but input method is NULL"); */ +/* wlr_log(WLR_INFO, "text_input_commit but input method is NULL"); + */ /* return; */ /* } */ /* wlr_log(WLR_DEBUG, "text_input_commit"); */ @@ -299,403 +306,427 @@ static void handle_text_input_enable(struct wl_listener *listener, void *data) { /* } */ static void relay_disable_text_input(struct dwl_input_method_relay *relay, - struct dwl_text_input *text_input) { - if (relay->input_method == NULL) { - wlr_log(WLR_INFO, "text_input_disable, but input method is NULL"); - return; - } - wlr_log(WLR_INFO,"text_input_disable"); - + struct dwl_text_input *text_input) { + if (relay->input_method == NULL) { + wlr_log(WLR_INFO, "text_input_disable, but input method is NULL"); + return; + } + wlr_log(WLR_INFO, "text_input_disable"); + #ifdef XWAYLAND - // https://gitee.com/guyuming76/dwl/commit/59328d6ecbbef1b1cd6e5ea8d90d78ccddd5c263 - wlr_input_method_v2_send_deactivate(relay->input_method); - wlr_log(WLR_INFO,"input_method deactivate for xwayland"); + // https://gitee.com/guyuming76/dwl/commit/59328d6ecbbef1b1cd6e5ea8d90d78ccddd5c263 + wlr_input_method_v2_send_deactivate(relay->input_method); + wlr_log(WLR_INFO, "input_method deactivate for xwayland"); #endif - //but if you keep the line above while remove the line below, input Chinese in geogebra(xwayland) won't work - relay_send_im_state(relay, text_input->input); + // but if you keep the line above while remove the line below, input Chinese + // in geogebra(xwayland) won't work + relay_send_im_state(relay, text_input->input); } - static void handle_text_input_destroy(struct wl_listener *listener, - void *data) { - struct dwl_text_input *text_input = wl_container_of(listener, text_input, - text_input_destroy); + void *data) { + struct dwl_text_input *text_input = + wl_container_of(listener, text_input, text_input_destroy); - if (text_input->input->current_enabled) { - wlr_log(WLR_INFO,"text_input_destroy when still enabled"); - relay_disable_text_input(text_input->relay, text_input); - } - else { - wlr_log(WLR_INFO,"text_input_destroy"); - } - - text_input_set_pending_focused_surface(text_input, NULL); - //wl_list_remove(&text_input->text_input_commit.link); - wl_list_remove(&text_input->text_input_destroy.link); - //wl_list_remove(&text_input->text_input_disable.link); - wl_list_remove(&text_input->text_input_enable.link); - wl_list_remove(&text_input->link); - free(text_input); + if (text_input->input->current_enabled) { + wlr_log(WLR_INFO, "text_input_destroy when still enabled"); + relay_disable_text_input(text_input->relay, text_input); + } else { + wlr_log(WLR_INFO, "text_input_destroy"); + } + + text_input_set_pending_focused_surface(text_input, NULL); + // wl_list_remove(&text_input->text_input_commit.link); + wl_list_remove(&text_input->text_input_destroy.link); + // wl_list_remove(&text_input->text_input_disable.link); + wl_list_remove(&text_input->text_input_enable.link); + wl_list_remove(&text_input->link); + free(text_input); } static void handle_pending_focused_surface_destroy(struct wl_listener *listener, - void *data) { - struct dwl_text_input *text_input = wl_container_of(listener, text_input, - pending_focused_surface_destroy); - struct wlr_surface *surface = data; - assert(text_input->pending_focused_surface == surface); - text_input->pending_focused_surface = NULL; - wl_list_remove(&text_input->pending_focused_surface_destroy.link); - wl_list_init(&text_input->pending_focused_surface_destroy.link); + void *data) { + struct dwl_text_input *text_input = + wl_container_of(listener, text_input, pending_focused_surface_destroy); + struct wlr_surface *surface = data; + assert(text_input->pending_focused_surface == surface); + text_input->pending_focused_surface = NULL; + wl_list_remove(&text_input->pending_focused_surface_destroy.link); + wl_list_init(&text_input->pending_focused_surface_destroy.link); } - static void relay_handle_text_input_new(struct wl_listener *listener, - void *data) { - struct dwl_input_method_relay *relay = wl_container_of(listener, relay, - text_input_new); - struct wlr_text_input_v3 *wlr_text_input = data; - if (seat != wlr_text_input->seat) { - return; - } + void *data) { + struct dwl_input_method_relay *relay = + wl_container_of(listener, relay, text_input_new); + struct wlr_text_input_v3 *wlr_text_input = data; + if (seat != wlr_text_input->seat) { + return; + } - struct dwl_text_input *input; - input = calloc(1, sizeof(*input)); - if (!input) { - wlr_log(WLR_ERROR, "dwl_text_input calloc failed"); - return; - } - wlr_log(WLR_INFO, "dwl_text_input calloc"); - input->input = wlr_text_input; - input->relay = relay; + struct dwl_text_input *input; + input = calloc(1, sizeof(*input)); + if (!input) { + wlr_log(WLR_ERROR, "dwl_text_input calloc failed"); + return; + } + wlr_log(WLR_INFO, "dwl_text_input calloc"); + input->input = wlr_text_input; + input->relay = relay; - wl_list_insert(&relay->text_inputs, &input->link); + wl_list_insert(&relay->text_inputs, &input->link); - input->text_input_enable.notify = handle_text_input_enable; - wl_signal_add(&wlr_text_input->events.enable, &input->text_input_enable); + input->text_input_enable.notify = handle_text_input_enable; + wl_signal_add(&wlr_text_input->events.enable, &input->text_input_enable); - //input->text_input_commit.notify = handle_text_input_commit; - //wl_signal_add(&text_input->events.commit, &input->text_input_commit); + // input->text_input_commit.notify = handle_text_input_commit; + // wl_signal_add(&text_input->events.commit, &input->text_input_commit); - /* input->text_input_disable.notify = handle_text_input_disable; */ - /* wl_signal_add(&text_input->events.disable, &input->text_input_disable); */ + /* input->text_input_disable.notify = handle_text_input_disable; */ + /* wl_signal_add(&text_input->events.disable, &input->text_input_disable); */ - input->text_input_destroy.notify = handle_text_input_destroy; - wl_signal_add(&wlr_text_input->events.destroy, &input->text_input_destroy); + input->text_input_destroy.notify = handle_text_input_destroy; + wl_signal_add(&wlr_text_input->events.destroy, &input->text_input_destroy); - input->pending_focused_surface_destroy.notify = - handle_pending_focused_surface_destroy; - wl_list_init(&input->pending_focused_surface_destroy.link); + input->pending_focused_surface_destroy.notify = + handle_pending_focused_surface_destroy; + wl_list_init(&input->pending_focused_surface_destroy.link); } - -static LayerSurface* layer_surface_from_wlr_layer_surface_v1( - struct wlr_layer_surface_v1* layer_surface) { - return layer_surface->data; +static LayerSurface *layer_surface_from_wlr_layer_surface_v1( + struct wlr_layer_surface_v1 *layer_surface) { + return layer_surface->data; } - static void get_parent_and_output_box(struct wlr_surface *focused_surface, - struct wlr_box *parent, struct wlr_box *output_box) { - struct wlr_output *output; - struct wlr_box output_box_tmp; - struct wlr_layer_surface_v1 *layer_surface; - Client *client = NULL; - LayerSurface *l = NULL; + struct wlr_box *parent, + struct wlr_box *output_box) { + struct wlr_output *output; + struct wlr_box output_box_tmp; + struct wlr_layer_surface_v1 *layer_surface; + Client *client = NULL; + LayerSurface *l = NULL; - if ((layer_surface=wlr_layer_surface_v1_try_from_wlr_surface(focused_surface))) { - LayerSurface* layer = - layer_surface_from_wlr_layer_surface_v1(layer_surface); - output = layer->layer_surface->output; - wlr_output_layout_get_box(output_layout, output,&output_box_tmp); - *parent = layer->geom; - parent->x += output_box_tmp.x; - parent->y += output_box_tmp.y; - wlr_log(WLR_INFO,"get_parent_and_output_box layersurface output_box_tmp->x %d y %d",output_box_tmp.x, output_box_tmp.y); - wlr_log(WLR_INFO,"get_parent_and_output_box layersurface parent->x %d y %d",parent->x,parent->y); - } else { - toplevel_from_wlr_surface(focused_surface, &client, &l); - - output = wlr_output_layout_output_at(output_layout, - client->geom.x, client->geom.y); - wlr_output_layout_get_box(output_layout, output,&output_box_tmp); - - parent->x = client->geom.x + client->bw; - parent->y = client->geom.y + client->bw; - parent->width = client->geom.width; - parent->height = client->geom.height; - wlr_log(WLR_INFO,"get_parent_and_output_box client output_box_tmp->x %d y %d",output_box_tmp.x, output_box_tmp.y); - wlr_log(WLR_INFO,"get_parent_and_output_box client client->geom.x %d y %d",client->geom.x,client->geom.y); - wlr_log(WLR_INFO,"get_parent_and_output_box client client->bw %d",client->bw); - wlr_log(WLR_INFO,"get_parent_and_output_box client parent->x %d y %d",parent->x,parent->y); - } + if ((layer_surface = + wlr_layer_surface_v1_try_from_wlr_surface(focused_surface))) { + LayerSurface *layer = + layer_surface_from_wlr_layer_surface_v1(layer_surface); + output = layer->layer_surface->output; + wlr_output_layout_get_box(output_layout, output, &output_box_tmp); + *parent = layer->geom; + parent->x += output_box_tmp.x; + parent->y += output_box_tmp.y; + wlr_log(WLR_INFO, + "get_parent_and_output_box layersurface output_box_tmp->x %d y %d", + output_box_tmp.x, output_box_tmp.y); + wlr_log(WLR_INFO, + "get_parent_and_output_box layersurface parent->x %d y %d", + parent->x, parent->y); + } else { + toplevel_from_wlr_surface(focused_surface, &client, &l); - //*output_box = output_box_tmp; - memcpy(output_box,&output_box_tmp,sizeof(struct wlr_box)); - wlr_log(WLR_INFO,"get_parent_and_output_box output_box x %d y %d width %d height %d",output_box->x,output_box->y,output_box->width,output_box->height); + output = wlr_output_layout_output_at(output_layout, client->geom.x, + client->geom.y); + wlr_output_layout_get_box(output_layout, output, &output_box_tmp); + + parent->x = client->geom.x + client->bw; + parent->y = client->geom.y + client->bw; + parent->width = client->geom.width; + parent->height = client->geom.height; + wlr_log(WLR_INFO, + "get_parent_and_output_box client output_box_tmp->x %d y %d", + output_box_tmp.x, output_box_tmp.y); + wlr_log(WLR_INFO, + "get_parent_and_output_box client client->geom.x %d y %d", + client->geom.x, client->geom.y); + wlr_log(WLR_INFO, "get_parent_and_output_box client client->bw %d", + client->bw); + wlr_log(WLR_INFO, "get_parent_and_output_box client parent->x %d y %d", + parent->x, parent->y); + } + + //*output_box = output_box_tmp; + memcpy(output_box, &output_box_tmp, sizeof(struct wlr_box)); + wlr_log(WLR_INFO, + "get_parent_and_output_box output_box x %d y %d width %d height %d", + output_box->x, output_box->y, output_box->width, output_box->height); } -// 如果当前focused wlr_text_input_v3.features 满足 WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE, 不含这个feature就弹出在父窗口左上角 -// 根据 wlr_text_input_v3.current.cursor_rectangle 计算出一个wlr_box -// 再调用 wlr_input_popup_surface_v2_send_text_input_rectangle 和 wlr_scene_node_set_position +// 如果当前focused wlr_text_input_v3.features 满足 +// WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE, +// 不含这个feature就弹出在父窗口左上角 根据 +// wlr_text_input_v3.current.cursor_rectangle 计算出一个wlr_box 再调用 +// wlr_input_popup_surface_v2_send_text_input_rectangle 和 +// wlr_scene_node_set_position static void input_popup_update(struct dwl_input_popup *popup) { - struct wlr_surface* focused_surface; - struct wlr_box output_box, parent, input_cursor; - int x1, x2, y1, y2, x, y, available_right, available_left, available_down, - available_up, popup_width, popup_height; - bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds; + struct wlr_surface *focused_surface; + struct wlr_box output_box, parent, input_cursor; + int x1, x2, y1, y2, x, y, available_right, available_left, available_down, + available_up, popup_width, popup_height; + bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds; - struct dwl_text_input *text_input = - relay_get_focused_text_input(popup->relay); - if (!text_input|| !text_input->input->focused_surface) { - return; - } + struct dwl_text_input *text_input = + relay_get_focused_text_input(popup->relay); + if (!text_input || !text_input->input->focused_surface) { + return; + } - //TODO: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/743da5c0ae723098fe772aadb93810f60e700ab9 + // TODO: + // https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/743da5c0ae723098fe772aadb93810f60e700ab9 - if (!popup->popup_surface->surface->mapped) { - return; - } + if (!popup->popup_surface->surface->mapped) { + return; + } - cursor_rect = text_input->input->current.features - & WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE; + cursor_rect = text_input->input->current.features & + WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE; - focused_surface = text_input->input->focused_surface; - input_cursor = text_input->input->current.cursor_rectangle; + focused_surface = text_input->input->focused_surface; + input_cursor = text_input->input->current.cursor_rectangle; - get_parent_and_output_box(focused_surface, &parent, &output_box); + get_parent_and_output_box(focused_surface, &parent, &output_box); - popup_width = popup->popup_surface->surface->current.width; - popup_height = popup->popup_surface->surface->current.height; + popup_width = popup->popup_surface->surface->current.width; + popup_height = popup->popup_surface->surface->current.height; - if (!cursor_rect) { - input_cursor.x = 0; - input_cursor.y = 0; - input_cursor.width = parent.width; - input_cursor.height = parent.height; - wlr_log(WLR_INFO,"input_popup_update !cursor_rect"); + if (!cursor_rect) { + input_cursor.x = 0; + input_cursor.y = 0; + input_cursor.width = parent.width; + input_cursor.height = parent.height; + wlr_log(WLR_INFO, "input_popup_update !cursor_rect"); - popup->x=parent.x; - popup->y=parent.y; - popup->visible=true; - } - else { - wlr_log(WLR_INFO,"input_popup_update input_cursor x %d y %d width %d height %d",input_cursor.x,input_cursor.y,input_cursor.width,input_cursor.height); + popup->x = parent.x; + popup->y = parent.y; + popup->visible = true; + } else { + wlr_log(WLR_INFO, + "input_popup_update input_cursor x %d y %d width %d height %d", + input_cursor.x, input_cursor.y, input_cursor.width, + input_cursor.height); - x1 = parent.x + input_cursor.x; - x2 = parent.x + input_cursor.x + input_cursor.width; - y1 = parent.y + input_cursor.y; - y2 = parent.y + input_cursor.y + input_cursor.height; - x = x1; - y = y2; + x1 = parent.x + input_cursor.x; + x2 = parent.x + input_cursor.x + input_cursor.width; + y1 = parent.y + input_cursor.y; + y2 = parent.y + input_cursor.y + input_cursor.height; + x = x1; + y = y2; - wlr_log(WLR_INFO,"input_popup_update x1 %d x2 %d y1 %d y2 %d; x %d y %d",x1,x2,y1,y2,x,y); - available_right = output_box.x + output_box.width - x1; - available_left = x2 - output_box.x; - if (available_right < popup_width && available_left > available_right) { - x = x2 - popup_width; - wlr_log(WLR_INFO,"input_popup_update available_left %d popup_width %d available_right %d; x %d",available_left,popup_width,available_right,x); - } + wlr_log(WLR_INFO, "input_popup_update x1 %d x2 %d y1 %d y2 %d; x %d y %d", + x1, x2, y1, y2, x, y); + available_right = output_box.x + output_box.width - x1; + available_left = x2 - output_box.x; + if (available_right < popup_width && available_left > available_right) { + x = x2 - popup_width; + wlr_log(WLR_INFO, + "input_popup_update available_left %d popup_width %d " + "available_right %d; x %d", + available_left, popup_width, available_right, x); + } - available_down = output_box.y + output_box.height - y2; - available_up = y1 - output_box.y; - if (available_down < popup_height && available_up > available_down) { - y = y1 - popup_height; - wlr_log(WLR_INFO,"input_popup_update available up %d popup_height %d available_down %d; y %d",available_up,popup_height,available_down,y); - } + available_down = output_box.y + output_box.height - y2; + available_up = y1 - output_box.y; + if (available_down < popup_height && available_up > available_down) { + y = y1 - popup_height; + wlr_log(WLR_INFO, + "input_popup_update available up %d popup_height %d " + "available_down %d; y %d", + available_up, popup_height, available_down, y); + } - popup->x = x; - popup->y = y; + popup->x = x; + popup->y = y; - // Hide popup if input_cursor position is completely out of bounds - x1_in_bounds = (input_cursor.x >= 0 && input_cursor.x < parent.width); - y1_in_bounds = (input_cursor.y >= 0 && input_cursor.y < parent.height); - x2_in_bounds = (input_cursor.x + input_cursor.width >= 0 - && input_cursor.x + input_cursor.width < parent.width); - y2_in_bounds = (input_cursor.y + input_cursor.height >= 0 - && input_cursor.y + input_cursor.height < parent.height); - popup->visible = - (x1_in_bounds && y1_in_bounds) || (x2_in_bounds && y2_in_bounds); + // Hide popup if input_cursor position is completely out of bounds + x1_in_bounds = (input_cursor.x >= 0 && input_cursor.x < parent.width); + y1_in_bounds = (input_cursor.y >= 0 && input_cursor.y < parent.height); + x2_in_bounds = (input_cursor.x + input_cursor.width >= 0 && + input_cursor.x + input_cursor.width < parent.width); + y2_in_bounds = (input_cursor.y + input_cursor.height >= 0 && + input_cursor.y + input_cursor.height < parent.height); + popup->visible = + (x1_in_bounds && y1_in_bounds) || (x2_in_bounds && y2_in_bounds); - struct wlr_box box = { - .x = x1 - x, - .y = y1 - y, - .width = input_cursor.width, - .height = input_cursor.height, - }; - wlr_input_popup_surface_v2_send_text_input_rectangle( - popup->popup_surface, &box); - wlr_log(WLR_INFO,"input_popup_update send_text_input_rect box.x %d box.y %d",box.x,box.y); + struct wlr_box box = { + .x = x1 - x, + .y = y1 - y, + .width = input_cursor.width, + .height = input_cursor.height, + }; + wlr_input_popup_surface_v2_send_text_input_rectangle(popup->popup_surface, + &box); + wlr_log(WLR_INFO, + "input_popup_update send_text_input_rect box.x %d box.y %d", box.x, + box.y); + } - } - - wlr_log(WLR_INFO,"input_popup_update x %d y %d visible %s",popup->x,popup->y,popup->visible?"true":"false"); - wlr_scene_node_set_position(&popup->scene->node, popup->x, popup->y); + wlr_log(WLR_INFO, "input_popup_update x %d y %d visible %s", popup->x, + popup->y, popup->visible ? "true" : "false"); + wlr_scene_node_set_position(&popup->scene->node, popup->x, popup->y); } static void handle_im_popup_map(struct wl_listener *listener, void *data) { - struct dwl_input_popup *popup = - wl_container_of(listener, popup, popup_map); + struct dwl_input_popup *popup = wl_container_of(listener, popup, popup_map); - wlr_log(WLR_INFO, "IM_popup_map"); - - //popup->scene = &wlr_scene_tree_create(layers[LyrIMPopup])->node; - popup->scene = wlr_scene_tree_create(layers[LyrIMPopup]); - popup->scene_surface = wlr_scene_subsurface_tree_create(popup->scene,popup->popup_surface->surface); - //popup->scene_surface = &wlr_scene_subsurface_tree_create(popup->scene->parent,popup->popup_surface->surface)->node; - //popup->scene_surface->data = popup; - popup->scene_surface->node.data = popup; + wlr_log(WLR_INFO, "IM_popup_map"); - input_popup_update(popup); + // popup->scene = &wlr_scene_tree_create(layers[LyrIMPopup])->node; + popup->scene = wlr_scene_tree_create(layers[LyrIMPopup]); + popup->scene_surface = wlr_scene_subsurface_tree_create( + popup->scene, popup->popup_surface->surface); + // popup->scene_surface = + // &wlr_scene_subsurface_tree_create(popup->scene->parent,popup->popup_surface->surface)->node; + // popup->scene_surface->data = popup; + popup->scene_surface->node.data = popup; - //wlr_scene_node_set_position(popup->scene, popup->x, popup->y); + input_popup_update(popup); + + // wlr_scene_node_set_position(popup->scene, popup->x, popup->y); } static void handle_im_popup_unmap(struct wl_listener *listener, void *data) { - struct dwl_input_popup *popup = - wl_container_of(listener, popup, popup_unmap); - //input_popup_update(popup); + struct dwl_input_popup *popup = wl_container_of(listener, popup, popup_unmap); + // input_popup_update(popup); - wlr_log(WLR_INFO,"im_popup_unmap"); - wlr_scene_node_destroy(&popup->scene->node); + wlr_log(WLR_INFO, "im_popup_unmap"); + wlr_scene_node_destroy(&popup->scene->node); } static void handle_im_popup_destroy(struct wl_listener *listener, void *data) { - struct dwl_input_method_relay *relay; - struct dwl_input_popup *popup = - wl_container_of(listener, popup, popup_destroy); + struct dwl_input_method_relay *relay; + struct dwl_input_popup *popup = + wl_container_of(listener, popup, popup_destroy); - wlr_log(WLR_INFO,"im_popup_destroy"); - - wl_list_remove(&popup->popup_destroy.link); - wl_list_remove(&popup->popup_unmap.link); - wl_list_remove(&popup->popup_map.link); + wlr_log(WLR_INFO, "im_popup_destroy"); - relay=popup->relay; - free(popup->relay->popup); - relay->popup=NULL; + wl_list_remove(&popup->popup_destroy.link); + wl_list_remove(&popup->popup_unmap.link); + wl_list_remove(&popup->popup_map.link); + + relay = popup->relay; + free(popup->relay->popup); + relay->popup = NULL; } +static void handle_im_new_popup_surface(struct wl_listener *listener, + void *data) { + // struct dwl_text_input* text_input; -static void handle_im_new_popup_surface(struct wl_listener *listener, void *data) { - // struct dwl_text_input* text_input; + struct dwl_input_method_relay *relay = + wl_container_of(listener, relay, input_method_new_popup_surface); + struct dwl_input_popup *popup = calloc(1, sizeof(*popup)); - struct dwl_input_method_relay *relay = wl_container_of(listener, relay, - input_method_new_popup_surface); - struct dwl_input_popup *popup = calloc(1, sizeof(*popup)); + wlr_log(WLR_INFO, "IM_new_popup_surface"); + relay->popup = popup; - wlr_log(WLR_INFO, "IM_new_popup_surface"); - relay->popup = popup; - - popup->relay = relay; - popup->popup_surface = data; - popup->popup_surface->data = popup; + popup->relay = relay; + popup->popup_surface = data; + popup->popup_surface->data = popup; - - wl_signal_add(&popup->popup_surface->surface->events.map, &popup->popup_map); - popup->popup_map.notify = handle_im_popup_map; + wl_signal_add(&popup->popup_surface->surface->events.map, &popup->popup_map); + popup->popup_map.notify = handle_im_popup_map; - wl_signal_add(&popup->popup_surface->surface->events.unmap, &popup->popup_unmap); - popup->popup_unmap.notify = handle_im_popup_unmap; + wl_signal_add(&popup->popup_surface->surface->events.unmap, + &popup->popup_unmap); + popup->popup_unmap.notify = handle_im_popup_unmap; - wl_signal_add( - &popup->popup_surface->events.destroy, &popup->popup_destroy); - popup->popup_destroy.notify = handle_im_popup_destroy; + wl_signal_add(&popup->popup_surface->events.destroy, &popup->popup_destroy); + popup->popup_destroy.notify = handle_im_popup_destroy; } - static void relay_handle_input_method_new(struct wl_listener *listener, - void *data) { - struct dwl_text_input *text_input; + void *data) { + struct dwl_text_input *text_input; - struct dwl_input_method_relay *relay = wl_container_of(listener, relay, - input_method_new); + struct dwl_input_method_relay *relay = + wl_container_of(listener, relay, input_method_new); - struct wlr_input_method_v2 *input_method = data; - if (seat != input_method->seat) { - wlr_log(WLR_INFO,"input_method_new Seat does not match"); - return; - } + struct wlr_input_method_v2 *input_method = data; + if (seat != input_method->seat) { + wlr_log(WLR_INFO, "input_method_new Seat does not match"); + return; + } - if (relay->input_method != NULL) { - wlr_log(WLR_INFO, "input_method_new Attempted to connect second input method to a seat"); - wlr_input_method_v2_send_unavailable(input_method); - return; - } + if (relay->input_method != NULL) { + wlr_log( + WLR_INFO, + "input_method_new Attempted to connect second input method to a seat"); + wlr_input_method_v2_send_unavailable(input_method); + return; + } - wlr_log(WLR_INFO,"input_method_new"); - - relay->input_method = input_method; - wl_signal_add(&relay->input_method->events.commit, - &relay->input_method_commit); - relay->input_method_commit.notify = handle_im_commit; - wl_signal_add(&relay->input_method->events.new_popup_surface, - &relay->input_method_new_popup_surface); - relay->input_method_new_popup_surface.notify = handle_im_new_popup_surface; - wl_signal_add(&relay->input_method->events.grab_keyboard, - &relay->input_method_grab_keyboard); - relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard; - wl_signal_add(&relay->input_method->events.destroy, - &relay->input_method_destroy); - relay->input_method_destroy.notify = handle_im_destroy; + wlr_log(WLR_INFO, "input_method_new"); - wlr_input_method_v2_send_activate(relay->input_method); + relay->input_method = input_method; + wl_signal_add(&relay->input_method->events.commit, + &relay->input_method_commit); + relay->input_method_commit.notify = handle_im_commit; + wl_signal_add(&relay->input_method->events.new_popup_surface, + &relay->input_method_new_popup_surface); + relay->input_method_new_popup_surface.notify = handle_im_new_popup_surface; + wl_signal_add(&relay->input_method->events.grab_keyboard, + &relay->input_method_grab_keyboard); + relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard; + wl_signal_add(&relay->input_method->events.destroy, + &relay->input_method_destroy); + relay->input_method_destroy.notify = handle_im_destroy; - text_input = relay_get_focusable_text_input(relay); - if (text_input) { - wlr_text_input_v3_send_enter(text_input->input, - text_input->pending_focused_surface); - text_input_set_pending_focused_surface(text_input, NULL); - } + wlr_input_method_v2_send_activate(relay->input_method); + + text_input = relay_get_focusable_text_input(relay); + if (text_input) { + wlr_text_input_v3_send_enter(text_input->input, + text_input->pending_focused_surface); + text_input_set_pending_focused_surface(text_input, NULL); + } } void dwl_input_method_relay_init(struct dwl_input_method_relay *relay) { - wl_list_init(&relay->text_inputs); + wl_list_init(&relay->text_inputs); - relay->popup=NULL; + relay->popup = NULL; - relay->text_input_new.notify = relay_handle_text_input_new; - wl_signal_add(&text_input_manager->events.text_input, - &relay->text_input_new); + relay->text_input_new.notify = relay_handle_text_input_new; + wl_signal_add(&text_input_manager->events.text_input, &relay->text_input_new); - relay->input_method_new.notify = relay_handle_input_method_new; - wl_signal_add(&input_method_manager->events.input_method, - &relay->input_method_new); + relay->input_method_new.notify = relay_handle_input_method_new; + wl_signal_add(&input_method_manager->events.input_method, + &relay->input_method_new); } void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay, - struct wlr_surface *surface) { - struct dwl_text_input *text_input; - wl_list_for_each(text_input, &relay->text_inputs, link) { - if (text_input->pending_focused_surface) { - assert(text_input->input->focused_surface == NULL); - if (surface != text_input->pending_focused_surface) { - text_input_set_pending_focused_surface(text_input, NULL); - } - } else if (text_input->input->focused_surface) { - assert(text_input->pending_focused_surface == NULL); - if (surface != text_input->input->focused_surface) { - relay_disable_text_input(relay, text_input); - wlr_text_input_v3_send_leave(text_input->input); - wlr_log(WLR_INFO, "wlr_text_input_send_leave"); - } else { - wlr_log(WLR_INFO, "IM relay set_focus already focused"); - continue; - } - } + struct wlr_surface *surface) { + struct dwl_text_input *text_input; + wl_list_for_each(text_input, &relay->text_inputs, link) { + if (text_input->pending_focused_surface) { + assert(text_input->input->focused_surface == NULL); + if (surface != text_input->pending_focused_surface) { + text_input_set_pending_focused_surface(text_input, NULL); + } + } else if (text_input->input->focused_surface) { + assert(text_input->pending_focused_surface == NULL); + if (surface != text_input->input->focused_surface) { + relay_disable_text_input(relay, text_input); + wlr_text_input_v3_send_leave(text_input->input); + wlr_log(WLR_INFO, "wlr_text_input_send_leave"); + } else { + wlr_log(WLR_INFO, "IM relay set_focus already focused"); + continue; + } + } - if (surface - && wl_resource_get_client(text_input->input->resource) - == wl_resource_get_client(surface->resource)) { - if (relay->input_method) { - wlr_text_input_v3_send_enter(text_input->input, surface); - wlr_log(WLR_INFO, "wlr_text_input_send_enter"); - if (relay->popup) input_popup_update(relay->popup); - } else { - text_input_set_pending_focused_surface(text_input, surface); - } - } - } + if (surface && wl_resource_get_client(text_input->input->resource) == + wl_resource_get_client(surface->resource)) { + if (relay->input_method) { + wlr_text_input_v3_send_enter(text_input->input, surface); + wlr_log(WLR_INFO, "wlr_text_input_send_enter"); + if (relay->popup) + input_popup_update(relay->popup); + } else { + text_input_set_pending_focused_surface(text_input, surface); + } + } + } } #endif diff --git a/client.h b/client.h index 800b867..ca5fbd6 100644 --- a/client.h +++ b/client.h @@ -6,403 +6,366 @@ */ /* Leave these functions first; they're used in the others */ -static inline int -client_is_x11(Client *c) -{ +static inline int client_is_x11(Client *c) { #ifdef XWAYLAND - return c->type == X11; + return c->type == X11; #endif - return 0; + return 0; } -static inline struct wlr_surface * -client_surface(Client *c) -{ +static inline struct wlr_surface *client_surface(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->surface; + if (client_is_x11(c)) + return c->surface.xwayland->surface; #endif - return c->surface.xdg->surface; + return c->surface.xdg->surface; } -static inline int -toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl) -{ - struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface; - struct wlr_surface *root_surface; - struct wlr_layer_surface_v1 *layer_surface; - Client *c = NULL; - LayerSurface *l = NULL; - int type = -1; +static inline int toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, + LayerSurface **pl) { + struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface; + struct wlr_surface *root_surface; + struct wlr_layer_surface_v1 *layer_surface; + Client *c = NULL; + LayerSurface *l = NULL; + int type = -1; #ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface; + struct wlr_xwayland_surface *xsurface; #endif - if (!s) - return -1; - root_surface = wlr_surface_get_root_surface(s); + if (!s) + return -1; + root_surface = wlr_surface_get_root_surface(s); #ifdef XWAYLAND - if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) { - c = xsurface->data; - type = c->type; - goto end; - } + if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) { + c = xsurface->data; + type = c->type; + goto end; + } #endif - if ((layer_surface = wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) { - l = layer_surface->data; - type = LayerShell; - goto end; - } + if ((layer_surface = + wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) { + l = layer_surface->data; + type = LayerShell; + goto end; + } - xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface); - while (xdg_surface) { - tmp_xdg_surface = NULL; - switch (xdg_surface->role) { - case WLR_XDG_SURFACE_ROLE_POPUP: - if (!xdg_surface->popup || !xdg_surface->popup->parent) - return -1; + xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface); + while (xdg_surface) { + tmp_xdg_surface = NULL; + switch (xdg_surface->role) { + case WLR_XDG_SURFACE_ROLE_POPUP: + if (!xdg_surface->popup || !xdg_surface->popup->parent) + return -1; - tmp_xdg_surface = wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent); + tmp_xdg_surface = + wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent); - if (!tmp_xdg_surface) - return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl); + if (!tmp_xdg_surface) + return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl); - xdg_surface = tmp_xdg_surface; - break; - case WLR_XDG_SURFACE_ROLE_TOPLEVEL: - c = xdg_surface->data; - type = c->type; - goto end; - case WLR_XDG_SURFACE_ROLE_NONE: - return -1; - } - } + xdg_surface = tmp_xdg_surface; + break; + case WLR_XDG_SURFACE_ROLE_TOPLEVEL: + c = xdg_surface->data; + type = c->type; + goto end; + case WLR_XDG_SURFACE_ROLE_NONE: + return -1; + } + } end: - if (pl) - *pl = l; - if (pc) - *pc = c; - return type; + if (pl) + *pl = l; + if (pc) + *pc = c; + return type; } /* The others */ -static inline void -client_activate_surface(struct wlr_surface *s, int activated) -{ - struct wlr_xdg_toplevel *toplevel; +static inline void client_activate_surface(struct wlr_surface *s, + int activated) { + struct wlr_xdg_toplevel *toplevel; #ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface; - if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) { - wlr_xwayland_surface_activate(xsurface, activated); - return; - } + struct wlr_xwayland_surface *xsurface; + if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) { + wlr_xwayland_surface_activate(xsurface, activated); + return; + } #endif - if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s))) - wlr_xdg_toplevel_set_activated(toplevel, activated); + if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s))) + wlr_xdg_toplevel_set_activated(toplevel, activated); } -static inline uint32_t -client_set_bounds(Client *c, int32_t width, int32_t height) -{ +static inline uint32_t client_set_bounds(Client *c, int32_t width, + int32_t height) { #ifdef XWAYLAND - if (client_is_x11(c)) - return 0; + if (client_is_x11(c)) + return 0; #endif - if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >= - XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && width >= 0 && height >= 0 - && (c->bounds.width != width || c->bounds.height != height)) { - c->bounds.width = width; - c->bounds.height = height; - return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height); - } - return 0; + if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >= + XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && + width >= 0 && height >= 0 && + (c->bounds.width != width || c->bounds.height != height)) { + c->bounds.width = width; + c->bounds.height = height; + return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height); + } + return 0; } -static inline const char * -client_get_appid(Client *c) -{ +static inline const char *client_get_appid(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->class; + if (client_is_x11(c)) + return c->surface.xwayland->class; #endif - return c->surface.xdg->toplevel->app_id; + return c->surface.xdg->toplevel->app_id; } -static inline void -client_get_clip(Client *c, struct wlr_box *clip) -{ - struct wlr_box xdg_geom = {0}; - *clip = (struct wlr_box){ - .x = 0, - .y = 0, - .width = c->geom.width - c->bw, - .height = c->geom.height - c->bw, - }; +static inline void client_get_clip(Client *c, struct wlr_box *clip) { + struct wlr_box xdg_geom = {0}; + *clip = (struct wlr_box){ + .x = 0, + .y = 0, + .width = c->geom.width - c->bw, + .height = c->geom.height - c->bw, + }; #ifdef XWAYLAND - if (client_is_x11(c)) - return; + if (client_is_x11(c)) + return; #endif - wlr_xdg_surface_get_geometry(c->surface.xdg, &xdg_geom); - clip->x = xdg_geom.x; - clip->y = xdg_geom.y; + wlr_xdg_surface_get_geometry(c->surface.xdg, &xdg_geom); + clip->x = xdg_geom.x; + clip->y = xdg_geom.y; } -static inline void -client_get_geometry(Client *c, struct wlr_box *geom) -{ +static inline void client_get_geometry(Client *c, struct wlr_box *geom) { #ifdef XWAYLAND - if (client_is_x11(c)) { - geom->x = c->surface.xwayland->x; - geom->y = c->surface.xwayland->y; - geom->width = c->surface.xwayland->width; - geom->height = c->surface.xwayland->height; - return; - } + if (client_is_x11(c)) { + geom->x = c->surface.xwayland->x; + geom->y = c->surface.xwayland->y; + geom->width = c->surface.xwayland->width; + geom->height = c->surface.xwayland->height; + return; + } #endif - wlr_xdg_surface_get_geometry(c->surface.xdg, geom); + wlr_xdg_surface_get_geometry(c->surface.xdg, geom); } -static inline Client * -client_get_parent(Client *c) -{ - Client *p = NULL; +static inline Client *client_get_parent(Client *c) { + Client *p = NULL; #ifdef XWAYLAND - if (client_is_x11(c)) { - if (c->surface.xwayland->parent) - toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); - return p; - } + if (client_is_x11(c)) { + if (c->surface.xwayland->parent) + toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); + return p; + } #endif - if (c->surface.xdg->toplevel->parent) - toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL); - return p; + if (c->surface.xdg->toplevel->parent) + toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, + &p, NULL); + return p; } -static inline int -client_has_children(Client *c) -{ +static inline int client_has_children(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return !wl_list_empty(&c->surface.xwayland->children); + if (client_is_x11(c)) + return !wl_list_empty(&c->surface.xwayland->children); #endif - /* surface.xdg->link is never empty because it always contains at least the - * surface itself. */ - return wl_list_length(&c->surface.xdg->link) > 1; + /* surface.xdg->link is never empty because it always contains at least the + * surface itself. */ + return wl_list_length(&c->surface.xdg->link) > 1; } -static inline const char * -client_get_title(Client *c) -{ +static inline const char *client_get_title(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->title; + if (client_is_x11(c)) + return c->surface.xwayland->title; #endif - return c->surface.xdg->toplevel->title; + return c->surface.xdg->toplevel->title; } -static inline int -client_is_float_type(Client *c) -{ - struct wlr_xdg_toplevel *toplevel; - struct wlr_xdg_toplevel_state state; +static inline int client_is_float_type(Client *c) { + struct wlr_xdg_toplevel *toplevel; + struct wlr_xdg_toplevel_state state; #ifdef XWAYLAND - if (client_is_x11(c)) { - struct wlr_xwayland_surface *surface = c->surface.xwayland; - xcb_size_hints_t *size_hints = surface->size_hints; - size_t i; - if (surface->modal) - return 1; + if (client_is_x11(c)) { + struct wlr_xwayland_surface *surface = c->surface.xwayland; + xcb_size_hints_t *size_hints = surface->size_hints; + size_t i; + if (surface->modal) + return 1; - for (i = 0; i < surface->window_type_len; i++) - if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] - || surface->window_type[i] == netatom[NetWMWindowTypeSplash] - || surface->window_type[i] == netatom[NetWMWindowTypeToolbar] - || surface->window_type[i] == netatom[NetWMWindowTypeUtility]) - return 1; + for (i = 0; i < surface->window_type_len; i++) + if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] || + surface->window_type[i] == netatom[NetWMWindowTypeSplash] || + surface->window_type[i] == netatom[NetWMWindowTypeToolbar] || + surface->window_type[i] == netatom[NetWMWindowTypeUtility]) + return 1; - return size_hints && size_hints->min_width > 0 && size_hints->min_height > 0 - && (size_hints->max_width == size_hints->min_width - || size_hints->max_height == size_hints->min_height); - } + return size_hints && size_hints->min_width > 0 && + size_hints->min_height > 0 && + (size_hints->max_width == size_hints->min_width || + size_hints->max_height == size_hints->min_height); + } #endif - toplevel = c->surface.xdg->toplevel; - state = toplevel->current; - return toplevel->parent || (state.min_width != 0 && state.min_height != 0 - && (state.min_width == state.max_width - || state.min_height == state.max_height)); + toplevel = c->surface.xdg->toplevel; + state = toplevel->current; + return toplevel->parent || (state.min_width != 0 && state.min_height != 0 && + (state.min_width == state.max_width || + state.min_height == state.max_height)); } -static inline int -client_is_rendered_on_mon(Client *c, Monitor *m) -{ - /* This is needed for when you don't want to check formal assignment, - * but rather actual displaying of the pixels. - * Usually VISIBLEON suffices and is also faster. */ - struct wlr_surface_output *s; - int unused_lx, unused_ly; - if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly)) - return 0; - wl_list_for_each(s, &client_surface(c)->current_outputs, link) - if (s->output == m->wlr_output) - return 1; - return 0; +static inline int client_is_rendered_on_mon(Client *c, Monitor *m) { + /* This is needed for when you don't want to check formal assignment, + * but rather actual displaying of the pixels. + * Usually VISIBLEON suffices and is also faster. */ + struct wlr_surface_output *s; + int unused_lx, unused_ly; + if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly)) + return 0; + wl_list_for_each(s, &client_surface(c)->current_outputs, + link) if (s->output == m->wlr_output) return 1; + return 0; } -static inline int -client_is_stopped(Client *c) -{ - int pid; - siginfo_t in = {0}; +static inline int client_is_stopped(Client *c) { + int pid; + siginfo_t in = {0}; #ifdef XWAYLAND - if (client_is_x11(c)) - return 0; + if (client_is_x11(c)) + return 0; #endif - wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); - if (waitid(P_PID, pid, &in, WNOHANG|WCONTINUED|WSTOPPED|WNOWAIT) < 0) { - /* This process is not our child process, while is very unluckely that - * it is stopped, in order to do not skip frames assume that it is. */ - if (errno == ECHILD) - return 1; - } else if (in.si_pid) { - if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED) - return 1; - if (in.si_code == CLD_CONTINUED) - return 0; - } + wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); + if (waitid(P_PID, pid, &in, WNOHANG | WCONTINUED | WSTOPPED | WNOWAIT) < 0) { + /* This process is not our child process, while is very unluckely that + * it is stopped, in order to do not skip frames assume that it is. */ + if (errno == ECHILD) + return 1; + } else if (in.si_pid) { + if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED) + return 1; + if (in.si_code == CLD_CONTINUED) + return 0; + } - return 0; + return 0; } -static inline int -client_is_unmanaged(Client *c) -{ +static inline int client_is_unmanaged(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->override_redirect; + if (client_is_x11(c)) + return c->surface.xwayland->override_redirect; #endif - return 0; + return 0; } -static inline void -client_notify_enter(struct wlr_surface *s, struct wlr_keyboard *kb) -{ - if (kb) - wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, - kb->num_keycodes, &kb->modifiers); - else - wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); +static inline void client_notify_enter(struct wlr_surface *s, + struct wlr_keyboard *kb) { + if (kb) + wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, kb->num_keycodes, + &kb->modifiers); + else + wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); } -static inline void -client_restack_surface(Client *c) -{ +static inline void client_restack_surface(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - wlr_xwayland_surface_restack(c->surface.xwayland, NULL, - XCB_STACK_MODE_ABOVE); + if (client_is_x11(c)) + wlr_xwayland_surface_restack(c->surface.xwayland, NULL, + XCB_STACK_MODE_ABOVE); #endif - return; + return; } -static inline void -client_send_close(Client *c) -{ +static inline void client_send_close(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_close(c->surface.xwayland); - return; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_close(c->surface.xwayland); + return; + } #endif - wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel); + wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel); } -static inline void -client_set_border_color(Client *c, const float color[static 4]) -{ - int i; - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(c->border[i], color); +static inline void client_set_border_color(Client *c, + const float color[static 4]) { + int i; + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(c->border[i], color); } -static inline void -client_set_fullscreen(Client *c, int fullscreen) -{ +static inline void client_set_fullscreen(Client *c, int fullscreen) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen); - return; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen); + return; + } #endif - wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); + wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); } -static inline uint32_t -client_set_size(Client *c, uint32_t width, uint32_t height) -{ +static inline uint32_t client_set_size(Client *c, uint32_t width, + uint32_t height) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_configure(c->surface.xwayland, - c->geom.x, c->geom.y, width, height); - return 0; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x, c->geom.y, + width, height); + return 0; + } #endif - if ((int32_t)width == c->surface.xdg->toplevel->current.width - && (int32_t)height == c->surface.xdg->toplevel->current.height) - return 0; - return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width, (int32_t)height); + if ((int32_t)width == c->surface.xdg->toplevel->current.width && + (int32_t)height == c->surface.xdg->toplevel->current.height) + return 0; + return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width, + (int32_t)height); } -static inline void -client_set_tiled(Client *c, uint32_t edges) -{ +static inline void client_set_tiled(Client *c, uint32_t edges) { #ifdef XWAYLAND - if (client_is_x11(c)) - return; + if (client_is_x11(c)) + return; #endif - if (wl_resource_get_version(c->surface.xdg->toplevel->resource) - >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { - wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges); - } else { - wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel, edges != WLR_EDGE_NONE); - } + if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >= + XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { + wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges); + } else { + wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel, + edges != WLR_EDGE_NONE); + } } -static inline void -client_set_suspended(Client *c, int suspended) -{ +static inline void client_set_suspended(Client *c, int suspended) { #ifdef XWAYLAND - if (client_is_x11(c)) - return; + if (client_is_x11(c)) + return; #endif - wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended); + wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended); } -static inline int -client_wants_focus(Client *c) -{ +static inline int client_wants_focus(Client *c) { #ifdef XWAYLAND - return client_is_unmanaged(c) - && wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) - && wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; + return client_is_unmanaged(c) && + wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) && + wlr_xwayland_icccm_input_model(c->surface.xwayland) != + WLR_ICCCM_INPUT_MODEL_NONE; #endif - return 0; + return 0; } -static inline int -client_wants_fullscreen(Client *c) -{ +static inline int client_wants_fullscreen(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->fullscreen; + if (client_is_x11(c)) + return c->surface.xwayland->fullscreen; #endif - return c->surface.xdg->toplevel->requested.fullscreen; + return c->surface.xdg->toplevel->requested.fullscreen; } diff --git a/maomao.c b/maomao.c index d460e59..121f4fe 100644 --- a/maomao.c +++ b/maomao.c @@ -1,11 +1,9 @@ /* * See LICENSE file for copyright and license details. */ +#include #include #include -#include -#include -#include #include #include #include @@ -30,6 +28,7 @@ #include #include #include +#include // #include #include #include @@ -86,7 +85,7 @@ #define TAGMASK ((1 << LENGTH(tags)) - 1) #define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L))) #define ISFULLSCREEN(A) \ - ((A)->isfullscreen || (A)->ismaxmizescreen || \ + ((A)->isfullscreen || (A)->ismaxmizescreen || \ (A)->overview_ismaxmizescreenbak || (A)->overview_isfullscreenbak) #define LISTEN_STATIC(E, H) \ do { \ @@ -98,7 +97,7 @@ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11 }; /* client types */ -enum { AxisUp,AxisDown, AxisLeft, AxisRight}; // 滚轮滚动的方向 +enum { AxisUp, AxisDown, AxisLeft, AxisRight }; // 滚轮滚动的方向 enum { LyrBg, LyrBottom, @@ -309,7 +308,7 @@ struct Monitor { int gappoh; /* horizontal outer gaps */ int gappov; /* vertical outer gaps */ Pertag *pertag; - Client *sel,*prevsel; + Client *sel, *prevsel; int isoverview; int is_in_hotarea; int gamma_lut_changed; @@ -367,16 +366,17 @@ static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); static void autostartexec(void); // 自启动命令执行 -static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 +static void axisnotify(struct wl_listener *listener, + void *data); // 滚轮事件处理 static void buttonpress(struct wl_listener *listener, void *data); // 鼠标按键事件处理 static void checkidleinhibitor(struct wlr_surface *exclude); static void cleanup(void); // 退出清理 static void cleanupkeyboard(struct wl_listener *listener, - void *data); // 退出清理 + void *data); // 退出清理 static void cleanupmon(struct wl_listener *listener, void *data); // 退出清理 -static void closemon(Monitor *m); // 退出清理 -static void toggle_hotarea(int x_root, int y_root); // 触发热区 +static void closemon(Monitor *m); // 退出清理 +static void toggle_hotarea(int x_root, int y_root); // 触发热区 static void commitlayersurfacenotify(struct wl_listener *listener, void *data); static void commitnotify(struct wl_listener *listener, void *data); static void createdecoration(struct wl_listener *listener, void *data); @@ -444,7 +444,7 @@ static void maplayersurfacenotify(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); static void minimizenotify(struct wl_listener *listener, void *data); -static void monocle(Monitor *m,unsigned int gappo, unsigned int gappi); +static void monocle(Monitor *m, unsigned int gappo, unsigned int gappi); static void motionabsolute(struct wl_listener *listener, void *data); static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, double sy, double sx_unaccel, @@ -528,7 +528,7 @@ static struct wlr_box setclient_coordinate_center(struct wlr_box geom); static unsigned int get_tags_first_tag(unsigned int tags); void client_commit(Client *c); -void apply_border(Client *c, struct wlr_box clip_box,int offset); +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); @@ -635,8 +635,8 @@ static Atom netatom[NetLast]; #endif /* configuration, allows nested code to access above variables */ -#include "preset_config.h" #include "parse_config.h" +#include "preset_config.h" /* attempt to encapsulate suck into one file */ #include "client.h" @@ -652,9 +652,9 @@ struct NumTags { }; struct Pertag { - unsigned int curtag, prevtag; /* current and previous tag */ - int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ - float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ + unsigned int curtag, prevtag; /* current and previous tag */ + int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ const Layout *ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */ }; @@ -748,8 +748,8 @@ bool client_animation_next_tick(Client *c) { c->animation.running = false; - if(c->animation.tagining) { - c->animation.tagining = false; + if (c->animation.tagining) { + c->animation.tagining = false; } if (c->animation.tagouting) { @@ -762,9 +762,9 @@ bool client_animation_next_tick(Client *c) { xytonode(cursor->x, cursor->y, NULL, &pointer_c, NULL, &sx, &sy); - surface = pointer_c && pointer_c == c ? client_surface(pointer_c) : NULL; - if(surface && pointer_c == selmon->sel) { - wlr_seat_pointer_notify_enter(seat, surface, sx, sy); + surface = pointer_c && pointer_c == c ? client_surface(pointer_c) : NULL; + if (surface && pointer_c == selmon->sel) { + wlr_seat_pointer_notify_enter(seat, surface, sx, sy); } return false; @@ -784,53 +784,50 @@ void client_actual_size(Client *c, uint32_t *width, uint32_t *height) { : c->current.height; } -void apply_border(Client *c, struct wlr_box clip_box, int offset) -{ +void apply_border(Client *c, struct wlr_box clip_box, int offset) { wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); wlr_scene_rect_set_size(c->border[0], clip_box.width, c->bw); wlr_scene_rect_set_size(c->border[1], clip_box.width, c->bw); - if (c->animation.tagining || c->animation.tagouted || c->animation.tagouting) - { - if (c->animation.current.x < c->mon->m.x) - { + if (c->animation.tagining || c->animation.tagouted || + c->animation.tagouting) { + if (c->animation.current.x < c->mon->m.x) { wlr_scene_rect_set_size(c->border[2], 0, 0); wlr_scene_rect_set_size(c->border[3], c->bw, clip_box.height - 2 * c->bw); wlr_scene_node_set_position(&c->border[0]->node, offset, 0); wlr_scene_node_set_position(&c->border[2]->node, 0 + offset, c->bw); - wlr_scene_node_set_position(&c->border[1]->node, offset, clip_box.height - c->bw); - wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw + offset, - c->bw); - } - else if (c->animation.current.x + c->geom.width > c->mon->m.x + c->mon->m.width) - { + wlr_scene_node_set_position(&c->border[1]->node, offset, + clip_box.height - c->bw); + wlr_scene_node_set_position(&c->border[3]->node, + clip_box.width - c->bw + offset, c->bw); + } else if (c->animation.current.x + c->geom.width > + c->mon->m.x + c->mon->m.width) { wlr_scene_rect_set_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); wlr_scene_rect_set_size(c->border[3], 0, 0); wlr_scene_node_set_position(&c->border[0]->node, 0, 0); wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); - wlr_scene_node_set_position(&c->border[1]->node, 0, clip_box.height - c->bw); + wlr_scene_node_set_position(&c->border[1]->node, 0, + clip_box.height - c->bw); wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, c->bw); - } - else - { + } else { wlr_scene_rect_set_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); wlr_scene_rect_set_size(c->border[3], c->bw, clip_box.height - 2 * c->bw); wlr_scene_node_set_position(&c->border[0]->node, 0, 0); wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); - wlr_scene_node_set_position(&c->border[1]->node, 0, clip_box.height - c->bw); + wlr_scene_node_set_position(&c->border[1]->node, 0, + clip_box.height - c->bw); wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, c->bw); } - } - else - { + } else { wlr_scene_rect_set_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); wlr_scene_rect_set_size(c->border[3], c->bw, clip_box.height - 2 * c->bw); wlr_scene_node_set_position(&c->border[0]->node, 0, 0); wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); - wlr_scene_node_set_position(&c->border[1]->node, 0, clip_box.height - c->bw); + wlr_scene_node_set_position(&c->border[1]->node, 0, + clip_box.height - c->bw); wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, c->bw); } @@ -856,18 +853,22 @@ void client_apply_clip(Client *c) { } // make tagout tagin animations not visible in other monitors - if(c->animation.tagouting || c->animation.tagining || c->animation.tagouted) { - if (c->animation.current.x <= c->mon->m.x) { - offset = c->mon->m.x - c->animation.current.x; - clip_box.x = clip_box.x + offset; - clip_box.width = clip_box.width - offset; - } else if(c->animation.current.x + c->geom.width >= c->mon->m.x + c->mon->m.width) { - clip_box.width = clip_box.width - (c->animation.current.x + c->animation.current.width - c->mon->m.x - c->mon->m.width); - } + if (c->animation.tagouting || c->animation.tagining || + c->animation.tagouted) { + if (c->animation.current.x <= c->mon->m.x) { + offset = c->mon->m.x - c->animation.current.x; + clip_box.x = clip_box.x + offset; + clip_box.width = clip_box.width - offset; + } else if (c->animation.current.x + c->geom.width >= + c->mon->m.x + c->mon->m.width) { + clip_box.width = clip_box.width - + (c->animation.current.x + c->animation.current.width - + c->mon->m.x - c->mon->m.width); + } } wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); - apply_border(c, clip_box,offset); + apply_border(c, clip_box, offset); } bool client_draw_frame(Client *c) { @@ -882,7 +883,7 @@ bool client_draw_frame(Client *c) { } } else { wlr_scene_node_set_position(&c->scene->node, c->pending.x, c->pending.y); - apply_border(c, c->pending,0); + apply_border(c, c->pending, 0); } client_apply_clip(c); @@ -1122,10 +1123,11 @@ applyrulesgeom(Client *c) { title = broken; for (ji = 0; ji < config.window_rules_count; ji++) { - if(config.window_rules_count < 1) + if (config.window_rules_count < 1) break; r = &config.window_rules[ji]; - if ( (r->title && strstr(title, r->title)) || (r->id && strstr(appid, r->id))) { + if ((r->title && strstr(title, r->title)) || + (r->id && strstr(appid, r->id))) { c->geom.width = r->width > 0 ? r->width : c->geom.width; c->geom.height = r->height > 0 ? r->height : c->geom.height; // 重新计算居中的坐标 @@ -1152,16 +1154,20 @@ applyrules(Client *c) { title = broken; for (ji = 0; ji < config.window_rules_count; ji++) { - if(config.window_rules_count < 1) + if (config.window_rules_count < 1) break; r = &config.window_rules[ji]; - if ( (r->title && strstr(title, r->title)) || (r->id && strstr(appid, r->id))) { + if ((r->title && strstr(title, r->title)) || + (r->id && strstr(appid, r->id))) { c->isfloating = r->isfloating > 0 ? r->isfloating : c->isfloating; - c->animation_type = r->animation_type == NULL ? c->animation_type : r->animation_type; - c->scroller_proportion = r->scroller_proportion > 0 ? r->scroller_proportion : scroller_default_proportion; + c->animation_type = + r->animation_type == NULL ? c->animation_type : r->animation_type; + c->scroller_proportion = r->scroller_proportion > 0 + ? r->scroller_proportion + : scroller_default_proportion; c->isnoborder = r->isnoborder > 0 ? r->isnoborder : c->isnoborder; - newtags = r->tags > 0 ? r->tags|newtags : newtags; + newtags = r->tags > 0 ? r->tags | newtags : newtags; i = 0; wl_list_for_each(m, &mons, link) if (r->monitor == i++) mon = m; @@ -1206,16 +1212,16 @@ arrange(Monitor *m, bool want_animation) { if (!m->wlr_output->enabled) return; - + wl_list_for_each(c, &clients, link) { if (c->iskilling) continue; if (c->mon == m && c->isglobal) { c->tags = m->tagset[m->seltags]; - if(selmon->sel == NULL) - focusclient(c,0); - } + if (selmon->sel == NULL) + focusclient(c, 0); + } if (c->mon == m) { if (VISIBLEON(c, m)) { @@ -1225,10 +1231,13 @@ arrange(Monitor *m, bool want_animation) { m->pertag->prevtag != 0 && m->pertag->curtag != 0) { c->animation.tagining = true; if (m->pertag->curtag > m->pertag->prevtag) { - c->animainit_geom.x = c->animation.running? c->animation.current.x: - c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); + c->animainit_geom.x = + c->animation.running + ? c->animation.current.x + : c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); } else { - c->animainit_geom.x = c->animation.running? c->animation.current.x : m->m.x - c->geom.width; + c->animainit_geom.x = c->animation.running ? c->animation.current.x + : m->m.x - c->geom.width; } } @@ -1249,7 +1258,8 @@ arrange(Monitor *m, bool want_animation) { resize(c, c->geom, 0); } else { c->pending = c->geom; - c->pending.x = c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); + c->pending.x = + c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); resize(c, c->geom, 0); } } else { @@ -1326,7 +1336,7 @@ Client *direction_select(const Arg *arg) { } // 动态分配内存 - tempClients = malloc((last + 1) * sizeof(Client*)); + tempClients = malloc((last + 1) * sizeof(Client *)); if (!tempClients) { // 处理内存分配失败的情况 return NULL; @@ -1364,7 +1374,8 @@ Client *direction_select(const Arg *arg) { if (tempClients[_i]->geom.y < sel_y) { int dis_x = tempClients[_i]->geom.x - sel_x; int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 if (tmp_distance < distance) { distance = tmp_distance; tempFocusClients = tempClients[_i]; @@ -1390,7 +1401,8 @@ Client *direction_select(const Arg *arg) { if (tempClients[_i]->geom.y > sel_y) { int dis_x = tempClients[_i]->geom.x - sel_x; int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 if (tmp_distance < distance) { distance = tmp_distance; tempFocusClients = tempClients[_i]; @@ -1416,7 +1428,8 @@ Client *direction_select(const Arg *arg) { if (tempClients[_i]->geom.x < sel_x) { int dis_x = tempClients[_i]->geom.x - sel_x; int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 if (tmp_distance < distance) { distance = tmp_distance; tempFocusClients = tempClients[_i]; @@ -1442,7 +1455,8 @@ Client *direction_select(const Arg *arg) { if (tempClients[_i]->geom.x > sel_x) { int dis_x = tempClients[_i]->geom.x - sel_x; int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = dis_x * dis_x + dis_y * dis_y; // 计算距离 + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 if (tmp_distance < distance) { distance = tmp_distance; tempFocusClients = tempClients[_i]; @@ -1554,7 +1568,7 @@ axisnotify(struct wl_listener *listener, void *data) { adir = event->delta > 0 ? AxisRight : AxisLeft; for (ji = 0; ji < config.axis_bindings_count; ji++) { - if(config.axis_bindings_count < 1) + if (config.axis_bindings_count < 1) break; a = &config.axis_bindings[ji]; if (CLEANMASK(mods) == CLEANMASK(a->mod) && // 按键一致 @@ -1604,12 +1618,12 @@ buttonpress(struct wl_listener *listener, void *data) { focusclient(c, 1); if (!surface) - wlr_seat_pointer_notify_clear_focus(seat); + wlr_seat_pointer_notify_clear_focus(seat); keyboard = wlr_seat_get_keyboard(seat); mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; for (ji = 0; ji < config.mouse_bindings_count; ji++) { - if(config.mouse_bindings_count < 1) + if (config.mouse_bindings_count < 1) break; b = &config.mouse_bindings[ji]; if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button && @@ -1806,7 +1820,7 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data) { void client_set_pending_state(Client *c) { // 判断是否需要动画 - if(c->isglobal && c->isfloating){ + if (c->isglobal && c->isfloating) { c->animation.should_animate = false; } else if (animations && c->animation.tagining) { c->animation.should_animate = true; @@ -1847,15 +1861,14 @@ void client_commit(Client *c) { wlr_output_schedule_frame(c->mon->wlr_output); } -void -commitnotify(struct wl_listener *listener, void *data) { +void commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); - if(!c || c->iskilling || c->animation.tagining || c->animation.tagining || c->animation.tagouted) + if (!c || c->iskilling || c->animation.tagining || c->animation.tagining || + c->animation.tagouted) return; // if don't do this, some client may resize uncompleted resize(c, c->geom, (c->isfloating && !c->isfullscreen)); - } void // 0.5 @@ -2007,7 +2020,7 @@ createmon(struct wl_listener *listener, void *data) { struct wlr_output *wlr_output = data; const ConfigMonitorRule *r; size_t i; - int ji,jk; + int ji, jk; Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m)); m->wlr_output = wlr_output; @@ -2032,7 +2045,7 @@ createmon(struct wl_listener *listener, void *data) { enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL; m->lt = &layouts[0]; - + for (ji = 0; ji < config.monitor_rules_count; ji++) { if (config.monitor_rules_count < 1) break; @@ -2045,7 +2058,7 @@ createmon(struct wl_listener *listener, void *data) { m->m.y = r->y; if (r->layout) { for (jk = 0; jk < LENGTH(layouts); jk++) { - if(strcmp(layouts[jk].name , r->layout) == 0) { + if (strcmp(layouts[jk].name, r->layout) == 0) { m->lt = &layouts[jk]; } } @@ -2090,19 +2103,17 @@ createmon(struct wl_listener *listener, void *data) { m->pertag->ltidxs[i] = m->lt; - if(i > 0 && strlen(config.tags[i-1].layout_name) > 0) { + if (i > 0 && strlen(config.tags[i - 1].layout_name) > 0) { for (jk = 0; jk < LENGTH(layouts); jk++) { - if(strcmp(layouts[jk].name , config.tags[i-1].layout_name) == 0) { + if (strcmp(layouts[jk].name, config.tags[i - 1].layout_name) == 0) { m->pertag->ltidxs[i] = &layouts[jk]; } - } + } } - } printstatus(); - /* The xdg-protocol specifies: * * If the fullscreened surface is not opaque, the compositor must make @@ -2546,11 +2557,11 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { title = focused ? client_get_title(focused) : ""; appid = focused ? client_get_appid(focused) : ""; - symbol = - monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; + symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; - zdwl_ipc_output_v2_send_layout(ipc_output->resource, - monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); + 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); @@ -2595,8 +2606,8 @@ void dwl_ipc_output_set_layout(struct wl_client *client, monitor = ipc_output->monitor; if (index >= LENGTH(layouts)) - index = 0; - + index = 0; + monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; arrange(monitor, false); printstatus(); @@ -2631,8 +2642,10 @@ void dwl_ipc_output_release(struct wl_client *client, } void focusclient(Client *c, int lift) { - struct wlr_surface *old_keyboard_focus_surface = seat->keyboard_state.focused_surface; - struct wlr_surface *old_pointer_focus_surface = seat->pointer_state.focused_surface; + struct wlr_surface *old_keyboard_focus_surface = + seat->keyboard_state.focused_surface; + struct wlr_surface *old_pointer_focus_surface = + seat->pointer_state.focused_surface; if (locked) return; @@ -2640,18 +2653,19 @@ void focusclient(Client *c, int lift) { if (c && c->iskilling) return; - if(c && c->animation.tagouting && !c->animation.tagouting) + if (c && c->animation.tagouting && !c->animation.tagouting) return; /* Raise client in stacking order if requested */ if (c && lift) wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 - if (c && client_surface(c) == old_keyboard_focus_surface && client_surface(c) == old_pointer_focus_surface) + if (c && client_surface(c) == old_keyboard_focus_surface && + client_surface(c) == old_pointer_focus_surface) return; else { - wlr_seat_pointer_notify_clear_focus(seat); - wlr_seat_keyboard_notify_clear_focus(seat); + wlr_seat_pointer_notify_clear_focus(seat); + wlr_seat_keyboard_notify_clear_focus(seat); } if (c && c->mon && c->mon != selmon) { @@ -2665,10 +2679,14 @@ void focusclient(Client *c, int lift) { if (selmon) { selmon->prevsel = selmon->sel; selmon->sel = c; - if (c && selmon->prevsel && selmon->prevsel->istiled && selmon->prevsel->tags == c->tags && c->istiled && !c->isfloating && !c->isfullscreen && strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name , "scroller") == 0) { - arrange(selmon,false); + if (c && selmon->prevsel && selmon->prevsel->istiled && + selmon->prevsel->tags == c->tags && c->istiled && !c->isfloating && + !c->isfullscreen && + strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") == 0) { + arrange(selmon, false); } else if (selmon->prevsel) { - selmon->prevsel =NULL; + selmon->prevsel = NULL; } } if (c && c->foreign_toplevel) @@ -2687,7 +2705,8 @@ void focusclient(Client *c, int lift) { } /* Deactivate old client if focus is changing */ - if (old_keyboard_focus_surface && (!c || client_surface(c) != old_keyboard_focus_surface)) { + if (old_keyboard_focus_surface && + (!c || client_surface(c) != old_keyboard_focus_surface)) { /* If an overlay is focused, don't focus or activate the client, * but only update its position in fstack to render its border with * focuscolor and focus it after the overlay is closed. */ @@ -2699,8 +2718,8 @@ void focusclient(Client *c, int lift) { return; } else if (w && w == exclusive_focus && client_wants_focus(w)) { return; - /* Don't deactivate old_keyboard_focus_surface client if the new one wants focus, as this causes - * issues with winecfg and probably other clients */ + /* Don't deactivate old_keyboard_focus_surface client if the new one wants + * focus, as this causes issues with winecfg and probably other clients */ } else if (w && !client_is_unmanaged(w) && (!c || !client_wants_focus(c))) { setborder_color(w); @@ -2796,7 +2815,7 @@ void // 0.6 fullscreennotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, fullscreen); - if(!c || c->iskilling) + if (!c || c->iskilling) return; setfullscreen(c, client_wants_fullscreen(c)); @@ -2905,8 +2924,8 @@ keybinding(uint32_t mods, xkb_keysym_t sym) { int handled = 0; const KeyBinding *k; int ji; - for (ji =0; ji < config.key_bindings_count; ji++) { - if(config.key_bindings_count < 1) + for (ji = 0; ji < config.key_bindings_count; ji++) { + if (config.key_bindings_count < 1) break; k = &config.key_bindings[ji]; if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->keysym && k->func) { @@ -2937,13 +2956,14 @@ keypress(struct wl_listener *listener, void *data) { wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); // ov tab mode detect moe key release - if (ov_tab_mode && !locked && event->state == WL_KEYBOARD_KEY_STATE_RELEASED && + if (ov_tab_mode && !locked && + event->state == WL_KEYBOARD_KEY_STATE_RELEASED && (keycode == 133 || keycode == 37 || keycode == 64 || keycode == 50 || keycode == 134 || keycode == 105 || keycode == 108 || keycode == 62) && selmon->sel) { - if(selmon->isoverview && selmon->sel) { - toggleoverview(&(Arg){.i=-1}); - } + if (selmon->isoverview && selmon->sel) { + toggleoverview(&(Arg){.i = -1}); + } } #ifdef IM @@ -3110,15 +3130,19 @@ mapnotify(struct wl_listener *listener, void *data) { c->scroller_proportion = scroller_default_proportion; c->is_open_animation = true; // nop - if (new_is_master && strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name , "scroller") != 0) + if (new_is_master && + strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") != 0) // tile at the top wl_list_insert(&clients, &c->link); // 新窗口是master,头部入栈 - else if (strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name , "scroller") == 0 && selmon->sel && selmon->sel->istiled) { + else if (strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") == 0 && + selmon->sel && selmon->sel->istiled) { selmon->sel->link.next->prev = &c->link; c->link.prev = &selmon->sel->link; c->link.next = selmon->sel->link.next; selmon->sel->link.next = &c->link; - }else + } else wl_list_insert(clients.prev, &c->link); // 尾部入栈 wl_list_insert(&fstack, &c->flink); @@ -3189,7 +3213,7 @@ maximizenotify(struct wl_listener *listener, void *data) { // togglemaxmizescreen(&(Arg){0}); Client *c = wl_container_of(listener, c, maximize); - if(!c || c->iskilling) + if (!c || c->iskilling) return; if (c->ismaxmizescreen || c->isfullscreen) @@ -3234,19 +3258,20 @@ minimizenotify(struct wl_listener *listener, void *data) { // togglemaxmizescreen(&(Arg){0}); Client *c = wl_container_of(listener, c, minimize); - if(!c || c->iskilling) + if (!c || c->iskilling) return; set_minized(c); } void // 17 -monocle(Monitor *m,unsigned int gappo, unsigned int gappi) { +monocle(Monitor *m, unsigned int gappo, unsigned int gappi) { Client *c; int n = 0; wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen || c->ismaxmizescreen || c->iskilling || c->animation.tagouting) + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen || + c->ismaxmizescreen || c->iskilling || c->animation.tagouting) continue; resize(c, m->w, 0); n++; @@ -3563,7 +3588,8 @@ printstatus(void) { printf("%s selmon %u\n", m->wlr_output->name, m == selmon); printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg); - printf("%s layout %s\n", m->wlr_output->name, m->pertag->ltidxs[m->pertag->curtag]->symbol); + printf("%s layout %s\n", m->wlr_output->name, + m->pertag->ltidxs[m->pertag->curtag]->symbol); dwl_ipc_output_printstatus(m); // 更新waybar上tag的状态 这里很关键 } fflush(stdout); @@ -3592,8 +3618,8 @@ void client_handle_opacity(Client *c) { return; double opacity = c->isfullscreen || c->ismaxmizescreen ? 1.0 - : c == selmon->sel ? 0.8 - : 0.5; + : c == selmon->sel ? 0.8 + : 0.5; wlr_scene_node_for_each_buffer(&c->scene_surface->node, scene_buffer_apply_opacity, &opacity); @@ -3789,8 +3815,10 @@ int is_special_animaiton_rule(Client *c) { } } - if (strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name , "scroller") == 0 && !c->isfloating) { - return DOWN; + if (strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") == 0 && + !c->isfloating) { + return DOWN; } else if (visible_client_number < 2 && !c->isfloating) { return DOWN; } else if (visible_client_number == 2 && !c->isfloating && !new_is_master) { @@ -3882,7 +3910,8 @@ void resize(Client *c, struct wlr_box geo, int interact) { // oldgeom = c->geom; bbox = interact ? &sgeom : &c->mon->w; - if(strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name , "scroller") == 0) { + if (strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name, + "scroller") == 0) { c->geom = geo; } else { // 这里会限制不允许窗口划出屏幕 client_set_bounds( @@ -4069,7 +4098,7 @@ void setmaxmizescreen(Client *c, int maxmizescreen) { // c->bw = fullscreen ? 0 : borderpx; // client_set_fullscreen(c, maxmizescreen); - wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile + wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile : c->isfloating ? LyrFloat : LyrTile]); @@ -4154,30 +4183,30 @@ void setgaps(int oh, int ov, int ih, int iv) { void // 17 setlayout(const Arg *arg) { int jk; - for (jk = 0; jk < LENGTH(layouts); jk++) { - if(strcmp(layouts[jk].name , arg->v) == 0) { - selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[jk]; + for (jk = 0; jk < LENGTH(layouts); jk++) { + if (strcmp(layouts[jk].name, arg->v) == 0) { + selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[jk]; - arrange(selmon, false); - printstatus(); - return; - } + arrange(selmon, false); + printstatus(); + return; } + } } void switch_layout(const Arg *arg) { int jk; - for (jk = 0; jk < LENGTH(layouts); jk++) { - if(strcmp(layouts[jk].name , selmon->pertag->ltidxs[selmon->pertag->curtag]->name) == 0) { - selmon->pertag->ltidxs[selmon->pertag->curtag] = jk == LENGTH(layouts) - 1? &layouts[0] : &layouts[jk+1]; - arrange(selmon, false); - printstatus(); - return; - } - } - - + for (jk = 0; jk < LENGTH(layouts); jk++) { + if (strcmp(layouts[jk].name, + selmon->pertag->ltidxs[selmon->pertag->curtag]->name) == 0) { + selmon->pertag->ltidxs[selmon->pertag->curtag] = + jk == LENGTH(layouts) - 1 ? &layouts[0] : &layouts[jk + 1]; + arrange(selmon, false); + printstatus(); + return; + } + } } /* arg > 1.0 will set mfact absolutely */ @@ -4186,7 +4215,8 @@ void // 17 setmfact(const Arg *arg) { float f; - if (!arg || !selmon || !selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange) + if (!arg || !selmon || + !selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange) return; f = arg->f < 1.0 ? arg->f + selmon->pertag->mfacts[selmon->pertag->curtag] : arg->f - 1.0; @@ -4306,142 +4336,146 @@ void handle_foreign_destroy(struct wl_listener *listener, void *data) { } } +void signalhandler(int signalnumber) { + void *array[64]; + size_t size; + char **strings; + size_t i; + char filename[1024]; -void signalhandler(int signalnumber) -{ - void *array[64]; - size_t size; - char **strings; - size_t i; - char filename[1024]; + // 获取当前用户家目录 + const char *homedir = getenv("HOME"); + if (!homedir) { + // 如果获取失败,则无法继续 + return; + } - // 获取当前用户家目录 - const char *homedir = getenv("HOME"); - if (!homedir) { - // 如果获取失败,则无法继续 - return; - } + // 构建日志文件路径 + snprintf(filename, sizeof(filename), "%s/.config/maomao/crash.log", homedir); - // 构建日志文件路径 - snprintf(filename, sizeof(filename), "%s/.config/maomao/crash.log", homedir); + // 打开日志文件 + FILE *fp = fopen(filename, "a"); + if (!fp) { + // 如果无法打开日志文件,则不处理 + return; + } - // 打开日志文件 - FILE *fp = fopen(filename, "a"); - if (!fp) { - // 如果无法打开日志文件,则不处理 - return; - } + // 获取堆栈跟踪 + size = backtrace(array, 64); + strings = backtrace_symbols(array, size); - // 获取堆栈跟踪 - size = backtrace(array, 64); - strings = backtrace_symbols(array, size); + // 写入错误信息和堆栈跟踪到文件 + fprintf(fp, "Received signal %d:\n", signalnumber); + for (i = 0; i < size; ++i) { + fprintf(fp, "%zu %s\n", i, strings[i]); + } - // 写入错误信息和堆栈跟踪到文件 - fprintf(fp, "Received signal %d:\n", signalnumber); - for (i = 0; i < size; ++i) { - fprintf(fp, "%zu %s\n", i, strings[i]); - } + // 关闭文件 + fclose(fp); - // 关闭文件 - fclose(fp); + // 释放分配的内存 + free(strings); - // 释放分配的内存 - free(strings); - - // 不调用 exit 以允许生成核心转储文件 + // 不调用 exit 以允许生成核心转储文件 } void free_config(void) { - // 释放内存 - int i; - for (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); + // 释放内存 + int i; + for (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 ( 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 (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 ( i = 0; i < config.key_bindings_count; i++) { - if (config.key_bindings[i].arg.v) { - free((void *)config.key_bindings[i].arg.v); - config.key_bindings[i].arg.v = NULL; // 避免重复释放 - } + for (i = 0; i < config.key_bindings_count; i++) { + if (config.key_bindings[i].arg.v) { + free((void *)config.key_bindings[i].arg.v); + config.key_bindings[i].arg.v = NULL; // 避免重复释放 } - free(config.key_bindings); + } + free(config.key_bindings); - for ( i = 0; i < config.mouse_bindings_count; i++) { - if (config.mouse_bindings[i].arg.v) { - free((void *)config.mouse_bindings[i].arg.v); - config.mouse_bindings[i].arg.v = NULL; // 避免重复释放 - } + for (i = 0; i < config.mouse_bindings_count; i++) { + if (config.mouse_bindings[i].arg.v) { + free((void *)config.mouse_bindings[i].arg.v); + config.mouse_bindings[i].arg.v = NULL; // 避免重复释放 } - free(config.mouse_bindings); + } + free(config.mouse_bindings); - for (i = 0; i < config.axis_bindings_count; i++) { - if (config.axis_bindings[i].arg.v) { - free((void *)config.axis_bindings[i].arg.v); - config.axis_bindings[i].arg.v = NULL; // 避免重复释放 - } + for (i = 0; i < config.axis_bindings_count; i++) { + if (config.axis_bindings[i].arg.v) { + free((void *)config.axis_bindings[i].arg.v); + config.axis_bindings[i].arg.v = NULL; // 避免重复释放 } - free(config.axis_bindings); - + } + free(config.axis_bindings); } void override_config(void) { - animations = config.animations; - animation_type = config.animation_type; - animation_fade_in = config.animation_fade_in; - zoom_initial_ratio = config.zoom_initial_ratio; - fadein_begin_opacity = config.fadein_begin_opacity; - animation_duration_move = config.animation_duration_move; - animation_duration_open = config.animation_duration_open; - animation_duration_tag = config.animation_duration_tag; + animations = config.animations; + animation_type = config.animation_type; + animation_fade_in = config.animation_fade_in; + zoom_initial_ratio = config.zoom_initial_ratio; + fadein_begin_opacity = config.fadein_begin_opacity; + animation_duration_move = config.animation_duration_move; + animation_duration_open = config.animation_duration_open; + animation_duration_tag = config.animation_duration_tag; - // 复制数组类型的变量 - memcpy(animation_curve, config.animation_curve, sizeof(animation_curve)); - memcpy(scroller_proportion_preset, config.scroller_proportion_preset, sizeof(scroller_proportion_preset)); + // 复制数组类型的变量 + memcpy(animation_curve, config.animation_curve, sizeof(animation_curve)); + memcpy(scroller_proportion_preset, config.scroller_proportion_preset, + sizeof(scroller_proportion_preset)); - scroller_structs = config.scroller_structs; - scroller_default_proportion = config.scroller_default_proportion; - scoller_focus_center = config.scoller_focus_center; + scroller_structs = config.scroller_structs; + scroller_default_proportion = config.scroller_default_proportion; + scoller_focus_center = config.scoller_focus_center; - new_is_master = config.new_is_master; - default_mfact = config.default_mfact; - default_nmaster = config.default_nmaster; - hotarea_size = config.hotarea_size; - enable_hotarea = config.enable_hotarea; - ov_tab_mode = config.ov_tab_mode; - overviewgappi = config.overviewgappi; - overviewgappo = config.overviewgappo; - axis_bind_apply_timeout = config.axis_bind_apply_timeout; - focus_on_activate = config.focus_on_activate; - numlockon = config.numlockon; - bypass_surface_visibility = config.bypass_surface_visibility; - sloppyfocus = config.sloppyfocus; - warpcursor = config.warpcursor; - smartgaps = config.smartgaps; - gappih = config.gappih; - gappiv = config.gappiv; - gappoh = config.gappoh; - gappov = config.gappov; - borderpx = config.borderpx; + new_is_master = config.new_is_master; + default_mfact = config.default_mfact; + default_nmaster = config.default_nmaster; + hotarea_size = config.hotarea_size; + enable_hotarea = config.enable_hotarea; + ov_tab_mode = config.ov_tab_mode; + overviewgappi = config.overviewgappi; + overviewgappo = config.overviewgappo; + axis_bind_apply_timeout = config.axis_bind_apply_timeout; + focus_on_activate = config.focus_on_activate; + numlockon = config.numlockon; + bypass_surface_visibility = config.bypass_surface_visibility; + sloppyfocus = config.sloppyfocus; + warpcursor = config.warpcursor; + smartgaps = config.smartgaps; + gappih = config.gappih; + gappiv = config.gappiv; + gappoh = config.gappoh; + gappov = config.gappov; + borderpx = config.borderpx; - // 复制颜色数组 - memcpy(rootcolor, config.rootcolor, sizeof(rootcolor)); - memcpy(bordercolor, config.bordercolor, sizeof(bordercolor)); - memcpy(focuscolor, config.focuscolor, sizeof(focuscolor)); - memcpy(maxmizescreencolor, config.maxmizescreencolor, sizeof(maxmizescreencolor)); - memcpy(urgentcolor, config.urgentcolor, sizeof(urgentcolor)); - memcpy(scratchpadcolor, config.scratchpadcolor, sizeof(scratchpadcolor)); - memcpy(globalcolor, config.globalcolor, sizeof(globalcolor)); + // 复制颜色数组 + memcpy(rootcolor, config.rootcolor, sizeof(rootcolor)); + memcpy(bordercolor, config.bordercolor, sizeof(bordercolor)); + memcpy(focuscolor, config.focuscolor, sizeof(focuscolor)); + memcpy(maxmizescreencolor, config.maxmizescreencolor, + sizeof(maxmizescreencolor)); + memcpy(urgentcolor, config.urgentcolor, sizeof(urgentcolor)); + memcpy(scratchpadcolor, config.scratchpadcolor, sizeof(scratchpadcolor)); + memcpy(globalcolor, config.globalcolor, sizeof(globalcolor)); } void parse_config(void) { @@ -4460,21 +4494,20 @@ void parse_config(void) { config.axis_bindings = NULL; config.axis_bindings_count = 0; - // 获取当前用户家目录 - const char *homedir = getenv("HOME"); - if (!homedir) { - // 如果获取失败,则无法继续 - return; - } + // 获取当前用户家目录 + const char *homedir = getenv("HOME"); + if (!homedir) { + // 如果获取失败,则无法继续 + return; + } // 构建日志文件路径 - snprintf(filename, sizeof(filename), "%s/.config/maomao/config.conf", homedir); + snprintf(filename, sizeof(filename), "%s/.config/maomao/config.conf", + homedir); - - parse_config_file(&config, filename); + parse_config_file(&config, filename); override_config(); - } void reload_config(const Arg *arg) { @@ -4484,7 +4517,6 @@ void reload_config(const Arg *arg) { void setup(void) { - signal(SIGSEGV, signalhandler); parse_config(); @@ -4752,28 +4784,28 @@ void sigchld(int unused) { void spawn(const Arg *arg) { if (fork() == 0) { - dup2(STDERR_FILENO, STDOUT_FILENO); - setsid(); + dup2(STDERR_FILENO, STDOUT_FILENO); + setsid(); - // 将 arg->v 拆分为字符串数组 - char *argv[64]; // 假设最多有 64 个参数 - int argc = 0; - char *token = strtok((char *)arg->v, " "); - while (token != NULL && argc < 63) { - // 扩展 ~ 为家目录路径 - wordexp_t p; - if (wordexp(token, &p, 0) == 0) { - argv[argc++] = p.we_wordv[0]; - } else { - argv[argc++] = token; // 如果扩展失败,使用原始 token - } - token = strtok(NULL, " "); + // 将 arg->v 拆分为字符串数组 + char *argv[64]; // 假设最多有 64 个参数 + int argc = 0; + char *token = strtok((char *)arg->v, " "); + while (token != NULL && argc < 63) { + // 扩展 ~ 为家目录路径 + wordexp_t p; + if (wordexp(token, &p, 0) == 0) { + argv[argc++] = p.we_wordv[0]; + } else { + argv[argc++] = token; // 如果扩展失败,使用原始 token } - argv[argc] = NULL; // execvp 需要以 NULL 结尾的数组 + token = strtok(NULL, " "); + } + argv[argc] = NULL; // execvp 需要以 NULL 结尾的数组 - // 执行命令 - execvp(argv[0], argv); - die("dwl: execvp %s failed:", argv[0]); + // 执行命令 + execvp(argv[0], argv); + die("dwl: execvp %s failed:", argv[0]); } } @@ -4834,80 +4866,75 @@ void overview(Monitor *m, unsigned int gappo, unsigned int gappi) { grid(m, overviewgappo, overviewgappi); } - void fibonacci(Monitor *mon, int s) { - unsigned int i=0, n=0, nx, ny, nw, nh; - Client *c; + unsigned int i = 0, n = 0, nx, ny, nw, nh; + Client *c; - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, mon) && !c->isfloating && !c->iskilling - && !c->isfullscreen && !c->ismaxmizescreen - && !c->animation.tagouting) - n++; - if(n == 0) - return; + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, mon) && !c->isfloating && + !c->iskilling && !c->isfullscreen && + !c->ismaxmizescreen && + !c->animation.tagouting) n++; + if (n == 0) + return; - nx = mon->w.x + gappoh; - ny = mon->w.y + gappov; - nw = mon->w.width - gappoh; - nh = mon->w.height - gappov; + nx = mon->w.x + gappoh; + ny = mon->w.y + gappov; + nw = mon->w.width - gappoh; + nh = mon->w.height - gappov; - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, mon) && !c->isfloating && !c->iskilling - && !c->isfullscreen && !c->ismaxmizescreen - && !c->animation.tagouting) { - if((i % 2 && nh / 2 > 2 * c->bw) - || (!(i % 2) && nw / 2 > 2 * c->bw)) { - if(i < n - 1) { - if(i % 2) - nh /= 2; - else - nw /= 2; - if((i % 4) == 2 && !s) - nx += nw; - else if((i % 4) == 3 && !s) - ny += nh; - } - if((i % 4) == 0) { - if(s) - ny += nh; - else - ny -= nh; - } - else if((i % 4) == 1) - nx += nw; - else if((i % 4) == 2) - ny += nh; - else if((i % 4) == 3) { - if(s) - nx += nw; - else - nx -= nw; - } - if(i == 0) - { - if(n != 1) - nw = (mon->w.width - gappoh) * mon->pertag->mfacts[mon->pertag->curtag]; - ny = mon->w.y + gappov; - } - else if(i == 1) - nw = mon->w.width - gappoh - nw; - i++; - } - - resize(c, (struct wlr_box){.x = nx, .y = ny, - .width = nw - gappih, .height = nh - gappiv}, 0); - } + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, mon) && !c->isfloating && + !c->iskilling && !c->isfullscreen && + !c->ismaxmizescreen && + !c->animation.tagouting) { + if ((i % 2 && nh / 2 > 2 * c->bw) || (!(i % 2) && nw / 2 > 2 * c->bw)) { + if (i < n - 1) { + if (i % 2) + nh /= 2; + else + nw /= 2; + if ((i % 4) == 2 && !s) + nx += nw; + else if ((i % 4) == 3 && !s) + ny += nh; + } + if ((i % 4) == 0) { + if (s) + ny += nh; + else + ny -= nh; + } else if ((i % 4) == 1) + nx += nw; + else if ((i % 4) == 2) + ny += nh; + else if ((i % 4) == 3) { + if (s) + nx += nw; + else + nx -= nw; + } + if (i == 0) { + if (n != 1) + nw = (mon->w.width - gappoh) * + mon->pertag->mfacts[mon->pertag->curtag]; + ny = mon->w.y + gappov; + } else if (i == 1) + nw = mon->w.width - gappoh - nw; + i++; + } + + resize(c, + (struct wlr_box){ + .x = nx, .y = ny, .width = nw - gappih, .height = nh - gappiv}, + 0); + } } -void -dwindle(Monitor *mon,unsigned int gappo, unsigned int gappi) { - fibonacci(mon, 1); +void dwindle(Monitor *mon, unsigned int gappo, unsigned int gappi) { + fibonacci(mon, 1); } -void -spiral(Monitor *mon, unsigned int gappo, unsigned int gappi) { - fibonacci(mon, 0); +void spiral(Monitor *mon, unsigned int gappo, unsigned int gappi) { + fibonacci(mon, 0); } // 网格布局窗口大小和位置计算 @@ -4922,7 +4949,8 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) { // 第一次遍历,计算 n 的值 wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && !c->iskilling && !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->iskilling && !c->animation.tagouting && + c->mon == selmon) { n++; } } @@ -4932,7 +4960,7 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) { } // 动态分配内存 - tempClients = malloc(n * sizeof(Client*)); + tempClients = malloc(n * sizeof(Client *)); if (!tempClients) { // 处理内存分配失败的情况 return; @@ -4941,7 +4969,8 @@ void grid(Monitor *m, unsigned int gappo, unsigned int gappi) { // 第二次遍历,填充 tempClients n = 0; wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && !c->iskilling && !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->iskilling && !c->animation.tagouting && + c->mon == selmon) { tempClients[n] = c; n++; } @@ -5018,8 +5047,9 @@ void scroller(Monitor *m, unsigned int gappo, unsigned int gappi) { // 第一次遍历,计算 n 的值 wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && !c->isfloating && !c->isfullscreen && !c->ismaxmizescreen && !c->iskilling && - !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->isfloating && !c->isfullscreen && + !c->ismaxmizescreen && !c->iskilling && !c->animation.tagouting && + c->mon == selmon) { n++; } } @@ -5029,7 +5059,7 @@ void scroller(Monitor *m, unsigned int gappo, unsigned int gappi) { } // 动态分配内存 - tempClients = malloc(n * sizeof(Client*)); + tempClients = malloc(n * sizeof(Client *)); if (!tempClients) { // 处理内存分配失败的情况 return; @@ -5038,8 +5068,9 @@ void scroller(Monitor *m, unsigned int gappo, unsigned int gappi) { // 第二次遍历,填充 tempClients n = 0; wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && !c->isfloating && !c->isfullscreen && !c->ismaxmizescreen && !c->iskilling && - !c->animation.tagouting && c->mon == selmon) { + if (VISIBLEON(c, c->mon) && !c->isfloating && !c->isfullscreen && + !c->ismaxmizescreen && !c->iskilling && !c->animation.tagouting && + c->mon == selmon) { tempClients[n] = c; n++; } @@ -5051,14 +5082,17 @@ void scroller(Monitor *m, unsigned int gappo, unsigned int gappi) { target_geom.width = max_client_width * c->scroller_proportion; target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; - resizeclient(c, target_geom.x, target_geom.y, target_geom.width, target_geom.height, 0); + resizeclient(c, target_geom.x, target_geom.y, target_geom.width, + target_geom.height, 0); free(tempClients); // 释放内存 return; } - if (selmon->sel && selmon->sel->istiled && !c->ismaxmizescreen && !c->isfullscreen) { + if (selmon->sel && selmon->sel->istiled && !c->ismaxmizescreen && + !c->isfullscreen) { root_client = selmon->sel; - } else if (selmon->prevsel && selmon->prevsel->istiled && !c->ismaxmizescreen && !c->isfullscreen) { + } else if (selmon->prevsel && selmon->prevsel->istiled && + !c->ismaxmizescreen && !c->isfullscreen) { root_client = selmon->prevsel; } else { wl_list_for_each(c, &clients, link) { @@ -5089,14 +5123,18 @@ void scroller(Monitor *m, unsigned int gappo, unsigned int gappi) { target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; if (need_scroller) { - if (scoller_focus_center || - selmon->prevsel == NULL || - (selmon->prevsel->scroller_proportion * max_client_width) + (root_client->scroller_proportion * max_client_width) > m->w.width - 2 * scroller_structs - gappih) { + if (scoller_focus_center || selmon->prevsel == NULL || + (selmon->prevsel->scroller_proportion * max_client_width) + + (root_client->scroller_proportion * max_client_width) > + m->w.width - 2 * scroller_structs - gappih) { target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; } else { - target_geom.x = root_client->geom.x > m->w.x + (m->w.width) / 2 ? - m->w.x + (m->w.width - root_client->scroller_proportion * max_client_width - scroller_structs) : - m->w.x + scroller_structs; + target_geom.x = + root_client->geom.x > m->w.x + (m->w.width) / 2 + ? m->w.x + (m->w.width - + root_client->scroller_proportion * max_client_width - + scroller_structs) + : m->w.x + scroller_structs; } resize(tempClients[focus_client_index], target_geom, 0); } else { @@ -5106,13 +5144,15 @@ void scroller(Monitor *m, unsigned int gappo, unsigned int gappi) { for (i = 1; i <= focus_client_index; i++) { c = tempClients[focus_client_index - i]; - target_geom.x = tempClients[focus_client_index - i + 1]->geom.x - gappih - target_geom.width; + target_geom.x = tempClients[focus_client_index - i + 1]->geom.x - gappih - + target_geom.width; resize(c, target_geom, 0); } for (i = 1; i < n - focus_client_index; i++) { c = tempClients[focus_client_index + i]; - target_geom.x = tempClients[focus_client_index + i - 1]->geom.x + gappih + tempClients[focus_client_index + i - 1]->geom.width; + target_geom.x = tempClients[focus_client_index + i - 1]->geom.x + gappih + + tempClients[focus_client_index + i - 1]->geom.width; resize(c, target_geom, 0); } @@ -5190,7 +5230,7 @@ void overview_restore(Client *c, const Arg *arg) { client_set_fullscreen(c, false); } } else { - if(c->is_restoring_from_ov ) { + if (c->is_restoring_from_ov) { c->is_restoring_from_ov = false; resizeclient(c, c->overview_backup_x, c->overview_backup_y, c->overview_backup_w, c->overview_backup_h, 0); @@ -5206,29 +5246,30 @@ void overview_restore(Client *c, const Arg *arg) { void switch_proportion_preset(const Arg *arg) { float target_proportion = 0; - if(LENGTH(scroller_proportion_preset) == 0) { + if (LENGTH(scroller_proportion_preset) == 0) { return; } if (selmon->sel) { for (int i = 0; i < LENGTH(scroller_proportion_preset); i++) { - if (scroller_proportion_preset[i] == selmon->sel->scroller_proportion) { - if(i == LENGTH(scroller_proportion_preset) -1) { - target_proportion = scroller_proportion_preset[0]; - break; - } else { - target_proportion = scroller_proportion_preset[i+1]; - break; - } + if (scroller_proportion_preset[i] == selmon->sel->scroller_proportion) { + if (i == LENGTH(scroller_proportion_preset) - 1) { + target_proportion = scroller_proportion_preset[0]; + break; + } else { + target_proportion = scroller_proportion_preset[i + 1]; + break; } + } } if (target_proportion == 0) { target_proportion = scroller_proportion_preset[0]; } - unsigned int max_client_width = selmon->w.width - 2 * scroller_structs - gappih; + unsigned int max_client_width = + selmon->w.width - 2 * scroller_structs - gappih; selmon->sel->scroller_proportion = target_proportion; selmon->sel->geom.width = max_client_width * target_proportion; // resize(selmon->sel, selmon->sel->geom, 0); @@ -5238,7 +5279,8 @@ void switch_proportion_preset(const Arg *arg) { void set_proportion(const Arg *arg) { if (selmon->sel) { - unsigned int max_client_width = selmon->w.width - 2 * scroller_structs - gappih; + unsigned int max_client_width = + selmon->w.width - 2 * scroller_structs - gappih; selmon->sel->scroller_proportion = arg->f; selmon->sel->geom.width = max_client_width * arg->f; // resize(selmon->sel, selmon->sel->geom, 0); @@ -5251,8 +5293,8 @@ void toggleoverview(const Arg *arg) { Client *c; - if(selmon->isoverview && ov_tab_mode && arg->i != -1 && selmon->sel) { - focusstack(&(Arg){.i=1}); + if (selmon->isoverview && ov_tab_mode && arg->i != -1 && selmon->sel) { + focusstack(&(Arg){.i = 1}); return; } @@ -5288,8 +5330,7 @@ void toggleoverview(const Arg *arg) { } } else { wl_list_for_each(c, &clients, link) { - if (c && - !c->iskilling && client_surface(c)->mapped) + if (c && !c->iskilling && client_surface(c)->mapped) overview_restore(c, &(Arg){.ui = target}); } } @@ -5297,9 +5338,8 @@ void toggleoverview(const Arg *arg) { view(&(Arg){.ui = target}, false); if (ov_tab_mode && selmon->isoverview && selmon->sel) { - focusstack(&(Arg){.i=1}); + focusstack(&(Arg){.i = 1}); } - } void tile(Monitor *m, unsigned int gappo, unsigned int uappi) { @@ -5615,7 +5655,7 @@ updatemons(struct wl_listener *listener, void *data) { void updatetitle(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, set_title); - if(!c || c->iskilling) + if (!c || c->iskilling) return; const char *title; @@ -5934,7 +5974,9 @@ void toggleglobal(const Arg *arg) { void zoom(const Arg *arg) { Client *c, *sel = focustop(selmon); - if (!sel || !selmon || !selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange || sel->isfloating) + if (!sel || !selmon || + !selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange || + sel->isfloating) return; /* Search for the first tiled window that is not sel, marking sel as @@ -5965,7 +6007,7 @@ void zoom(const Arg *arg) { void activatex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, activate); - if(!c || c->iskilling) + if (!c || c->iskilling) return; /* Only "managed" windows can be activated */ @@ -5992,7 +6034,7 @@ void // 0.7 configurex11(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, configure); - if(!c || c->iskilling) + if (!c || c->iskilling) return; struct wlr_xwayland_surface_configure_event *event = data; @@ -6007,7 +6049,8 @@ configurex11(struct wl_listener *listener, void *data) { event->width, event->height); return; } - if ((c->isfloating && c != grabc) || !c->mon->pertag->ltidxs[c->mon->pertag->curtag]->arrange) + if ((c->isfloating && c != grabc) || + !c->mon->pertag->ltidxs[c->mon->pertag->curtag]->arrange) resize(c, (struct wlr_box){.x = event->x - c->bw, .y = event->y - c->bw, @@ -6105,7 +6148,7 @@ int main(int argc, char *argv[]) { else if (c == 'd') log_level = WLR_DEBUG; else if (c == 'v') - die("dwl " VERSION); + die("maomao " VERSION); else goto usage; } diff --git a/meson.build b/meson.build index 261f2b4..1691617 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('maomao', ['c', 'cpp'], - version : '0.1' + version : '0.1.1' ) subdir('protocols') diff --git a/parse_config.h b/parse_config.h index 31ed1a7..f3bcc2d 100644 --- a/parse_config.h +++ b/parse_config.h @@ -1,723 +1,742 @@ -#include -#include #include #include +#include +#include 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; - int width; - int height; + const char *id; + const char *title; + unsigned int tags; + int isfloating; + int isfullscreen; + float scroller_proportion; + const char *animation_type; + int isnoborder; + int monitor; + int width; + int height; } ConfigWinRule; typedef struct { - const char *name; // 显示器名称 - float mfact; // 主区域比例 - int nmaster; // 主区域窗口数量 - const char *layout; // 布局名称(字符串) - int rr; // 旋转和翻转(假设为整数) - float scale; // 显示器缩放比例 - int x, y; // 显示器位置 + 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; + 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; + 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; + 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 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]; + 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 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 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; + 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; - float rootcolor[4]; - float bordercolor[4]; - float focuscolor[4]; - float maxmizescreencolor[4]; - float urgentcolor[4]; - float scratchpadcolor[4]; - float globalcolor[4]; + int smartgaps; + unsigned int gappih; + unsigned int gappiv; + unsigned int gappoh; + unsigned int gappov; + unsigned int borderpx; + float rootcolor[4]; + float bordercolor[4]; + float focuscolor[4]; + float maxmizescreencolor[4]; + float urgentcolor[4]; + float scratchpadcolor[4]; + float globalcolor[4]; - char autostart[3][256]; + char autostart[3][256]; - struct { - int id; - char layout_name[256]; - } tags[9]; + struct { + int id; + char layout_name[256]; + } tags[9]; - ConfigWinRule *window_rules; - int window_rules_count; + ConfigWinRule *window_rules; + int window_rules_count; - ConfigMonitorRule *monitor_rules; // 动态数组 - int monitor_rules_count; // 条数 + ConfigMonitorRule *monitor_rules; // 动态数组 + int monitor_rules_count; // 条数 - KeyBinding *key_bindings; - int key_bindings_count; + KeyBinding *key_bindings; + int key_bindings_count; - MouseBinding *mouse_bindings; - int mouse_bindings_count; + MouseBinding *mouse_bindings; + int mouse_bindings_count; - AxisBinding *axis_bindings; - int axis_bindings_count; + AxisBinding *axis_bindings; + int axis_bindings_count; } Config; -int parseDirection(const char* str) { - // 将输入字符串转换为小写 - char lowerStr[10]; - int i = 0; - while (str[i] && i < 9) { - lowerStr[i] = tolower(str[i]); - i++; - } - lowerStr[i] = '\0'; +int parseDirection(const char *str) { + // 将输入字符串转换为小写 + char lowerStr[10]; + int i = 0; + while (str[i] && i < 9) { + lowerStr[i] = tolower(str[i]); + i++; + } + lowerStr[i] = '\0'; - // 根据转换后的小写字符串返回对应的枚举值 - if (strcmp(lowerStr, "up") == 0) { - return UP; - } else if (strcmp(lowerStr, "down") == 0) { - return DOWN; - } else if (strcmp(lowerStr, "left") == 0) { - return LEFT; - } else if (strcmp(lowerStr, "right") == 0) { - return RIGHT; - } else { - return UNDIR; - } + // 根据转换后的小写字符串返回对应的枚举值 + if (strcmp(lowerStr, "up") == 0) { + return UP; + } else if (strcmp(lowerStr, "down") == 0) { + return DOWN; + } else if (strcmp(lowerStr, "left") == 0) { + return LEFT; + } else if (strcmp(lowerStr, "right") == 0) { + return RIGHT; + } else { + return UNDIR; + } } 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; + char *endptr; + long int hex_num = strtol(hex_str, &endptr, 16); + if (*endptr != '\0') { + return -1; + } + return hex_num; } // 辅助函数:检查字符串是否以指定的前缀开头(忽略大小写) static bool starts_with_ignore_case(const char *str, const char *prefix) { - while (*prefix) { - if (tolower(*str) != tolower(*prefix)) { - return false; - } - str++; - prefix++; + while (*prefix) { + if (tolower(*str) != tolower(*prefix)) { + return false; } - return true; + str++; + prefix++; + } + return true; } uint32_t parse_mod(const char *mod_str) { - uint32_t mod = 0; - char lower_str[64]; // 假设输入的字符串长度不超过 64 - int i = 0; + uint32_t mod = 0; + char lower_str[64]; // 假设输入的字符串长度不超过 64 + int i = 0; - // 将 mod_str 转换为全小写 - for (i = 0; mod_str[i] && i < sizeof(lower_str) - 1; i++) { - lower_str[i] = tolower(mod_str[i]); - } - lower_str[i] = '\0'; // 确保字符串以 NULL 结尾 + // 将 mod_str 转换为全小写 + for (i = 0; mod_str[i] && i < sizeof(lower_str) - 1; i++) { + lower_str[i] = tolower(mod_str[i]); + } + lower_str[i] = '\0'; // 确保字符串以 NULL 结尾 - // 检查修饰键,忽略左右键标识(如 "_l" 和 "_r") - if (strstr(lower_str, "super") || strstr(lower_str, "super_l") || strstr(lower_str, "super_r")) { - mod |= WLR_MODIFIER_LOGO; - } - if (strstr(lower_str, "ctrl") || strstr(lower_str, "ctrl_l") || strstr(lower_str, "ctrl_r")) { - mod |= WLR_MODIFIER_CTRL; - } - if (strstr(lower_str, "shift") || strstr(lower_str, "shift_l") || strstr(lower_str, "shift_r")) { - mod |= WLR_MODIFIER_SHIFT; - } - if (strstr(lower_str, "alt") || strstr(lower_str, "alt_l") || strstr(lower_str, "alt_r")) { - mod |= WLR_MODIFIER_ALT; - } + // 检查修饰键,忽略左右键标识(如 "_l" 和 "_r") + if (strstr(lower_str, "super") || strstr(lower_str, "super_l") || + strstr(lower_str, "super_r")) { + mod |= WLR_MODIFIER_LOGO; + } + if (strstr(lower_str, "ctrl") || strstr(lower_str, "ctrl_l") || + strstr(lower_str, "ctrl_r")) { + mod |= WLR_MODIFIER_CTRL; + } + if (strstr(lower_str, "shift") || strstr(lower_str, "shift_l") || + strstr(lower_str, "shift_r")) { + mod |= WLR_MODIFIER_SHIFT; + } + if (strstr(lower_str, "alt") || strstr(lower_str, "alt_l") || + strstr(lower_str, "alt_r")) { + mod |= WLR_MODIFIER_ALT; + } - return mod; + return mod; } xkb_keysym_t parse_keysym(const char *keysym_str) { - if (strcmp(keysym_str, "F1") == 0 || strcmp(keysym_str, "f1") == 0) - return XKB_KEY_XF86Switch_VT_1; - else if (strcmp(keysym_str, "F2") == 0 || strcmp(keysym_str, "f2") == 0) - return XKB_KEY_XF86Switch_VT_2; - else if (strcmp(keysym_str, "F3") == 0 || strcmp(keysym_str, "f3") == 0) - return XKB_KEY_XF86Switch_VT_3; - else if (strcmp(keysym_str, "F4") == 0 || strcmp(keysym_str, "f4") == 0) - return XKB_KEY_XF86Switch_VT_4; - else if (strcmp(keysym_str, "F5") == 0 || strcmp(keysym_str, "f5") == 0) - return XKB_KEY_XF86Switch_VT_5; - else if (strcmp(keysym_str, "F6") == 0 || strcmp(keysym_str, "f6") == 0) - return XKB_KEY_XF86Switch_VT_6; - else if (strcmp(keysym_str, "F7") == 0 || strcmp(keysym_str, "f7") == 0) - return XKB_KEY_XF86Switch_VT_7; - else if (strcmp(keysym_str, "F8") == 0 || strcmp(keysym_str, "f8") == 0) - return XKB_KEY_XF86Switch_VT_8; - else if (strcmp(keysym_str, "F9") == 0 || strcmp(keysym_str, "f9") == 0) - return XKB_KEY_XF86Switch_VT_9; - else if (strcmp(keysym_str, "F10") == 0 || strcmp(keysym_str, "f10") == 0) - return XKB_KEY_XF86Switch_VT_10; - else if (strcmp(keysym_str, "F11") == 0 || strcmp(keysym_str, "f11") == 0) - return XKB_KEY_XF86Switch_VT_11; - else if (strcmp(keysym_str, "F12") == 0 || strcmp(keysym_str, "f12") == 0) - return XKB_KEY_XF86Switch_VT_12; - return xkb_keysym_from_name(keysym_str, XKB_KEYSYM_NO_FLAGS); + if (strcmp(keysym_str, "F1") == 0 || strcmp(keysym_str, "f1") == 0) + return XKB_KEY_XF86Switch_VT_1; + else if (strcmp(keysym_str, "F2") == 0 || strcmp(keysym_str, "f2") == 0) + return XKB_KEY_XF86Switch_VT_2; + else if (strcmp(keysym_str, "F3") == 0 || strcmp(keysym_str, "f3") == 0) + return XKB_KEY_XF86Switch_VT_3; + else if (strcmp(keysym_str, "F4") == 0 || strcmp(keysym_str, "f4") == 0) + return XKB_KEY_XF86Switch_VT_4; + else if (strcmp(keysym_str, "F5") == 0 || strcmp(keysym_str, "f5") == 0) + return XKB_KEY_XF86Switch_VT_5; + else if (strcmp(keysym_str, "F6") == 0 || strcmp(keysym_str, "f6") == 0) + return XKB_KEY_XF86Switch_VT_6; + else if (strcmp(keysym_str, "F7") == 0 || strcmp(keysym_str, "f7") == 0) + return XKB_KEY_XF86Switch_VT_7; + else if (strcmp(keysym_str, "F8") == 0 || strcmp(keysym_str, "f8") == 0) + return XKB_KEY_XF86Switch_VT_8; + else if (strcmp(keysym_str, "F9") == 0 || strcmp(keysym_str, "f9") == 0) + return XKB_KEY_XF86Switch_VT_9; + else if (strcmp(keysym_str, "F10") == 0 || strcmp(keysym_str, "f10") == 0) + return XKB_KEY_XF86Switch_VT_10; + else if (strcmp(keysym_str, "F11") == 0 || strcmp(keysym_str, "f11") == 0) + return XKB_KEY_XF86Switch_VT_11; + else if (strcmp(keysym_str, "F12") == 0 || strcmp(keysym_str, "f12") == 0) + return XKB_KEY_XF86Switch_VT_12; + return xkb_keysym_from_name(keysym_str, XKB_KEYSYM_NO_FLAGS); } typedef void (*FuncType)(const Arg *); - int parseButton(const char *str) { - // 将输入字符串转换为小写 - char lowerStr[20]; - int i = 0; - while (str[i] && i < 19) { - lowerStr[i] = tolower(str[i]); - i++; - } - lowerStr[i] = '\0'; // 确保字符串正确终止 + // 将输入字符串转换为小写 + char lowerStr[20]; + int i = 0; + while (str[i] && i < 19) { + lowerStr[i] = tolower(str[i]); + i++; + } + lowerStr[i] = '\0'; // 确保字符串正确终止 - // 根据转换后的小写字符串返回对应的按钮编号 - if (strcmp(lowerStr, "btn_left") == 0) { - return BTN_LEFT; - } else if (strcmp(lowerStr, "btn_right") == 0) { - return BTN_RIGHT; - } else if (strcmp(lowerStr, "btn_middle") == 0) { - return BTN_MIDDLE; - } else if (strcmp(lowerStr, "btn_side") == 0) { - return BTN_SIDE; - } else if (strcmp(lowerStr, "btn_extra") == 0) { - return BTN_EXTRA; - } else if (strcmp(lowerStr, "btn_forward") == 0) { - return BTN_FORWARD; - } else if (strcmp(lowerStr, "btn_back") == 0) { - return BTN_BACK; - } else if (strcmp(lowerStr, "btn_task") == 0) { - return BTN_TASK; - } else { - return 0; - } + // 根据转换后的小写字符串返回对应的按钮编号 + if (strcmp(lowerStr, "btn_left") == 0) { + return BTN_LEFT; + } else if (strcmp(lowerStr, "btn_right") == 0) { + return BTN_RIGHT; + } else if (strcmp(lowerStr, "btn_middle") == 0) { + return BTN_MIDDLE; + } else if (strcmp(lowerStr, "btn_side") == 0) { + return BTN_SIDE; + } else if (strcmp(lowerStr, "btn_extra") == 0) { + return BTN_EXTRA; + } else if (strcmp(lowerStr, "btn_forward") == 0) { + return BTN_FORWARD; + } else if (strcmp(lowerStr, "btn_back") == 0) { + return BTN_BACK; + } else if (strcmp(lowerStr, "btn_task") == 0) { + return BTN_TASK; + } else { + return 0; + } } - int parseMouseAction(const char *str) { - // 将输入字符串转换为小写 - char lowerStr[20]; - int i = 0; - while (str[i] && i < 19) { - lowerStr[i] = tolower(str[i]); - i++; - } - lowerStr[i] = '\0'; // 确保字符串正确终止 + // 将输入字符串转换为小写 + char lowerStr[20]; + int i = 0; + while (str[i] && i < 19) { + lowerStr[i] = tolower(str[i]); + i++; + } + lowerStr[i] = '\0'; // 确保字符串正确终止 - // 根据转换后的小写字符串返回对应的按钮编号 - if (strcmp(lowerStr, "curmove") == 0) { - return CurMove; - } else if (strcmp(lowerStr, "curresize") == 0) { - return CurResize; - } else if (strcmp(lowerStr, "curnormal") == 0) { - return CurNormal; - } else if (strcmp(lowerStr, "curpressed") == 0) { - return CurPressed; - } else { - return 0; - } + // 根据转换后的小写字符串返回对应的按钮编号 + if (strcmp(lowerStr, "curmove") == 0) { + return CurMove; + } else if (strcmp(lowerStr, "curresize") == 0) { + return CurResize; + } else if (strcmp(lowerStr, "curnormal") == 0) { + return CurNormal; + } else if (strcmp(lowerStr, "curpressed") == 0) { + return CurPressed; + } else { + return 0; + } } -void parseColoer(float *color,unsigned long int hex) { - color[0] = ((hex >> 24) & 0xFF) / 255.0f; - color[1] = ((hex >> 16) & 0xFF) / 255.0f; - color[2] = ((hex >> 8) & 0xFF) / 255.0f; - color[3] = (hex & 0xFF) / 255.0f; +void parseColoer(float *color, unsigned long int hex) { + color[0] = ((hex >> 24) & 0xFF) / 255.0f; + color[1] = ((hex >> 16) & 0xFF) / 255.0f; + color[2] = ((hex >> 8) & 0xFF) / 255.0f; + color[3] = (hex & 0xFF) / 255.0f; } -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 = parseDirection(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 = parseDirection(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; - (*arg).v = strdup(arg_value); - } 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).ui = 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 = parseMouseAction(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 if (strcmp(func_name, "reload_config") == 0) { - func = reload_config; - } else if (strcmp(func_name, "tag") == 0) { - func = tag; - (*arg).ui = 1 << (atoi(arg_value) -1); - } else if (strcmp(func_name, "view") == 0) { - func = bind_to_view; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } else { - return NULL; - } - return func; +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 = parseDirection(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 = parseDirection(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; + (*arg).v = strdup(arg_value); + } 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).ui = 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 = parseMouseAction(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 if (strcmp(func_name, "reload_config") == 0) { + func = reload_config; + } else if (strcmp(func_name, "tag") == 0) { + func = tag; + (*arg).ui = 1 << (atoi(arg_value) - 1); + } else if (strcmp(func_name, "view") == 0) { + func = bind_to_view; + (*arg).ui = 1 << (atoi(arg_value) - 1); + } 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; + 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); } - - 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 { - parseColoer(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 { - parseColoer(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 { - parseColoer(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 { - parseColoer(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 { - parseColoer(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 { - parseColoer(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 { - parseColoer(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 layout_name[256]; - if (sscanf(value, "id:%d,layout_name:%255[^\n]", &id, layout_name) == 2) { - if (id >= 1 && id <= 9) { - config->tags[id - 1].id = id; - strncpy(config->tags[id - 1].layout_name, layout_name, sizeof(config->tags[id - 1].layout_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)); - - rule->isfloating = -1; - rule->isfullscreen = -1; - rule->isnoborder = -1; - rule->monitor = -1; - rule->width = -1; - rule->height = -1; - rule->animation_type = NULL; - rule->scroller_proportion = -1; - rule->id = NULL; - rule->title = NULL; - rule->tags = 0; - - - 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 = 1 << (atoi(val) - 1); - } 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 = parseButton(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 = parseDirection(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 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 { - fprintf(stderr, "Error: Unknown key: %s\n", key); + parseColoer(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 { + parseColoer(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 { + parseColoer(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 { + parseColoer(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 { + parseColoer(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 { + parseColoer(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 { + parseColoer(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 layout_name[256]; + if (sscanf(value, "id:%d,layout_name:%255[^\n]", &id, layout_name) == 2) { + if (id >= 1 && id <= 9) { + config->tags[id - 1].id = id; + strncpy(config->tags[id - 1].layout_name, layout_name, + sizeof(config->tags[id - 1].layout_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)); + + rule->isfloating = -1; + rule->isfullscreen = -1; + rule->isnoborder = -1; + rule->monitor = -1; + rule->width = -1; + rule->height = -1; + rule->animation_type = NULL; + rule->scroller_proportion = -1; + rule->id = NULL; + rule->title = NULL; + rule->tags = 0; + + 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 = 1 << (atoi(val) - 1); + } 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 = parseButton(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 = parseDirection(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; - } + 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); - } + char line[512]; + while (fgets(line, sizeof(line), file)) { + if (line[0] == '#' || line[0] == '\n') + continue; + parse_config_line(config, line); + } - fclose(file); + fclose(file); } \ No newline at end of file diff --git a/preset_config.h b/preset_config.h index 8cd65ae..8d51e4c 100644 --- a/preset_config.h +++ b/preset_config.h @@ -1,89 +1,86 @@ /* 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 } +#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; //动画起始窗口比例 +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}; //动画曲线 +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; //新窗口是否插在头部 -double default_mfact = 0.55f; // master 窗口比例 -unsigned int default_nmaster = 1; //默认master数量 +unsigned int axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔 +unsigned int focus_on_activate = 1; // 收到窗口激活请求是否自动跳转聚焦 +unsigned int new_is_master = 1; // 新窗口是否插在头部 +double 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 */ +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_focus_center = 0; -float scroller_proportion_preset[] = {0.5,0.9,1.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); +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 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}; +/* 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 overviewlayout = {"󰃇", overview, "overview"}; -Layout layouts[] = { //最少两个,不能删除少于两个 - /* symbol arrange function name */ - { "S", scroller, "scroller" }, //滚动布局 - { "T", tile, "tile" }, //堆栈布局 - {"G", grid, "grid"}, - {"M",monocle,"monocle"}, - {"D",dwindle,"dwindle"}, - {"P",spiral,"spiral"}, +Layout layouts[] = { + // 最少两个,不能删除少于两个 + /* symbol arrange function name */ + {"S", scroller, "scroller"}, // 滚动布局 + {"T", tile, "tile"}, // 堆栈布局 + {"G", grid, "grid"}, {"M", monocle, "monocle"}, + {"D", dwindle, "dwindle"}, {"P", spiral, "spiral"}, }; - - /* keyboard */ struct xkb_rule_names xkb_rules = { - /* can specify fields: rules, model, layout, variant, options */ - /* example: - .options = "ctrl:nocaps", - */ - .options = NULL, + /* can specify fields: rules, model, layout, variant, options */ + /* example: + .options = "ctrl:nocaps", + */ + .options = NULL, }; int repeat_rate = 25; @@ -110,7 +107,8 @@ 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; +enum libinput_config_click_method click_method = + LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; /* You can choose between: LIBINPUT_CONFIG_SEND_EVENTS_ENABLED @@ -123,7 +121,8 @@ uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE */ -enum libinput_config_accel_profile accel_profile = 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 @@ -135,21 +134,9 @@ enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM; #define MODKEY WLR_MODIFIER_ALT static const char *tags[] = { - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", + "1", "2", "3", "4", "5", "6", "7", "8", "9", }; static const char *const autostart[] = { - "/bin/sh", - "-c", - "~/.config/maomao/autostart.sh", - NULL, - NULL, + "/bin/sh", "-c", "~/.config/maomao/autostart.sh", NULL, NULL, }; \ No newline at end of file diff --git a/util.c b/util.c index cca7c19..f49e1af 100644 --- a/util.c +++ b/util.c @@ -6,30 +6,27 @@ #include "util.h" -void -die(const char *fmt, ...) { - va_list ap; +void die(const char *fmt, ...) { + va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } + if (fmt[0] && fmt[strlen(fmt) - 1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } - exit(1); + exit(1); } -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; +void *ecalloc(size_t nmemb, size_t size) { + void *p; - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; }