From ce577adf4ad1e2cf1b77f1a27a5900906ba43b22 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 7 Mar 2025 18:55:44 +0800 Subject: [PATCH] fix: crash when use ipc tool set tag --- maomao.c | 225 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 118 insertions(+), 107 deletions(-) diff --git a/maomao.c b/maomao.c index 6886017..815fcf5 100644 --- a/maomao.c +++ b/maomao.c @@ -251,7 +251,7 @@ struct Client { typedef struct { struct wl_list link; struct wl_resource *resource; - Monitor *monitor; + Monitor *mon; } DwlIpcOutput; typedef struct { @@ -552,6 +552,7 @@ void client_set_opacity(Client *c, double opacity); void init_baked_points(void); void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx, int sy, void *data); +void view_in_mon(const Arg *arg, bool want_animation, Monitor *m); Client *direction_select(const Arg *arg); void bind_to_view(const Arg *arg); @@ -2051,6 +2052,10 @@ cleanupmon(struct wl_listener *listener, void *data) { LayerSurface *l, *tmp; size_t i; + DwlIpcOutput *ipc_output, *ipc_output_tmp; + wl_list_for_each_safe(ipc_output, ipc_output_tmp, &m->dwl_ipc_outputs, link) + wl_resource_destroy(ipc_output->resource); + /* m->layers[i] are intentionally not unlinked */ for (i = 0; i < LENGTH(m->layers); i++) { wl_list_for_each_safe(l, tmp, &m->layers[i], link) @@ -2757,67 +2762,69 @@ dirtomon(enum wlr_direction dir) { return selmon; } -void dwl_ipc_manager_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) { - struct wl_resource *manager_resource = - wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id); - if (!manager_resource) { - wl_client_post_no_memory(client); - return; - } - wl_resource_set_implementation(manager_resource, &dwl_manager_implementation, - NULL, dwl_ipc_manager_destroy); +void +dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct wl_resource *manager_resource = wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id); + if (!manager_resource) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(manager_resource, &dwl_manager_implementation, NULL, dwl_ipc_manager_destroy); - zdwl_ipc_manager_v2_send_tags(manager_resource, LENGTH(tags)); + zdwl_ipc_manager_v2_send_tags(manager_resource, LENGTH(tags)); - for (int i = 0; i < LENGTH(layouts); i++) - zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol); + for (unsigned int i = 0; i < LENGTH(layouts); i++) + zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol); } -void dwl_ipc_manager_destroy(struct wl_resource *resource) { - /* No state to destroy */ +void +dwl_ipc_manager_destroy(struct wl_resource *resource) +{ + /* No state to destroy */ } -void dwl_ipc_manager_get_output(struct wl_client *client, - struct wl_resource *resource, uint32_t id, - struct wl_resource *output) { - DwlIpcOutput *ipc_output; - Monitor *monitor = wlr_output_from_resource(output)->data; - struct wl_resource *output_resource = - wl_resource_create(client, &zdwl_ipc_output_v2_interface, - wl_resource_get_version(resource), id); - if (!output_resource) - return; +void +dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output) +{ + DwlIpcOutput *ipc_output; + Monitor *monitor = wlr_output_from_resource(output)->data; + struct wl_resource *output_resource = wl_resource_create(client, &zdwl_ipc_output_v2_interface, wl_resource_get_version(resource), id); + if (!output_resource) + return; - ipc_output = ecalloc(1, sizeof(*ipc_output)); - ipc_output->resource = output_resource; - ipc_output->monitor = monitor; - wl_resource_set_implementation(output_resource, &dwl_output_implementation, - ipc_output, dwl_ipc_output_destroy); - wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); - dwl_ipc_output_printstatus_to(ipc_output); + ipc_output = ecalloc(1, sizeof(*ipc_output)); + ipc_output->resource = output_resource; + ipc_output->mon = monitor; + wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy); + wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); + dwl_ipc_output_printstatus_to(ipc_output); } -void dwl_ipc_manager_release(struct wl_client *client, - struct wl_resource *resource) { - wl_resource_destroy(resource); +void +dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); } -// 在外部ipc客户端结束的时候会发出销毁请求,比如kill掉waybar,就会销毁waybar绑定的ipc_output -static void dwl_ipc_output_destroy(struct wl_resource *resource) { - DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource); - wl_list_remove(&ipc_output->link); - free(ipc_output); +static void +dwl_ipc_output_destroy(struct wl_resource *resource) +{ + DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource); + wl_list_remove(&ipc_output->link); + free(ipc_output); } -void dwl_ipc_output_printstatus(Monitor *monitor) { - DwlIpcOutput *ipc_output; - wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) - dwl_ipc_output_printstatus_to(ipc_output); +void +dwl_ipc_output_printstatus(Monitor *monitor) +{ + DwlIpcOutput *ipc_output; + wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) + dwl_ipc_output_printstatus_to(ipc_output); } void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { - Monitor *monitor = ipc_output->monitor; + Monitor *monitor = ipc_output->mon; Client *c, *focused; int tagmask, state, numclients, focused_client, tag; const char *title, *appid, *symbol; @@ -2879,39 +2886,46 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; zdwl_ipc_output_v2_send_layout( - ipc_output->resource, - monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); + 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); - zdwl_ipc_output_v2_send_frame(ipc_output->resource); + if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { + zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, focused ? focused->isfullscreen : 0); + } + if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + zdwl_ipc_output_v2_send_floating(ipc_output->resource, focused ? focused->isfloating : 0); + } + zdwl_ipc_output_v2_send_frame(ipc_output->resource); } -void dwl_ipc_output_set_client_tags(struct wl_client *client, - struct wl_resource *resource, - uint32_t and_tags, uint32_t xor_tags) { - DwlIpcOutput *ipc_output; - Monitor *monitor; - Client *selected_client; - unsigned int newtags = 0; +void +dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags) +{ + DwlIpcOutput *ipc_output; + Monitor *monitor; + Client *selected_client; + unsigned int newtags = 0; - ipc_output = wl_resource_get_user_data(resource); - if (!ipc_output) - return; + ipc_output = wl_resource_get_user_data(resource); + if (!ipc_output) + return; - monitor = ipc_output->monitor; - selected_client = focustop(monitor); - if (!selected_client) - return; + monitor = ipc_output->mon; + selected_client = focustop(monitor); + if (!selected_client) + return; - newtags = (selected_client->tags & and_tags) ^ xor_tags; - if (!newtags) - return; + newtags = (selected_client->tags & and_tags) ^ xor_tags; + if (!newtags) + return; - selected_client->tags = newtags; - focusclient(focustop(selmon), 1); - arrange(selmon, true); - printstatus(); + selected_client->tags = newtags; + if (selmon == monitor) + focusclient(focustop(monitor), 1); + arrange(selmon,false); + printstatus(); } void dwl_ipc_output_set_layout(struct wl_client *client, @@ -2923,7 +2937,7 @@ void dwl_ipc_output_set_layout(struct wl_client *client, if (!ipc_output) return; - monitor = ipc_output->monitor; + monitor = ipc_output->mon; if (index >= LENGTH(layouts)) index = 0; @@ -2932,32 +2946,25 @@ void dwl_ipc_output_set_layout(struct wl_client *client, printstatus(); } -void dwl_ipc_output_set_tags(struct wl_client *client, - struct wl_resource *resource, uint32_t tagmask, - uint32_t toggle_tagset) { - DwlIpcOutput *ipc_output; - Monitor *monitor; - unsigned int newtags = tagmask & TAGMASK; +void +dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset) +{ + DwlIpcOutput *ipc_output; + Monitor *monitor; + unsigned int newtags = tagmask & TAGMASK; - ipc_output = wl_resource_get_user_data(resource); - if (!ipc_output) - return; - monitor = ipc_output->monitor; + ipc_output = wl_resource_get_user_data(resource); + if (!ipc_output) + return; + monitor = ipc_output->mon; - if (!newtags || newtags == monitor->tagset[monitor->seltags]) - return; - if (toggle_tagset) - monitor->seltags ^= 1; - - monitor->tagset[monitor->seltags] = newtags; - focusclient(focustop(monitor), 1); - arrange(monitor, true); - printstatus(); + view_in_mon(&(Arg){.ui = newtags}, true,monitor); } -void dwl_ipc_output_release(struct wl_client *client, - struct wl_resource *resource) { - wl_resource_destroy(resource); +void +dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); } void focusclient(Client *c, int lift) { @@ -5059,7 +5066,7 @@ void setup(void) { input_relay = calloc(1, sizeof(*input_relay)); dwl_input_method_relay_init(input_relay); #endif - wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 1, NULL, + wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL, dwl_ipc_manager_bind); // 创建顶层管理句柄 @@ -6115,39 +6122,43 @@ urgent(struct wl_listener *listener, void *data) { void bind_to_view(const Arg *arg) { view(arg, true); } -void view(const Arg *arg, bool want_animation) { +void view_in_mon(const Arg *arg, bool want_animation, Monitor *m) { size_t i, tmptag; - if (!selmon || (arg->ui != ~0 && selmon->isoverview)) { + if (!m || (arg->ui != ~0 && m->isoverview)) { return; } - if ((selmon->tagset[selmon->seltags] & arg->ui & TAGMASK) != 0) { + if ((m->tagset[m->seltags] & arg->ui & TAGMASK) != 0) { want_animation = false; } - selmon->seltags ^= 1; /* toggle sel tagset */ + m->seltags ^= 1; /* toggle sel tagset */ if (arg->ui & TAGMASK) { - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - selmon->pertag->prevtag = selmon->pertag->curtag; + m->tagset[m->seltags] = arg->ui & TAGMASK; + m->pertag->prevtag = m->pertag->curtag; if (arg->ui == ~0) - selmon->pertag->curtag = 0; + m->pertag->curtag = 0; else { for (i = 0; !(arg->ui & 1 << i); i++) ; - selmon->pertag->curtag = i + 1; + m->pertag->curtag = i + 1; } } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; + tmptag = m->pertag->prevtag; + m->pertag->prevtag = m->pertag->curtag; + m->pertag->curtag = tmptag; } - focusclient(focustop(selmon), 1); - arrange(selmon, want_animation); + focusclient(focustop(m), 1); + arrange(m, want_animation); printstatus(); } +void view(const Arg *arg, bool want_animation) { + view_in_mon(arg, want_animation, selmon); +} + void viewtoleft(const Arg *arg) { size_t tmptag; unsigned int target = selmon->tagset[selmon->seltags];