From d5b6075b5941a31f547b7695faeb757176746954 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 20 Jun 2025 13:46:37 +0800 Subject: [PATCH] project: change project struct --- src/config/{preset_config.h => preset.h} | 0 src/ext-protocol/all.h | 3 + src/ext-protocol/dwl-ipc.h | 267 +++++++++++++ src/ext-protocol/foreign-toplevel.h | 105 +++++ .../ime.h => ext-protocol/text-input.h} | 0 src/maomao.c | 378 +----------------- 6 files changed, 380 insertions(+), 373 deletions(-) rename src/config/{preset_config.h => preset.h} (100%) create mode 100644 src/ext-protocol/all.h create mode 100644 src/ext-protocol/dwl-ipc.h create mode 100644 src/ext-protocol/foreign-toplevel.h rename src/{text_input/ime.h => ext-protocol/text-input.h} (100%) diff --git a/src/config/preset_config.h b/src/config/preset.h similarity index 100% rename from src/config/preset_config.h rename to src/config/preset.h diff --git a/src/ext-protocol/all.h b/src/ext-protocol/all.h new file mode 100644 index 0000000..c657e0d --- /dev/null +++ b/src/ext-protocol/all.h @@ -0,0 +1,3 @@ +#include "dwl-ipc.h" +#include "foreign-toplevel.h" +#include "text-input.h" \ No newline at end of file diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h new file mode 100644 index 0000000..d05c72c --- /dev/null +++ b/src/ext-protocol/dwl-ipc.h @@ -0,0 +1,267 @@ +#include "dwl-ipc-unstable-v2-protocol.h" + +static void dwl_ipc_manager_bind(struct wl_client *client, void *data, + unsigned int version, unsigned int id); +static void dwl_ipc_manager_destroy(struct wl_resource *resource); +static void dwl_ipc_manager_get_output(struct wl_client *client, + struct wl_resource *resource, + unsigned int id, + struct wl_resource *output); +static void dwl_ipc_manager_release(struct wl_client *client, + struct wl_resource *resource); +static void dwl_ipc_output_destroy(struct wl_resource *resource); +static void dwl_ipc_output_printstatus(Monitor *monitor); +static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output); +static void dwl_ipc_output_set_client_tags(struct wl_client *client, + struct wl_resource *resource, + unsigned int and_tags, + unsigned int xor_tags); +static void dwl_ipc_output_set_layout(struct wl_client *client, + struct wl_resource *resource, + unsigned int index); +static void dwl_ipc_output_set_tags(struct wl_client *client, + struct wl_resource *resource, + unsigned int tagmask, + unsigned int toggle_tagset); +static void dwl_ipc_output_quit(struct wl_client *client, + struct wl_resource *resource); +static void dwl_ipc_output_dispatch(struct wl_client *client, + struct wl_resource *resource, + const char *dispatch, const char *arg1, + const char *arg2, const char *arg3, + const char *arg4, const char *arg5); +static void dwl_ipc_output_release(struct wl_client *client, + struct wl_resource *resource); + +/* global event handlers */ +static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = { + .release = dwl_ipc_manager_release, + .get_output = dwl_ipc_manager_get_output}; +static struct zdwl_ipc_output_v2_interface dwl_output_implementation = { + .release = dwl_ipc_output_release, + .set_tags = dwl_ipc_output_set_tags, + .quit = dwl_ipc_output_quit, + .dispatch = dwl_ipc_output_dispatch, + .set_layout = dwl_ipc_output_set_layout, + .set_client_tags = dwl_ipc_output_set_client_tags}; + +void dwl_ipc_manager_bind(struct wl_client *client, void *data, + unsigned int version, unsigned int 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)); + + 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_get_output(struct wl_client *client, + struct wl_resource *resource, unsigned int id, + struct wl_resource *output) { + DwlIpcOutput *ipc_output; + struct wlr_output *op = wlr_output_from_resource(output); + if (!op) + return; + Monitor *monitor = op->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->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); +} + +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_to(DwlIpcOutput *ipc_output) { + Monitor *monitor = ipc_output->mon; + Client *c, *focused; + int tagmask, state, numclients, focused_client, tag; + const char *title, *appid, *symbol; + focused = focustop(monitor); + zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); + + for (tag = 0; tag < LENGTH(tags); tag++) { + numclients = state = focused_client = 0; + tagmask = 1 << tag; + if ((tagmask & monitor->tagset[monitor->seltags]) != 0) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; + wl_list_for_each(c, &clients, link) { + if (c->mon != monitor) + continue; + if (!(c->tags & tagmask)) + continue; + if (c == focused) + focused_client = 1; + if (c->isurgent) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; + numclients++; + } + zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, + numclients, focused_client); + } + + title = focused ? client_get_title(focused) : ""; + appid = focused ? client_get_appid(focused) : ""; + 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_title(ipc_output->resource, title ? title : broken); + zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); + zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { + zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, + focused ? focused->isfullscreen : 0); + } + if (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); + } + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + zdwl_ipc_output_v2_send_x(ipc_output->resource, + focused ? focused->geom.x : 0); + } + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + zdwl_ipc_output_v2_send_y(ipc_output->resource, + focused ? focused->geom.y : 0); + } + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + zdwl_ipc_output_v2_send_width(ipc_output->resource, + focused ? focused->geom.width : 0); + } + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + zdwl_ipc_output_v2_send_height(ipc_output->resource, + focused ? focused->geom.height : 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, + unsigned int and_tags, + unsigned int 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; + + monitor = ipc_output->mon; + selected_client = focustop(monitor); + if (!selected_client) + return; + + newtags = (selected_client->tags & and_tags) ^ xor_tags; + if (!newtags) + return; + + 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, + struct wl_resource *resource, + unsigned int index) { + DwlIpcOutput *ipc_output; + Monitor *monitor; + + ipc_output = wl_resource_get_user_data(resource); + if (!ipc_output) + return; + + monitor = ipc_output->mon; + if (index >= LENGTH(layouts)) + index = 0; + + monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; + arrange(monitor, false); + printstatus(); +} + +void dwl_ipc_output_set_tags(struct wl_client *client, + struct wl_resource *resource, unsigned int tagmask, + unsigned int 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->mon; + + view_in_mon(&(Arg){.ui = newtags}, true, monitor); +} + +void dwl_ipc_output_quit(struct wl_client *client, + struct wl_resource *resource) { + quit(&(Arg){0}); +} + +void dwl_ipc_output_dispatch(struct wl_client *client, + struct wl_resource *resource, const char *dispatch, + const char *arg1, const char *arg2, + const char *arg3, const char *arg4, + const char *arg5) { + + void (*func)(const Arg *); + Arg arg; + func = parse_func_name((char *)dispatch, &arg, (char *)arg1, (char *)arg2, + (char *)arg3, (char *)arg4, (char *)arg5); + if (func) { + func(&arg); + } +} + +void dwl_ipc_output_release(struct wl_client *client, + struct wl_resource *resource) { + wl_resource_destroy(resource); +} diff --git a/src/ext-protocol/foreign-toplevel.h b/src/ext-protocol/foreign-toplevel.h new file mode 100644 index 0000000..d2ee5ef --- /dev/null +++ b/src/ext-protocol/foreign-toplevel.h @@ -0,0 +1,105 @@ +#include + +static struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; + +static void handle_foreign_activate_request(struct wl_listener *listener, + void *data); +static void handle_foreign_fullscreen_request(struct wl_listener *listener, + void *data); +static void handle_foreign_close_request(struct wl_listener *listener, + void *data); +static void handle_foreign_destroy(struct wl_listener *listener, void *data); + +void handle_foreign_activate_request(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_activate_request); + unsigned int target; + + if (c && c->swallowing) + return; + + if (c && !c->isminied && c == selmon->sel) { + set_minized(c); + return; + } + + if (c->isminied) { + c->is_in_scratchpad = 0; + c->isnamedscratchpand = 0; + c->is_scratchpad_show = 0; + setborder_color(c); + show_hide_client(c); + return; + } + + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); +} + +void handle_foreign_fullscreen_request(struct wl_listener *listener, + void *data) { + return; +} + +void handle_foreign_close_request(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_close_request); + if (c) { + pending_kill_client(c); + } +} + +void handle_foreign_destroy(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_destroy); + if (c) { + wl_list_remove(&c->foreign_activate_request.link); + wl_list_remove(&c->foreign_fullscreen_request.link); + wl_list_remove(&c->foreign_close_request.link); + wl_list_remove(&c->foreign_destroy.link); + } +} + +void remove_foreign_topleve(Client *c) { + wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); + c->foreign_toplevel = NULL; +} + +void add_foreign_toplevel(Client *c) { + if (!c || !c->mon || !c->mon->wlr_output || !c->mon->wlr_output->enabled) + return; + + c->foreign_toplevel = + wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_manager); + // 监听来自外部对于窗口的事件请求 + if (c->foreign_toplevel) { + LISTEN(&(c->foreign_toplevel->events.request_activate), + &c->foreign_activate_request, handle_foreign_activate_request); + LISTEN(&(c->foreign_toplevel->events.request_fullscreen), + &c->foreign_fullscreen_request, + handle_foreign_fullscreen_request); + LISTEN(&(c->foreign_toplevel->events.request_close), + &c->foreign_close_request, handle_foreign_close_request); + LISTEN(&(c->foreign_toplevel->events.destroy), &c->foreign_destroy, + handle_foreign_destroy); + // 设置外部顶层句柄的id为应用的id + const char *appid; + appid = client_get_appid(c); + if (appid) + wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel, + appid); + // 设置外部顶层句柄的title为应用的title + const char *title; + title = client_get_title(c); + if (title) + wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, + title); + // 设置外部顶层句柄的显示监视器为当前监视器 + wlr_foreign_toplevel_handle_v1_output_enter(c->foreign_toplevel, + c->mon->wlr_output); + } +} + +void reset_foreign_tolevel(Client *c) { + remove_foreign_topleve(c); + add_foreign_toplevel(c); +} diff --git a/src/text_input/ime.h b/src/ext-protocol/text-input.h similarity index 100% rename from src/text_input/ime.h rename to src/ext-protocol/text-input.h diff --git a/src/maomao.c b/src/maomao.c index 9ae78a5..66374d6 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -82,10 +82,7 @@ #include #include #endif - #include "common/util.h" -#include "dwl-ipc-unstable-v2-protocol.h" -#include /* macros */ #define MAX(A, B) ((A) > (B) ? (A) : (B)) @@ -197,6 +194,7 @@ struct dwl_animation { typedef struct Pertag Pertag; typedef struct Monitor Monitor; +struct wlr_foreign_toplevel_handle_v1; typedef struct { float width_scale; @@ -489,38 +487,7 @@ static void destroysessionlock(struct wl_listener *listener, void *data); static void destroykeyboardgroup(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); static void setcursorshape(struct wl_listener *listener, void *data); -static void dwl_ipc_manager_bind(struct wl_client *client, void *data, - unsigned int version, unsigned int id); -static void dwl_ipc_manager_destroy(struct wl_resource *resource); -static void dwl_ipc_manager_get_output(struct wl_client *client, - struct wl_resource *resource, - unsigned int id, - struct wl_resource *output); -static void dwl_ipc_manager_release(struct wl_client *client, - struct wl_resource *resource); -static void dwl_ipc_output_destroy(struct wl_resource *resource); -static void dwl_ipc_output_printstatus(Monitor *monitor); -static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output); -static void dwl_ipc_output_set_client_tags(struct wl_client *client, - struct wl_resource *resource, - unsigned int and_tags, - unsigned int xor_tags); -static void dwl_ipc_output_set_layout(struct wl_client *client, - struct wl_resource *resource, - unsigned int index); -static void dwl_ipc_output_set_tags(struct wl_client *client, - struct wl_resource *resource, - unsigned int tagmask, - unsigned int toggle_tagset); -static void dwl_ipc_output_quit(struct wl_client *client, - struct wl_resource *resource); -static void dwl_ipc_output_dispatch(struct wl_client *client, - struct wl_resource *resource, - const char *dispatch, const char *arg1, - const char *arg2, const char *arg3, - const char *arg4, const char *arg5); -static void dwl_ipc_output_release(struct wl_client *client, - struct wl_resource *resource); + static void focusclient(Client *c, int lift); static void setborder_color(Client *c); @@ -623,14 +590,6 @@ static void show_scratchpad(Client *c); static void show_hide_client(Client *c); static void tag_client(const Arg *arg, Client *target_client); -static void handle_foreign_activate_request(struct wl_listener *listener, - void *data); -static void handle_foreign_fullscreen_request(struct wl_listener *listener, - void *data); -static void handle_foreign_close_request(struct wl_listener *listener, - void *data); -static void handle_foreign_destroy(struct wl_listener *listener, void *data); - static struct wlr_box setclient_coordinate_center(Client *c, struct wlr_box geom, int offsetx, int offsety); @@ -657,6 +616,7 @@ static int hidecursor(void *data); static bool check_hit_no_border(Client *c); static void reset_keyboard_layout(void); static void client_update_oldmonname_record(Client *c, Monitor *m); +static void pending_kill_client(Client *c); #include "data/static_keymap.h" #include "dispatch/dispatch.h" @@ -670,7 +630,6 @@ static void *exclusive_focus; static struct wl_display *dpy; static struct wl_event_loop *event_loop; static struct wlr_relative_pointer_manager_v1 *pointer_manager; -static struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; static struct wlr_backend *backend; static struct wlr_backend *headless_backend; static struct wlr_scene *scene; @@ -746,7 +705,7 @@ static struct { int hotspot_y; } last_cursor; -#include "config/preset_config.h" +#include "config/preset.h" struct Pertag { unsigned int curtag, prevtag; /* current and previous tag */ @@ -757,18 +716,6 @@ struct Pertag { *ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */ }; -/* global event handlers */ -static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = { - .release = dwl_ipc_manager_release, - .get_output = dwl_ipc_manager_get_output}; -static struct zdwl_ipc_output_v2_interface dwl_output_implementation = { - .release = dwl_ipc_output_release, - .set_tags = dwl_ipc_output_set_tags, - .quit = dwl_ipc_output_quit, - .dispatch = dwl_ipc_output_dispatch, - .set_layout = dwl_ipc_output_set_layout, - .set_client_tags = dwl_ipc_output_set_client_tags}; - static struct wl_listener cursor_axis = {.notify = axisnotify}; static struct wl_listener cursor_button = {.notify = buttonpress}; static struct wl_listener cursor_frame = {.notify = cursorframe}; @@ -816,8 +763,8 @@ static struct wlr_xwayland *xwayland; #include "client/client.h" #include "config/parse_config.h" +#include "ext-protocol/all.h" #include "layout/layout.h" -#include "text_input/ime.h" struct dvec2 calculate_animation_curve_at(double t, int type) { struct dvec2 point; @@ -1499,51 +1446,6 @@ void show_scratchpad(Client *c) { setborder_color(c); } -void remove_foreign_topleve(Client *c) { - wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); - c->foreign_toplevel = NULL; -} - -void add_foreign_toplevel(Client *c) { - if (!c || !c->mon || !c->mon->wlr_output || !c->mon->wlr_output->enabled) - return; - - c->foreign_toplevel = - wlr_foreign_toplevel_handle_v1_create(foreign_toplevel_manager); - // 监听来自外部对于窗口的事件请求 - if (c->foreign_toplevel) { - LISTEN(&(c->foreign_toplevel->events.request_activate), - &c->foreign_activate_request, handle_foreign_activate_request); - LISTEN(&(c->foreign_toplevel->events.request_fullscreen), - &c->foreign_fullscreen_request, - handle_foreign_fullscreen_request); - LISTEN(&(c->foreign_toplevel->events.request_close), - &c->foreign_close_request, handle_foreign_close_request); - LISTEN(&(c->foreign_toplevel->events.destroy), &c->foreign_destroy, - handle_foreign_destroy); - // 设置外部顶层句柄的id为应用的id - const char *appid; - appid = client_get_appid(c); - if (appid) - wlr_foreign_toplevel_handle_v1_set_app_id(c->foreign_toplevel, - appid); - // 设置外部顶层句柄的title为应用的title - const char *title; - title = client_get_title(c); - if (title) - wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, - title); - // 设置外部顶层句柄的显示监视器为当前监视器 - wlr_foreign_toplevel_handle_v1_output_enter(c->foreign_toplevel, - c->mon->wlr_output); - } -} - -void reset_foreign_tolevel(Client *c) { - remove_foreign_topleve(c); - add_foreign_toplevel(c); -} - pid_t getparentprocess(pid_t p) { unsigned int v = 0; @@ -3756,227 +3658,6 @@ Monitor *dirtomon(enum wlr_direction dir) { return selmon; } -void dwl_ipc_manager_bind(struct wl_client *client, void *data, - unsigned int version, unsigned int 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)); - - 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_get_output(struct wl_client *client, - struct wl_resource *resource, unsigned int id, - struct wl_resource *output) { - DwlIpcOutput *ipc_output; - struct wlr_output *op = wlr_output_from_resource(output); - if (!op) - return; - Monitor *monitor = op->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->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); -} - -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_to(DwlIpcOutput *ipc_output) { - Monitor *monitor = ipc_output->mon; - Client *c, *focused; - int tagmask, state, numclients, focused_client, tag; - const char *title, *appid, *symbol; - focused = focustop(monitor); - zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); - - for (tag = 0; tag < LENGTH(tags); tag++) { - numclients = state = focused_client = 0; - tagmask = 1 << tag; - if ((tagmask & monitor->tagset[monitor->seltags]) != 0) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; - wl_list_for_each(c, &clients, link) { - if (c->mon != monitor) - continue; - if (!(c->tags & tagmask)) - continue; - if (c == focused) - focused_client = 1; - if (c->isurgent) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; - numclients++; - } - zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, - numclients, focused_client); - } - - title = focused ? client_get_title(focused) : ""; - appid = focused ? client_get_appid(focused) : ""; - 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_title(ipc_output->resource, title ? title : broken); - zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); - zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { - zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, - focused ? focused->isfullscreen : 0); - } - if (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); - } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { - zdwl_ipc_output_v2_send_x(ipc_output->resource, - focused ? focused->geom.x : 0); - } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { - zdwl_ipc_output_v2_send_y(ipc_output->resource, - focused ? focused->geom.y : 0); - } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { - zdwl_ipc_output_v2_send_width(ipc_output->resource, - focused ? focused->geom.width : 0); - } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { - zdwl_ipc_output_v2_send_height(ipc_output->resource, - focused ? focused->geom.height : 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, - unsigned int and_tags, - unsigned int 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; - - monitor = ipc_output->mon; - selected_client = focustop(monitor); - if (!selected_client) - return; - - newtags = (selected_client->tags & and_tags) ^ xor_tags; - if (!newtags) - return; - - 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, - struct wl_resource *resource, - unsigned int index) { - DwlIpcOutput *ipc_output; - Monitor *monitor; - - ipc_output = wl_resource_get_user_data(resource); - if (!ipc_output) - return; - - monitor = ipc_output->mon; - if (index >= LENGTH(layouts)) - index = 0; - - monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; - arrange(monitor, false); - printstatus(); -} - -void dwl_ipc_output_set_tags(struct wl_client *client, - struct wl_resource *resource, unsigned int tagmask, - unsigned int 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->mon; - - view_in_mon(&(Arg){.ui = newtags}, true, monitor); -} - -void dwl_ipc_output_quit(struct wl_client *client, - struct wl_resource *resource) { - quit(&(Arg){0}); -} - -void dwl_ipc_output_dispatch(struct wl_client *client, - struct wl_resource *resource, const char *dispatch, - const char *arg1, const char *arg2, - const char *arg3, const char *arg4, - const char *arg5) { - - void (*func)(const Arg *); - Arg arg; - func = parse_func_name((char *)dispatch, &arg, (char *)arg1, (char *)arg2, - (char *)arg3, (char *)arg4, (char *)arg5); - if (func) { - func(&arg); - } -} - -void dwl_ipc_output_release(struct wl_client *client, - struct wl_resource *resource) { - wl_resource_destroy(resource); -} - void focusclient(Client *c, int lift) { struct wlr_surface *old_keyboard_focus_surface = seat->keyboard_state.focused_surface; @@ -6256,55 +5937,6 @@ void show_hide_client(Client *c) { wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } -void handle_foreign_activate_request(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, foreign_activate_request); - unsigned int target; - - if (c && c->swallowing) - return; - - if (c && !c->isminied && c == selmon->sel) { - set_minized(c); - return; - } - - if (c->isminied) { - c->is_in_scratchpad = 0; - c->isnamedscratchpand = 0; - c->is_scratchpad_show = 0; - setborder_color(c); - show_hide_client(c); - return; - } - - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target}, true); - focusclient(c, 1); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); -} - -void handle_foreign_fullscreen_request(struct wl_listener *listener, - void *data) { - return; -} - -void handle_foreign_close_request(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, foreign_close_request); - if (c) { - pending_kill_client(c); - } -} - -void handle_foreign_destroy(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, foreign_destroy); - if (c) { - wl_list_remove(&c->foreign_activate_request.link); - wl_list_remove(&c->foreign_fullscreen_request.link); - wl_list_remove(&c->foreign_close_request.link); - wl_list_remove(&c->foreign_destroy.link); - } -} - void create_output(struct wlr_backend *backend, void *data) { bool *done = data; if (*done) {