diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..914c1a4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: LLVM +UseTab: Always +TabWidth: 4 +IndentWidth: 4 diff --git a/src/client/client.h b/src/client/client.h index 4c4e783..7c3ef4d 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -8,405 +8,413 @@ /* Leave these functions first; they're used in the others */ 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) { #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; + 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; + 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) { + 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) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->class ? c->surface.xwayland->class : "broken"; + if (client_is_x11(c)) + return c->surface.xwayland->class ? c->surface.xwayland->class + : "broken"; #endif - return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id - : "broken"; + return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id + : "broken"; } static inline int client_get_pid(Client *c) { - pid_t pid; + pid_t pid; #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->pid; + if (client_is_x11(c)) + return c->surface.xwayland->pid; #endif - wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); - return pid; + wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); + return pid; } static inline void client_get_clip(Client *c, struct wlr_box *clip) { - *clip = (struct wlr_box){ - .x = 0, - .y = 0, - .width = c->geom.width - c->bw, - .height = c->geom.height - c->bw, - }; + *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 - clip->x = c->surface.xdg->geometry.x; - clip->y = c->surface.xdg->geometry.y; + clip->x = c->surface.xdg->geometry.x; + clip->y = c->surface.xdg->geometry.y; } 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 - *geom = c->surface.xdg->geometry; + *geom = c->surface.xdg->geometry; } static inline Client *client_get_parent(Client *c) { - Client *p = NULL; + 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) { #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) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->title ? c->surface.xwayland->title : "broken"; + if (client_is_x11(c)) + return c->surface.xwayland->title ? c->surface.xwayland->title + : "broken"; #endif - return c->surface.xdg->toplevel->title ? c->surface.xdg->toplevel->title - : "broken"; + return c->surface.xdg->toplevel->title ? c->surface.xdg->toplevel->title + : "broken"; } static inline int client_is_float_type(Client *c) { - struct wlr_xdg_toplevel *toplevel; - struct wlr_xdg_toplevel_state state; + 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; - 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; + if (surface->modal) + return 1; - if (wlr_xwayland_surface_has_window_type( - surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DIALOG) || - wlr_xwayland_surface_has_window_type( - surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH) || - wlr_xwayland_surface_has_window_type( - surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLBAR) || - wlr_xwayland_surface_has_window_type( - surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY)) { - return 1; - } + if (wlr_xwayland_surface_has_window_type( + surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DIALOG) || + wlr_xwayland_surface_has_window_type( + surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH) || + wlr_xwayland_surface_has_window_type( + surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLBAR) || + wlr_xwayland_surface_has_window_type( + surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY)) { + 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; + /* 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}; + 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) { #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); + 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_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); + 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) { #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 void client_set_scale(struct wlr_surface *s, float scale) { - wlr_fractional_scale_v1_notify_scale(s, scale); - wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale)); + wlr_fractional_scale_v1_notify_scale(s, scale); + wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale)); } static inline uint32_t client_set_size(Client *c, uint32_t width, - uint32_t height) { + uint32_t height) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw, - c->geom.y + c->bw, width, height); - return 0; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw, + c->geom.y + c->bw, 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) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_set_maximized( - c->surface.xwayland, edges != WLR_EDGE_NONE, edges != WLR_EDGE_NONE); - return; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_set_maximized(c->surface.xwayland, + edges != WLR_EDGE_NONE, + edges != WLR_EDGE_NONE); + 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); - } - 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); + } + wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel, + edges != WLR_EDGE_NONE); } 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_should_ignore_focus(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) { - struct wlr_xwayland_surface *surface = c->surface.xwayland; - // 处理不需要焦点的窗口类型 - const uint32_t no_focus_types[] = { - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_COMBO, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DND, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DROPDOWN_MENU, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_MENU, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_NOTIFICATION, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_POPUP_MENU, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DESKTOP, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLTIP, - WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY}; - // 检查窗口类型是否需要禁止焦点 - for (size_t i = 0; i < sizeof(no_focus_types) / sizeof(no_focus_types[0]); - ++i) { - if (wlr_xwayland_surface_has_window_type(surface, no_focus_types[i])) { - return 1; - } - } - } + if (client_is_x11(c)) { + struct wlr_xwayland_surface *surface = c->surface.xwayland; + // 处理不需要焦点的窗口类型 + const uint32_t no_focus_types[] = { + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_COMBO, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DND, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DROPDOWN_MENU, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_MENU, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_NOTIFICATION, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_POPUP_MENU, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DESKTOP, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLTIP, + WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY}; + // 检查窗口类型是否需要禁止焦点 + for (size_t i = 0; + i < sizeof(no_focus_types) / sizeof(no_focus_types[0]); ++i) { + if (wlr_xwayland_surface_has_window_type(surface, + no_focus_types[i])) { + return 1; + } + } + } #endif - return 0; + return 0; } static inline int client_wants_focus(Client *c) { #ifdef XWAYLAND - return client_is_unmanaged(c) && - wlr_xwayland_surface_override_redirect_wants_focus( - c->surface.xwayland) && - wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) != - WLR_ICCCM_INPUT_MODEL_NONE; + return client_is_unmanaged(c) && + wlr_xwayland_surface_override_redirect_wants_focus( + c->surface.xwayland) && + wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) != + WLR_ICCCM_INPUT_MODEL_NONE; #endif - return 0; + return 0; } 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/src/common/mem.c b/src/common/mem.c index ac9296a..e464cd0 100644 --- a/src/common/mem.c +++ b/src/common/mem.c @@ -7,34 +7,34 @@ #include static void die_if_null(void *ptr) { - if (!ptr) { - perror("Failed to allocate memory"); - exit(EXIT_FAILURE); - } + if (!ptr) { + perror("Failed to allocate memory"); + exit(EXIT_FAILURE); + } } void *xzalloc(size_t size) { - if (!size) { - return NULL; - } - void *ptr = calloc(1, size); - die_if_null(ptr); - return ptr; + if (!size) { + return NULL; + } + void *ptr = calloc(1, size); + die_if_null(ptr); + return ptr; } void *xrealloc(void *ptr, size_t size) { - if (!size) { - free(ptr); - return NULL; - } - ptr = realloc(ptr, size); - die_if_null(ptr); - return ptr; + if (!size) { + free(ptr); + return NULL; + } + ptr = realloc(ptr, size); + die_if_null(ptr); + return ptr; } char *xstrdup(const char *str) { - assert(str); - char *copy = strdup(str); - die_if_null(copy); - return copy; + assert(str); + char *copy = strdup(str); + die_if_null(copy); + return copy; } diff --git a/src/common/mem.h b/src/common/mem.h index 08ac50d..1163c1e 100644 --- a/src/common/mem.h +++ b/src/common/mem.h @@ -47,18 +47,17 @@ char *xstrdup(const char *str); * before assigning the result. */ #define xstrdup_replace(ptr, str) \ - do { \ - free(ptr); \ - (ptr) = xstrdup(str); \ - } while (0) + do { \ + free(ptr); \ + (ptr) = xstrdup(str); \ + } while (0) /* * Frees memory pointed to by and sets to NULL. * Does nothing if is already NULL. */ #define zfree(ptr) \ - do { \ - free(ptr); \ - (ptr) = NULL; \ - } while (0) - + do { \ + free(ptr); \ + (ptr) = NULL; \ + } while (0) diff --git a/src/common/util.c b/src/common/util.c index bf83e3d..b5dd267 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -11,71 +11,63 @@ #include void die(const char *fmt, ...) { - va_list ap; + 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 *p; - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; } int fd_set_nonblock(int fd) { - int flags = fcntl(fd, F_GETFL); - if (flags < 0) { - perror("fcntl(F_GETFL):"); - return -1; - } - if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { - perror("fcntl(F_SETFL):"); - return -1; - } + int flags = fcntl(fd, F_GETFL); + if (flags < 0) { + perror("fcntl(F_GETFL):"); + return -1; + } + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + perror("fcntl(F_SETFL):"); + return -1; + } - return 0; + return 0; } int regex_match(const char *pattern, const char *str) { - int errnum; - PCRE2_SIZE erroffset; - pcre2_code *re = pcre2_compile( - (PCRE2_SPTR)pattern, - PCRE2_ZERO_TERMINATED, - PCRE2_UTF, // 启用 UTF-8 支持 - &errnum, &erroffset, NULL - ); - if (!re) { - PCRE2_UCHAR errbuf[256]; - pcre2_get_error_message(errnum, errbuf, sizeof(errbuf)); - fprintf(stderr, "PCRE2 error: %s at offset %zu\n", errbuf, erroffset); - return 0; - } + int errnum; + PCRE2_SIZE erroffset; + pcre2_code *re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, + PCRE2_UTF, // 启用 UTF-8 支持 + &errnum, &erroffset, NULL); + if (!re) { + PCRE2_UCHAR errbuf[256]; + pcre2_get_error_message(errnum, errbuf, sizeof(errbuf)); + fprintf(stderr, "PCRE2 error: %s at offset %zu\n", errbuf, erroffset); + return 0; + } - pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL); - int ret = pcre2_match( - re, - (PCRE2_SPTR)str, - strlen(str), - 0, 0, - match_data, - NULL - ); + pcre2_match_data *match_data = + pcre2_match_data_create_from_pattern(re, NULL); + int ret = + pcre2_match(re, (PCRE2_SPTR)str, strlen(str), 0, 0, match_data, NULL); - pcre2_match_data_free(match_data); - pcre2_code_free(re); - return ret >= 0; + pcre2_match_data_free(match_data); + pcre2_code_free(re); + return ret >= 0; } diff --git a/src/common/util.h b/src/common/util.h index ff6943e..5807c2f 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -1,6 +1,5 @@ /* See LICENSE.dwm file for copyright and license details. */ - void die(const char *fmt, ...); void *ecalloc(size_t nmemb, size_t size); int fd_set_nonblock(int fd); diff --git a/src/config/parse_config.h b/src/config/parse_config.h index d4b4e3a..a59952e 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -10,218 +10,219 @@ enum { NUM_TYPE_MINUS, NUM_TYPE_PLUS, NUM_TYPE_DEFAULT }; 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 { - const char *id; - const char *title; - unsigned int tags; - int isfloating; - int isfullscreen; - float scroller_proportion; - const char *animation_type_open; - const char *animation_type_close; - int isnoborder; - int isopensilent; - int isopenscratchpad; - int isunglobal; - int isglobal; - int isoverlay; - int monitor; - int offsetx; - int offsety; - int width; - int height; - int nofadein; - int nofadeout; - int no_force_center; - int isterm; - int noswallow; - int scratchpad_width; - int scratchpad_height; - uint32_t passmod; - xkb_keysym_t keysym; - KeyBinding globalkeybinding; + const char *id; + const char *title; + unsigned int tags; + int isfloating; + int isfullscreen; + float scroller_proportion; + const char *animation_type_open; + const char *animation_type_close; + int isnoborder; + int isopensilent; + int isopenscratchpad; + int isunglobal; + int isglobal; + int isoverlay; + int monitor; + int offsetx; + int offsety; + int width; + int height; + int nofadein; + int nofadeout; + int no_force_center; + int isterm; + int noswallow; + int scratchpad_width; + int scratchpad_height; + uint32_t passmod; + xkb_keysym_t keysym; + KeyBinding globalkeybinding; } ConfigWinRule; typedef struct { - const char *name; // 显示器名称 - float mfact; // 主区域比例 - int nmaster; // 主区域窗口数量 - const char *layout; // 布局名称(字符串) - int rr; // 旋转和翻转(假设为整数) - float scale; // 显示器缩放比例 - int x, y; // 显示器位置 - int isterm; - int noswallow; + const char *name; // 显示器名称 + float mfact; // 主区域比例 + int nmaster; // 主区域窗口数量 + const char *layout; // 布局名称(字符串) + int rr; // 旋转和翻转(假设为整数) + float scale; // 显示器缩放比例 + int x, y; // 显示器位置 + int isterm; + int noswallow; } ConfigMonitorRule; // 定义一个宏来简化默认按键绑定的添加 #define CHVT(n) \ - { \ - WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT, XKB_KEY_XF86Switch_VT_##n, chvt, { \ - .ui = (n) \ - } \ - } + { \ + WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT, XKB_KEY_XF86Switch_VT_##n, chvt, \ + { \ + .ui = (n) \ + } \ + } // 默认的按键绑定数组 -KeyBinding default_key_bindings[] = {CHVT(1), CHVT(2), CHVT(3), CHVT(4), - CHVT(5), CHVT(6), CHVT(7), CHVT(8), - CHVT(9), CHVT(10), CHVT(11), CHVT(12)}; +KeyBinding default_key_bindings[] = {CHVT(1), CHVT(2), CHVT(3), CHVT(4), + CHVT(5), CHVT(6), CHVT(7), CHVT(8), + CHVT(9), CHVT(10), CHVT(11), CHVT(12)}; 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 { - unsigned int mod; - unsigned int motion; - unsigned int fingers_count; - void (*func)(const Arg *); - Arg arg; + unsigned int mod; + unsigned int motion; + unsigned int fingers_count; + void (*func)(const Arg *); + Arg arg; } GestureBinding; typedef struct { - int id; // 标签ID (1-9) - char *layout_name; // 布局名称 - int no_render_border; + int id; // 标签ID (1-9) + char *layout_name; // 布局名称 + int no_render_border; } ConfigTagRule; typedef struct { - int animations; - char animation_type_open[10]; - char animation_type_close[10]; - int animation_fade_in; - int animation_fade_out; - int tag_animation_direction; - float zoom_initial_ratio; - float fadein_begin_opacity; - float fadeout_begin_opacity; - uint32_t animation_duration_move; - uint32_t animation_duration_open; - uint32_t animation_duration_tag; - uint32_t animation_duration_close; - double animation_curve_move[4]; - double animation_curve_open[4]; - double animation_curve_tag[4]; - double animation_curve_close[4]; + int animations; + char animation_type_open[10]; + char animation_type_close[10]; + int animation_fade_in; + int animation_fade_out; + int tag_animation_direction; + float zoom_initial_ratio; + float fadein_begin_opacity; + float fadeout_begin_opacity; + uint32_t animation_duration_move; + uint32_t animation_duration_open; + uint32_t animation_duration_tag; + uint32_t animation_duration_close; + double animation_curve_move[4]; + double animation_curve_open[4]; + double animation_curve_tag[4]; + double animation_curve_close[4]; - int scroller_structs; - float scroller_default_proportion; - float scroller_default_proportion_single; - int scroller_focus_center; - int scroller_prefer_center; - int focus_cross_monitor; - int focus_cross_tag; - int no_border_when_single; - int snap_distance; - int enable_floating_snap; - int drag_tile_to_tile; - unsigned int swipe_min_threshold; - float *scroller_proportion_preset; - int scroller_proportion_preset_count; + int scroller_structs; + float scroller_default_proportion; + float scroller_default_proportion_single; + int scroller_focus_center; + int scroller_prefer_center; + int focus_cross_monitor; + int focus_cross_tag; + int no_border_when_single; + int snap_distance; + int enable_floating_snap; + int drag_tile_to_tile; + unsigned int swipe_min_threshold; + float *scroller_proportion_preset; + int scroller_proportion_preset_count; - char **circle_layout; - int circle_layout_count; + char **circle_layout; + int circle_layout_count; - unsigned int new_is_master; - float default_mfact; - float default_smfact; - unsigned int default_nmaster; + unsigned int new_is_master; + float default_mfact; + float default_smfact; + unsigned int default_nmaster; - unsigned int hotarea_size; - unsigned int enable_hotarea; - unsigned int ov_tab_mode; - int overviewgappi; - int overviewgappo; - unsigned int cursor_hide_timeout; + unsigned int hotarea_size; + unsigned int enable_hotarea; + unsigned int ov_tab_mode; + int overviewgappi; + int overviewgappo; + unsigned int cursor_hide_timeout; - unsigned int axis_bind_apply_timeout; - unsigned int focus_on_activate; - int bypass_surface_visibility; - int sloppyfocus; - int warpcursor; + unsigned int axis_bind_apply_timeout; + unsigned int focus_on_activate; + int bypass_surface_visibility; + int sloppyfocus; + int warpcursor; - /* keyboard */ - int repeat_rate; - int repeat_delay; - unsigned int numlockon; + /* keyboard */ + int repeat_rate; + int repeat_delay; + unsigned int numlockon; - /* Trackpad */ - int tap_to_click; - int tap_and_drag; - int drag_lock; - int mouse_natural_scrolling; - int trackpad_natural_scrolling; - int disable_while_typing; - int left_handed; - int middle_button_emulation; - unsigned int accel_profile; - double accel_speed; + /* Trackpad */ + int tap_to_click; + int tap_and_drag; + int drag_lock; + int mouse_natural_scrolling; + int trackpad_natural_scrolling; + int disable_while_typing; + int left_handed; + int middle_button_emulation; + unsigned int accel_profile; + double accel_speed; - 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]; - float overlaycolor[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]; + float overlaycolor[4]; - char autostart[3][256]; + char autostart[3][256]; - ConfigTagRule *tag_rules; // 动态数组 - int tag_rules_count; // 数量 + ConfigTagRule *tag_rules; // 动态数组 + int tag_rules_count; // 数量 - 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; - GestureBinding *gesture_bindings; - int gesture_bindings_count; + GestureBinding *gesture_bindings; + int gesture_bindings_count; - char **exec; - int exec_count; + char **exec; + int exec_count; - char **exec_once; - int exec_once_count; + char **exec_once; + int exec_once_count; - char *cursor_theme; - unsigned int cursor_size; + char *cursor_theme; + unsigned int cursor_size; - int single_scratchpad; - int xwayland_persistence; + int single_scratchpad; + int xwayland_persistence; } Config; @@ -232,1900 +233,1927 @@ void parse_config_file(Config *config, const char *file_path); // Helper function to trim whitespace from start and end of a string void trim_whitespace(char *str) { - if (str == NULL || *str == '\0') - return; + if (str == NULL || *str == '\0') + return; - // Trim leading space - char *start = str; - while (isspace((unsigned char)*start)) { - start++; - } + // Trim leading space + char *start = str; + while (isspace((unsigned char)*start)) { + start++; + } - // Trim trailing space - char *end = str + strlen(str) - 1; - while (end > start && isspace((unsigned char)*end)) { - end--; - } + // Trim trailing space + char *end = str + strlen(str) - 1; + while (end > start && isspace((unsigned char)*end)) { + end--; + } - // Null-terminate the trimmed string - *(end + 1) = '\0'; + // Null-terminate the trimmed string + *(end + 1) = '\0'; - // Move the trimmed part to the beginning if needed - if (start != str) { - memmove(str, start, end - start + 2); // +2 to include null terminator - } + // Move the trimmed part to the beginning if needed + if (start != str) { + memmove(str, start, end - start + 2); // +2 to include null terminator + } } int parse_double_array(const char *input, double *output, int max_count) { - char *dup = strdup(input); // 复制一份用于修改 - char *token; - int count = 0; + char *dup = strdup(input); // 复制一份用于修改 + char *token; + int count = 0; - token = strtok(dup, ","); - while (token != NULL && count < max_count) { - trim_whitespace(token); // 对每一个分割后的 token 去除前后空格 - char *endptr; - double val = strtod(token, &endptr); - if (endptr == token || *endptr != '\0') { - fprintf(stderr, "Error: Invalid number in array: %s\n", token); - free(dup); - return -1; // 解析失败 - } - output[count++] = val; - token = strtok(NULL, ","); - } + token = strtok(dup, ","); + while (token != NULL && count < max_count) { + trim_whitespace(token); // 对每一个分割后的 token 去除前后空格 + char *endptr; + double val = strtod(token, &endptr); + if (endptr == token || *endptr != '\0') { + fprintf(stderr, "Error: Invalid number in array: %s\n", token); + free(dup); + return -1; // 解析失败 + } + output[count++] = val; + token = strtok(NULL, ","); + } - free(dup); - return count; + free(dup); + return count; } // 清理字符串中的不可见字符(包括 \r, \n, 空格等) char *sanitize_string(char *str) { - // 去除首部不可见字符 - while (*str != '\0' && !isprint((unsigned char)*str)) - str++; - // 去除尾部不可见字符 - char *end = str + strlen(str) - 1; - while (end > str && !isprint((unsigned char)*end)) - end--; - *(end + 1) = '\0'; - return str; + // 去除首部不可见字符 + while (*str != '\0' && !isprint((unsigned char)*str)) + str++; + // 去除尾部不可见字符 + char *end = str + strlen(str) - 1; + while (end > str && !isprint((unsigned char)*end)) + end--; + *(end + 1) = '\0'; + return str; } int parse_circle_direction(const char *str) { - // 将输入字符串转换为小写 - char lowerStr[10]; - int i = 0; - while (str[i] && i < 9) { - lowerStr[i] = tolower(str[i]); - i++; - } - lowerStr[i] = '\0'; + // 将输入字符串转换为小写 + char lowerStr[10]; + int i = 0; + while (str[i] && i < 9) { + lowerStr[i] = tolower(str[i]); + i++; + } + lowerStr[i] = '\0'; - // 根据转换后的小写字符串返回对应的枚举值 - if (strcmp(lowerStr, "next") == 0) { - return 1; - } else { - return -1; - } + // 根据转换后的小写字符串返回对应的枚举值 + if (strcmp(lowerStr, "next") == 0) { + return 1; + } else { + return -1; + } } int parse_direction(const char *str) { - // 将输入字符串转换为小写 - char lowerStr[10]; - int i = 0; - while (str[i] && i < 9) { - lowerStr[i] = tolower(str[i]); - i++; - } - lowerStr[i] = '\0'; + // 将输入字符串转换为小写 + 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; } xkb_keysym_t normalize_keysym(xkb_keysym_t sym) { - // 首先转换为小写(主要影响字母键) - sym = xkb_keysym_to_lower(sym); + // 首先转换为小写(主要影响字母键) + sym = xkb_keysym_to_lower(sym); - // 将数字小键盘键转换为普通数字键 - switch (sym) { - // 小键盘数字转换 - case XKB_KEY_KP_0: - return XKB_KEY_0; - case XKB_KEY_KP_1: - return XKB_KEY_1; - case XKB_KEY_KP_2: - return XKB_KEY_2; - case XKB_KEY_KP_3: - return XKB_KEY_3; - case XKB_KEY_KP_4: - return XKB_KEY_4; - case XKB_KEY_KP_5: - return XKB_KEY_5; - case XKB_KEY_KP_6: - return XKB_KEY_6; - case XKB_KEY_KP_7: - return XKB_KEY_7; - case XKB_KEY_KP_8: - return XKB_KEY_8; - case XKB_KEY_KP_9: - return XKB_KEY_9; + // 将数字小键盘键转换为普通数字键 + switch (sym) { + // 小键盘数字转换 + case XKB_KEY_KP_0: + return XKB_KEY_0; + case XKB_KEY_KP_1: + return XKB_KEY_1; + case XKB_KEY_KP_2: + return XKB_KEY_2; + case XKB_KEY_KP_3: + return XKB_KEY_3; + case XKB_KEY_KP_4: + return XKB_KEY_4; + case XKB_KEY_KP_5: + return XKB_KEY_5; + case XKB_KEY_KP_6: + return XKB_KEY_6; + case XKB_KEY_KP_7: + return XKB_KEY_7; + case XKB_KEY_KP_8: + return XKB_KEY_8; + case XKB_KEY_KP_9: + return XKB_KEY_9; - // 将 Shift+数字 的符号转换回基础数字 - case XKB_KEY_exclam: - return XKB_KEY_1; // ! - case XKB_KEY_at: - return XKB_KEY_2; // @ - case XKB_KEY_numbersign: - return XKB_KEY_3; // # - case XKB_KEY_dollar: - return XKB_KEY_4; // $ - case XKB_KEY_percent: - return XKB_KEY_5; // % - case XKB_KEY_asciicircum: - return XKB_KEY_6; // ^ - case XKB_KEY_ampersand: - return XKB_KEY_7; // & - case XKB_KEY_asterisk: - return XKB_KEY_8; // * - case XKB_KEY_parenleft: - return XKB_KEY_9; // ( - case XKB_KEY_parenright: - return XKB_KEY_0; // ) + // 将 Shift+数字 的符号转换回基础数字 + case XKB_KEY_exclam: + return XKB_KEY_1; // ! + case XKB_KEY_at: + return XKB_KEY_2; // @ + case XKB_KEY_numbersign: + return XKB_KEY_3; // # + case XKB_KEY_dollar: + return XKB_KEY_4; // $ + case XKB_KEY_percent: + return XKB_KEY_5; // % + case XKB_KEY_asciicircum: + return XKB_KEY_6; // ^ + case XKB_KEY_ampersand: + return XKB_KEY_7; // & + case XKB_KEY_asterisk: + return XKB_KEY_8; // * + case XKB_KEY_parenleft: + return XKB_KEY_9; // ( + case XKB_KEY_parenright: + return XKB_KEY_0; // ) - // 其他布局可能需要的变体(如欧洲键盘) - case XKB_KEY_quotedbl: - return XKB_KEY_2; // " - case XKB_KEY_section: - return XKB_KEY_6; // § - case XKB_KEY_degree: - return XKB_KEY_0; // ° + // 其他布局可能需要的变体(如欧洲键盘) + case XKB_KEY_quotedbl: + return XKB_KEY_2; // " + case XKB_KEY_section: + return XKB_KEY_6; // § + case XKB_KEY_degree: + return XKB_KEY_0; // ° - default: - return sym; - } + default: + return sym; + } } // 辅助函数:检查字符串是否以指定的前缀开头(忽略大小写) static bool starts_with_ignore_case(const char *str, const char *prefix) { - while (*prefix) { - if (tolower(*str) != tolower(*prefix)) { - return false; - } - str++; - prefix++; - } - return true; + while (*prefix) { + if (tolower(*str) != tolower(*prefix)) { + return false; + } + 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) { - return xkb_keysym_from_name(keysym_str, XKB_KEYSYM_NO_FLAGS); + return xkb_keysym_from_name(keysym_str, XKB_KEYSYM_NO_FLAGS); } int parse_button(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 parse_mouse_action(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 convert_hex_to_rgba(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; + 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; } unsigned int parse_num_type(char *str) { - switch (str[0]) { - case '-': - return NUM_TYPE_MINUS; - case '+': - return NUM_TYPE_PLUS; - default: - return NUM_TYPE_DEFAULT; - } + switch (str[0]) { + case '-': + return NUM_TYPE_MINUS; + case '+': + return NUM_TYPE_PLUS; + default: + return NUM_TYPE_DEFAULT; + } } FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, - char *arg_value2, char *arg_value3, char *arg_value4, - char *arg_value5) { + char *arg_value2, char *arg_value3, char *arg_value4, + char *arg_value5) { - FuncType func = NULL; - (*arg).v = NULL; - (*arg).v2 = NULL; - (*arg).v3 = NULL; + FuncType func = NULL; + (*arg).v = NULL; + (*arg).v2 = NULL; + (*arg).v3 = NULL; - if (strcmp(func_name, "focusstack") == 0) { - func = focusstack; - (*arg).i = parse_circle_direction(arg_value); - } else if (strcmp(func_name, "focusdir") == 0) { - func = focusdir; - (*arg).i = parse_direction(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, "setsmfact") == 0) { - func = setsmfact; - (*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 = parse_direction(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, "increase_proportion") == 0) { - func = increase_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, "tagsilent") == 0) { - func = tagsilent; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } 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, "togglefakefullscreen") == 0) { - func = togglefakefullscreen; - } else if (strcmp(func_name, "toggleoverlay") == 0) { - func = toggleoverlay; - } 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, "toggle_render_border") == 0) { - func = toggle_render_border; - } else if (strcmp(func_name, "focusmon") == 0) { - func = focusmon; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "tagmon") == 0) { - func = tagmon; - (*arg).i = parse_direction(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, "spawn_on_empty") == 0) { - func = spawn_on_empty; - (*arg).v = strdup(arg_value); // 注意:之后需要释放这个内存 - (*arg).ui = 1 << (atoi(arg_value2) - 1); - } else if (strcmp(func_name, "quit") == 0) { - func = quit; - } else if (strcmp(func_name, "create_virtual_output") == 0) { - func = create_virtual_output; - } else if (strcmp(func_name, "destroy_all_virtual_output") == 0) { - func = destroy_all_virtual_output; - } else if (strcmp(func_name, "moveresize") == 0) { - func = moveresize; - (*arg).ui = parse_mouse_action(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 if (strcmp(func_name, "toggletag") == 0) { - func = toggletag; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } else if (strcmp(func_name, "toggleview") == 0) { - func = toggleview; - (*arg).ui = 1 << (atoi(arg_value) - 1); - } else if (strcmp(func_name, "smartmovewin") == 0) { - func = smartmovewin; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "smartresizewin") == 0) { - func = smartresizewin; - (*arg).i = parse_direction(arg_value); - } else if (strcmp(func_name, "resizewin") == 0) { - func = resizewin; - (*arg).ui = parse_num_type(arg_value); - (*arg).ui2 = parse_num_type(arg_value2); - (*arg).i = - (*arg).ui == NUM_TYPE_DEFAULT ? atoi(arg_value) : atoi(arg_value + 1); - (*arg).i2 = (*arg).ui2 == NUM_TYPE_DEFAULT ? atoi(arg_value2) - : atoi(arg_value2 + 1); - } else if (strcmp(func_name, "movewin") == 0) { - func = movewin; - (*arg).ui = parse_num_type(arg_value); - (*arg).ui2 = parse_num_type(arg_value2); - (*arg).i = - (*arg).ui == NUM_TYPE_DEFAULT ? atoi(arg_value) : atoi(arg_value + 1); - (*arg).i2 = (*arg).ui2 == NUM_TYPE_DEFAULT ? atoi(arg_value2) - : atoi(arg_value2 + 1); - } else if (strcmp(func_name, "toggle_named_scratchpad") == 0) { - func = toggle_named_scratchpad; - (*arg).v = strdup(arg_value); - (*arg).v2 = strdup(arg_value2); - (*arg).v3 = strdup(arg_value5); - (*arg).ui = arg_value3 ? atoi(arg_value3) : 0; - (*arg).ui2 = arg_value4 ? atoi(arg_value4) : 0; - } else { - return NULL; - } - return func; + if (strcmp(func_name, "focusstack") == 0) { + func = focusstack; + (*arg).i = parse_circle_direction(arg_value); + } else if (strcmp(func_name, "focusdir") == 0) { + func = focusdir; + (*arg).i = parse_direction(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, "setsmfact") == 0) { + func = setsmfact; + (*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 = parse_direction(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, "increase_proportion") == 0) { + func = increase_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, "tagsilent") == 0) { + func = tagsilent; + (*arg).ui = 1 << (atoi(arg_value) - 1); + } 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, "togglefakefullscreen") == 0) { + func = togglefakefullscreen; + } else if (strcmp(func_name, "toggleoverlay") == 0) { + func = toggleoverlay; + } 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, "toggle_render_border") == 0) { + func = toggle_render_border; + } else if (strcmp(func_name, "focusmon") == 0) { + func = focusmon; + (*arg).i = parse_direction(arg_value); + } else if (strcmp(func_name, "tagmon") == 0) { + func = tagmon; + (*arg).i = parse_direction(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, "spawn_on_empty") == 0) { + func = spawn_on_empty; + (*arg).v = strdup(arg_value); // 注意:之后需要释放这个内存 + (*arg).ui = 1 << (atoi(arg_value2) - 1); + } else if (strcmp(func_name, "quit") == 0) { + func = quit; + } else if (strcmp(func_name, "create_virtual_output") == 0) { + func = create_virtual_output; + } else if (strcmp(func_name, "destroy_all_virtual_output") == 0) { + func = destroy_all_virtual_output; + } else if (strcmp(func_name, "moveresize") == 0) { + func = moveresize; + (*arg).ui = parse_mouse_action(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 if (strcmp(func_name, "toggletag") == 0) { + func = toggletag; + (*arg).ui = 1 << (atoi(arg_value) - 1); + } else if (strcmp(func_name, "toggleview") == 0) { + func = toggleview; + (*arg).ui = 1 << (atoi(arg_value) - 1); + } else if (strcmp(func_name, "smartmovewin") == 0) { + func = smartmovewin; + (*arg).i = parse_direction(arg_value); + } else if (strcmp(func_name, "smartresizewin") == 0) { + func = smartresizewin; + (*arg).i = parse_direction(arg_value); + } else if (strcmp(func_name, "resizewin") == 0) { + func = resizewin; + (*arg).ui = parse_num_type(arg_value); + (*arg).ui2 = parse_num_type(arg_value2); + (*arg).i = (*arg).ui == NUM_TYPE_DEFAULT ? atoi(arg_value) + : atoi(arg_value + 1); + (*arg).i2 = (*arg).ui2 == NUM_TYPE_DEFAULT ? atoi(arg_value2) + : atoi(arg_value2 + 1); + } else if (strcmp(func_name, "movewin") == 0) { + func = movewin; + (*arg).ui = parse_num_type(arg_value); + (*arg).ui2 = parse_num_type(arg_value2); + (*arg).i = (*arg).ui == NUM_TYPE_DEFAULT ? atoi(arg_value) + : atoi(arg_value + 1); + (*arg).i2 = (*arg).ui2 == NUM_TYPE_DEFAULT ? atoi(arg_value2) + : atoi(arg_value2 + 1); + } else if (strcmp(func_name, "toggle_named_scratchpad") == 0) { + func = toggle_named_scratchpad; + (*arg).v = strdup(arg_value); + (*arg).v2 = strdup(arg_value2); + (*arg).v3 = strdup(arg_value5); + (*arg).ui = arg_value3 ? atoi(arg_value3) : 0; + (*arg).ui2 = arg_value4 ? atoi(arg_value4) : 0; + } else { + return NULL; + } + return func; } void run_exec() { - Arg arg; + Arg arg; - for (int i = 0; i < config.exec_count; i++) { - arg.v = config.exec[i]; - spawn(&arg); - } + for (int i = 0; i < config.exec_count; i++) { + arg.v = config.exec[i]; + spawn(&arg); + } } void run_exec_once() { - Arg arg; + Arg arg; - for (int i = 0; i < config.exec_once_count; i++) { - arg.v = config.exec_once[i]; - spawn(&arg); - } + for (int i = 0; i < config.exec_once_count; i++) { + arg.v = config.exec_once[i]; + spawn(&arg); + } } 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; + } - // Then trim each part separately - trim_whitespace(key); - trim_whitespace(value); + // Then trim each part separately + trim_whitespace(key); + trim_whitespace(value); - if (strcmp(key, "animations") == 0) { - config->animations = atoi(value); - } else if (strcmp(key, "animation_type_open") == 0) { - snprintf(config->animation_type_open, sizeof(config->animation_type_open), - "%.9s", value); // string limit to 9 char - } else if (strcmp(key, "animation_type_close") == 0) { - snprintf(config->animation_type_close, sizeof(config->animation_type_close), - "%.9s", value); // string limit to 9 char - } else if (strcmp(key, "animation_fade_in") == 0) { - config->animation_fade_in = atoi(value); - } else if (strcmp(key, "animation_fade_out") == 0) { - config->animation_fade_out = atoi(value); - } else if (strcmp(key, "tag_animation_direction") == 0) { - config->tag_animation_direction = 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, "fadeout_begin_opacity") == 0) { - config->fadeout_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_duration_close") == 0) { - config->animation_duration_close = atoi(value); - } else if (strcmp(key, "animation_curve_move") == 0) { - int num = parse_double_array(value, config->animation_curve_move, 4); - if (num != 4) { - fprintf(stderr, "Error: Failed to parse animation_curve_move: %s\n", - value); - } - } else if (strcmp(key, "animation_curve_open") == 0) { - int num = parse_double_array(value, config->animation_curve_open, 4); - if (num != 4) { - fprintf(stderr, "Error: Failed to parse animation_curve_open: %s\n", - value); - } - } else if (strcmp(key, "animation_curve_tag") == 0) { - int num = parse_double_array(value, config->animation_curve_tag, 4); - if (num != 4) { - fprintf(stderr, "Error: Failed to parse animation_curve_tag: %s\n", - value); - } - } else if (strcmp(key, "animation_curve_close") == 0) { - int num = parse_double_array(value, config->animation_curve_close, 4); - if (num != 4) { - fprintf(stderr, "Error: Failed to parse animation_curve_close: %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, "scroller_default_proportion_single") == 0) { - config->scroller_default_proportion_single = atof(value); - } else if (strcmp(key, "scroller_focus_center") == 0) { - config->scroller_focus_center = atoi(value); - } else if (strcmp(key, "scroller_prefer_center") == 0) { - config->scroller_prefer_center = atoi(value); - } else if (strcmp(key, "focus_cross_monitor") == 0) { - config->focus_cross_monitor = atoi(value); - } else if (strcmp(key, "focus_cross_tag") == 0) { - config->focus_cross_tag = atoi(value); - } else if (strcmp(key, "single_scratchpad") == 0) { - config->single_scratchpad = atoi(value); - } else if (strcmp(key, "xwayland_persistence") == 0) { - config->xwayland_persistence = atoi(value); - } else if (strcmp(key, "no_border_when_single") == 0) { - config->no_border_when_single = atoi(value); - } else if (strcmp(key, "snap_distance") == 0) { - config->snap_distance = atoi(value); - } else if (strcmp(key, "enable_floating_snap") == 0) { - config->enable_floating_snap = atoi(value); - } else if (strcmp(key, "drag_tile_to_tile") == 0) { - config->drag_tile_to_tile = atoi(value); - } else if (strcmp(key, "swipe_min_threshold") == 0) { - config->swipe_min_threshold = atoi(value); - } else if (strcmp(key, "scroller_proportion_preset") == 0) { - // 1. 统计 value 中有多少个逗号,确定需要解析的浮点数个数 - int count = 0; // 初始化为 0 - for (const char *p = value; *p; p++) { - if (*p == ',') - count++; - } - int float_count = count + 1; // 浮点数的数量是逗号数量加 1 + if (strcmp(key, "animations") == 0) { + config->animations = atoi(value); + } else if (strcmp(key, "animation_type_open") == 0) { + snprintf(config->animation_type_open, + sizeof(config->animation_type_open), "%.9s", + value); // string limit to 9 char + } else if (strcmp(key, "animation_type_close") == 0) { + snprintf(config->animation_type_close, + sizeof(config->animation_type_close), "%.9s", + value); // string limit to 9 char + } else if (strcmp(key, "animation_fade_in") == 0) { + config->animation_fade_in = atoi(value); + } else if (strcmp(key, "animation_fade_out") == 0) { + config->animation_fade_out = atoi(value); + } else if (strcmp(key, "tag_animation_direction") == 0) { + config->tag_animation_direction = 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, "fadeout_begin_opacity") == 0) { + config->fadeout_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_duration_close") == 0) { + config->animation_duration_close = atoi(value); + } else if (strcmp(key, "animation_curve_move") == 0) { + int num = parse_double_array(value, config->animation_curve_move, 4); + if (num != 4) { + fprintf(stderr, "Error: Failed to parse animation_curve_move: %s\n", + value); + } + } else if (strcmp(key, "animation_curve_open") == 0) { + int num = parse_double_array(value, config->animation_curve_open, 4); + if (num != 4) { + fprintf(stderr, "Error: Failed to parse animation_curve_open: %s\n", + value); + } + } else if (strcmp(key, "animation_curve_tag") == 0) { + int num = parse_double_array(value, config->animation_curve_tag, 4); + if (num != 4) { + fprintf(stderr, "Error: Failed to parse animation_curve_tag: %s\n", + value); + } + } else if (strcmp(key, "animation_curve_close") == 0) { + int num = parse_double_array(value, config->animation_curve_close, 4); + if (num != 4) { + fprintf(stderr, + "Error: Failed to parse animation_curve_close: %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, "scroller_default_proportion_single") == 0) { + config->scroller_default_proportion_single = atof(value); + } else if (strcmp(key, "scroller_focus_center") == 0) { + config->scroller_focus_center = atoi(value); + } else if (strcmp(key, "scroller_prefer_center") == 0) { + config->scroller_prefer_center = atoi(value); + } else if (strcmp(key, "focus_cross_monitor") == 0) { + config->focus_cross_monitor = atoi(value); + } else if (strcmp(key, "focus_cross_tag") == 0) { + config->focus_cross_tag = atoi(value); + } else if (strcmp(key, "single_scratchpad") == 0) { + config->single_scratchpad = atoi(value); + } else if (strcmp(key, "xwayland_persistence") == 0) { + config->xwayland_persistence = atoi(value); + } else if (strcmp(key, "no_border_when_single") == 0) { + config->no_border_when_single = atoi(value); + } else if (strcmp(key, "snap_distance") == 0) { + config->snap_distance = atoi(value); + } else if (strcmp(key, "enable_floating_snap") == 0) { + config->enable_floating_snap = atoi(value); + } else if (strcmp(key, "drag_tile_to_tile") == 0) { + config->drag_tile_to_tile = atoi(value); + } else if (strcmp(key, "swipe_min_threshold") == 0) { + config->swipe_min_threshold = atoi(value); + } else if (strcmp(key, "scroller_proportion_preset") == 0) { + // 1. 统计 value 中有多少个逗号,确定需要解析的浮点数个数 + int count = 0; // 初始化为 0 + for (const char *p = value; *p; p++) { + if (*p == ',') + count++; + } + int float_count = count + 1; // 浮点数的数量是逗号数量加 1 - // 2. 动态分配内存,存储浮点数 - config->scroller_proportion_preset = - (float *)malloc(float_count * sizeof(float)); - if (!config->scroller_proportion_preset) { - fprintf(stderr, "Error: Memory allocation failed\n"); - return; - } + // 2. 动态分配内存,存储浮点数 + config->scroller_proportion_preset = + (float *)malloc(float_count * sizeof(float)); + if (!config->scroller_proportion_preset) { + fprintf(stderr, "Error: Memory allocation failed\n"); + return; + } - // 3. 解析 value 中的浮点数 - char *value_copy = strdup(value); // 复制 value,因为 strtok 会修改原字符串 - char *token = strtok(value_copy, ","); - int i = 0; + // 3. 解析 value 中的浮点数 + char *value_copy = + strdup(value); // 复制 value,因为 strtok 会修改原字符串 + char *token = strtok(value_copy, ","); + int i = 0; - while (token != NULL && i < float_count) { - if (sscanf(token, "%f", &config->scroller_proportion_preset[i]) != 1) { - fprintf( - stderr, - "Error: Invalid float value in scroller_proportion_preset: %s\n", - token); - free(value_copy); - free(config->scroller_proportion_preset); // 释放已分配的内存 - config->scroller_proportion_preset = NULL; // 防止野指针 - return; - } - token = strtok(NULL, ","); - i++; - } + while (token != NULL && i < float_count) { + if (sscanf(token, "%f", &config->scroller_proportion_preset[i]) != + 1) { + fprintf(stderr, + "Error: Invalid float value in " + "scroller_proportion_preset: %s\n", + token); + free(value_copy); + free(config->scroller_proportion_preset); // 释放已分配的内存 + config->scroller_proportion_preset = NULL; // 防止野指针 + return; + } + token = strtok(NULL, ","); + i++; + } - // 4. 检查解析的浮点数数量是否匹配 - if (i != float_count) { - fprintf(stderr, "Error: Invalid scroller_proportion_preset format: %s\n", - value); - free(value_copy); - free(config->scroller_proportion_preset); // 释放已分配的内存 - config->scroller_proportion_preset = NULL; // 防止野指针 - config->scroller_proportion_preset_count = 0; - return; - } - config->scroller_proportion_preset_count = float_count; + // 4. 检查解析的浮点数数量是否匹配 + if (i != float_count) { + fprintf(stderr, + "Error: Invalid scroller_proportion_preset format: %s\n", + value); + free(value_copy); + free(config->scroller_proportion_preset); // 释放已分配的内存 + config->scroller_proportion_preset = NULL; // 防止野指针 + config->scroller_proportion_preset_count = 0; + return; + } + config->scroller_proportion_preset_count = float_count; - // 5. 释放临时复制的字符串 - free(value_copy); - } else if (strcmp(key, "circle_layout") == 0) { - // 1. 统计 value 中有多少个逗号,确定需要解析的字符串个数 - int count = 0; // 初始化为 0 - for (const char *p = value; *p; p++) { - if (*p == ',') - count++; - } - int string_count = count + 1; // 字符串的数量是逗号数量加 1 + // 5. 释放临时复制的字符串 + free(value_copy); + } else if (strcmp(key, "circle_layout") == 0) { + // 1. 统计 value 中有多少个逗号,确定需要解析的字符串个数 + int count = 0; // 初始化为 0 + for (const char *p = value; *p; p++) { + if (*p == ',') + count++; + } + int string_count = count + 1; // 字符串的数量是逗号数量加 1 - // 2. 动态分配内存,存储字符串指针 - config->circle_layout = (char **)malloc(string_count * sizeof(char *)); - memset(config->circle_layout, 0, string_count * sizeof(char *)); - if (!config->circle_layout) { - fprintf(stderr, "Error: Memory allocation failed\n"); - return; - } + // 2. 动态分配内存,存储字符串指针 + config->circle_layout = (char **)malloc(string_count * sizeof(char *)); + memset(config->circle_layout, 0, string_count * sizeof(char *)); + if (!config->circle_layout) { + fprintf(stderr, "Error: Memory allocation failed\n"); + return; + } - // 3. 解析 value 中的字符串 - char *value_copy = strdup(value); // 复制 value,因为 strtok 会修改原字符串 - char *token = strtok(value_copy, ","); - int i = 0; - char *cleaned_token; - while (token != NULL && i < string_count) { - // 为每个字符串分配内存并复制内容 - cleaned_token = sanitize_string(token); - config->circle_layout[i] = strdup(cleaned_token); - if (!config->circle_layout[i]) { - fprintf(stderr, "Error: Memory allocation failed for string: %s\n", - token); - // 释放之前分配的内存 - for (int j = 0; j < i; j++) { - free(config->circle_layout[j]); - } - free(config->circle_layout); - free(value_copy); - config->circle_layout = NULL; // 防止野指针 - config->circle_layout_count = 0; - return; - } - token = strtok(NULL, ","); - i++; - } + // 3. 解析 value 中的字符串 + char *value_copy = + strdup(value); // 复制 value,因为 strtok 会修改原字符串 + char *token = strtok(value_copy, ","); + int i = 0; + char *cleaned_token; + while (token != NULL && i < string_count) { + // 为每个字符串分配内存并复制内容 + cleaned_token = sanitize_string(token); + config->circle_layout[i] = strdup(cleaned_token); + if (!config->circle_layout[i]) { + fprintf(stderr, + "Error: Memory allocation failed for string: %s\n", + token); + // 释放之前分配的内存 + for (int j = 0; j < i; j++) { + free(config->circle_layout[j]); + } + free(config->circle_layout); + free(value_copy); + config->circle_layout = NULL; // 防止野指针 + config->circle_layout_count = 0; + return; + } + token = strtok(NULL, ","); + i++; + } - // 4. 检查解析的字符串数量是否匹配 - if (i != string_count) { - fprintf(stderr, "Error: Invalid circle_layout format: %s\n", value); - // 释放之前分配的内存 - for (int j = 0; j < i; j++) { - free(config->circle_layout[j]); - } - free(config->circle_layout); - free(value_copy); - config->circle_layout = NULL; // 防止野指针 - config->circle_layout_count = 0; - return; - } - config->circle_layout_count = string_count; + // 4. 检查解析的字符串数量是否匹配 + if (i != string_count) { + fprintf(stderr, "Error: Invalid circle_layout format: %s\n", value); + // 释放之前分配的内存 + for (int j = 0; j < i; j++) { + free(config->circle_layout[j]); + } + free(config->circle_layout); + free(value_copy); + config->circle_layout = NULL; // 防止野指针 + config->circle_layout_count = 0; + return; + } + config->circle_layout_count = string_count; - // 5. 释放临时复制的字符串 - free(value_copy); - } 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_smfact") == 0) { - config->default_smfact = 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, "cursor_hide_timeout") == 0) { - config->cursor_hide_timeout = 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, "repeat_rate") == 0) { - config->repeat_rate = atoi(value); - } else if (strcmp(key, "repeat_delay") == 0) { - config->repeat_delay = atoi(value); - } else if (strcmp(key, "tap_to_click") == 0) { - config->tap_to_click = atoi(value); - } else if (strcmp(key, "tap_and_drag") == 0) { - config->tap_and_drag = atoi(value); - } else if (strcmp(key, "drag_lock") == 0) { - config->drag_lock = atoi(value); - } else if (strcmp(key, "mouse_natural_scrolling") == 0) { - config->mouse_natural_scrolling = atoi(value); - } else if (strcmp(key, "trackpad_natural_scrolling") == 0) { - config->trackpad_natural_scrolling = atoi(value); - } else if (strcmp(key, "cursor_size") == 0) { - config->cursor_size = atoi(value); - } else if (strcmp(key, "cursor_theme") == 0) { - config->cursor_theme = strdup(value); - } else if (strcmp(key, "disable_while_typing") == 0) { - config->disable_while_typing = atoi(value); - } else if (strcmp(key, "left_handed") == 0) { - config->left_handed = atoi(value); - } else if (strcmp(key, "middle_button_emulation") == 0) { - config->middle_button_emulation = atoi(value); - } else if (strcmp(key, "accel_profile") == 0) { - config->accel_profile = atoi(value); - } else if (strcmp(key, "accel_speed") == 0) { - config->accel_speed = atof(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 { - convert_hex_to_rgba(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 { - convert_hex_to_rgba(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 { - convert_hex_to_rgba(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 { - convert_hex_to_rgba(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 { - convert_hex_to_rgba(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 { - convert_hex_to_rgba(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 { - convert_hex_to_rgba(config->globalcolor, color); - } - } else if (strcmp(key, "overlaycolor") == 0) { - long int color = parse_color(value); - if (color == -1) { - fprintf(stderr, "Error: Invalid overlaycolor format: %s\n", value); - } else { - convert_hex_to_rgba(config->overlaycolor, 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); - } - trim_whitespace(config->autostart[0]); - trim_whitespace(config->autostart[1]); - trim_whitespace(config->autostart[2]); - } else if (strcmp(key, "tagrule") == 0) { - config->tag_rules = - realloc(config->tag_rules, - (config->tag_rules_count + 1) * sizeof(ConfigTagRule)); - if (!config->tag_rules) { - fprintf(stderr, "Error: Failed to allocate memory for tag rules\n"); - return; - } + // 5. 释放临时复制的字符串 + free(value_copy); + } 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_smfact") == 0) { + config->default_smfact = 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, "cursor_hide_timeout") == 0) { + config->cursor_hide_timeout = 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, "repeat_rate") == 0) { + config->repeat_rate = atoi(value); + } else if (strcmp(key, "repeat_delay") == 0) { + config->repeat_delay = atoi(value); + } else if (strcmp(key, "tap_to_click") == 0) { + config->tap_to_click = atoi(value); + } else if (strcmp(key, "tap_and_drag") == 0) { + config->tap_and_drag = atoi(value); + } else if (strcmp(key, "drag_lock") == 0) { + config->drag_lock = atoi(value); + } else if (strcmp(key, "mouse_natural_scrolling") == 0) { + config->mouse_natural_scrolling = atoi(value); + } else if (strcmp(key, "trackpad_natural_scrolling") == 0) { + config->trackpad_natural_scrolling = atoi(value); + } else if (strcmp(key, "cursor_size") == 0) { + config->cursor_size = atoi(value); + } else if (strcmp(key, "cursor_theme") == 0) { + config->cursor_theme = strdup(value); + } else if (strcmp(key, "disable_while_typing") == 0) { + config->disable_while_typing = atoi(value); + } else if (strcmp(key, "left_handed") == 0) { + config->left_handed = atoi(value); + } else if (strcmp(key, "middle_button_emulation") == 0) { + config->middle_button_emulation = atoi(value); + } else if (strcmp(key, "accel_profile") == 0) { + config->accel_profile = atoi(value); + } else if (strcmp(key, "accel_speed") == 0) { + config->accel_speed = atof(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 { + convert_hex_to_rgba(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 { + convert_hex_to_rgba(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 { + convert_hex_to_rgba(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 { + convert_hex_to_rgba(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 { + convert_hex_to_rgba(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 { + convert_hex_to_rgba(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 { + convert_hex_to_rgba(config->globalcolor, color); + } + } else if (strcmp(key, "overlaycolor") == 0) { + long int color = parse_color(value); + if (color == -1) { + fprintf(stderr, "Error: Invalid overlaycolor format: %s\n", value); + } else { + convert_hex_to_rgba(config->overlaycolor, 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); + } + trim_whitespace(config->autostart[0]); + trim_whitespace(config->autostart[1]); + trim_whitespace(config->autostart[2]); + } else if (strcmp(key, "tagrule") == 0) { + config->tag_rules = + realloc(config->tag_rules, + (config->tag_rules_count + 1) * sizeof(ConfigTagRule)); + if (!config->tag_rules) { + fprintf(stderr, "Error: Failed to allocate memory for tag rules\n"); + return; + } - ConfigTagRule *rule = &config->tag_rules[config->tag_rules_count]; - memset(rule, 0, sizeof(ConfigTagRule)); + ConfigTagRule *rule = &config->tag_rules[config->tag_rules_count]; + memset(rule, 0, sizeof(ConfigTagRule)); - // 设置默认值 - rule->id = 0; - rule->layout_name = NULL; + // 设置默认值 + rule->id = 0; + rule->layout_name = NULL; - char *token = strtok(value, ","); - while (token != NULL) { - char *colon = strchr(token, ':'); - if (colon != NULL) { - *colon = '\0'; - char *key = token; - char *val = colon + 1; + char *token = strtok(value, ","); + while (token != NULL) { + char *colon = strchr(token, ':'); + if (colon != NULL) { + *colon = '\0'; + char *key = token; + char *val = colon + 1; - trim_whitespace(key); - trim_whitespace(val); + trim_whitespace(key); + trim_whitespace(val); - if (strcmp(key, "id") == 0) { - rule->id = atoi(val); - } else if (strcmp(key, "layout_name") == 0) { - rule->layout_name = strdup(val); - } else if (strcmp(key, "no_render_border") == 0) { - rule->no_render_border = atoi(val); - } - } - token = strtok(NULL, ","); - } + if (strcmp(key, "id") == 0) { + rule->id = atoi(val); + } else if (strcmp(key, "layout_name") == 0) { + rule->layout_name = strdup(val); + } else if (strcmp(key, "no_render_border") == 0) { + rule->no_render_border = atoi(val); + } + } + token = strtok(NULL, ","); + } - config->tag_rules_count++; - } 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; - } + config->tag_rules_count++; + } 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)); + ConfigWinRule *rule = &config->window_rules[config->window_rules_count]; + memset(rule, 0, sizeof(ConfigWinRule)); - rule->isfloating = -1; - rule->isfullscreen = -1; - rule->isnoborder = -1; - rule->isopensilent = -1; - rule->isopenscratchpad = -1; - rule->isunglobal = -1; - rule->isglobal = -1; - rule->isoverlay = -1; - rule->isterm = -1; - rule->noswallow = -1; - rule->monitor = -1; - rule->offsetx = 0; - rule->offsety = 0; - rule->nofadein = -1; - rule->nofadeout = -1; - rule->no_force_center = -1; - rule->scratchpad_width = 0; - rule->scratchpad_height = 0; - rule->width = 0; - rule->height = 0; - rule->animation_type_open = NULL; - rule->animation_type_close = NULL; - rule->scroller_proportion = 0; - rule->id = NULL; - rule->title = NULL; - rule->tags = 0; - rule->globalkeybinding = (KeyBinding){0}; + rule->isfloating = -1; + rule->isfullscreen = -1; + rule->isnoborder = -1; + rule->isopensilent = -1; + rule->isopenscratchpad = -1; + rule->isunglobal = -1; + rule->isglobal = -1; + rule->isoverlay = -1; + rule->isterm = -1; + rule->noswallow = -1; + rule->monitor = -1; + rule->offsetx = 0; + rule->offsety = 0; + rule->nofadein = -1; + rule->nofadeout = -1; + rule->no_force_center = -1; + rule->scratchpad_width = 0; + rule->scratchpad_height = 0; + rule->width = 0; + rule->height = 0; + rule->animation_type_open = NULL; + rule->animation_type_close = NULL; + rule->scroller_proportion = 0; + rule->id = NULL; + rule->title = NULL; + rule->tags = 0; + rule->globalkeybinding = (KeyBinding){0}; - char *token = strtok(value, ","); - while (token != NULL) { - char *colon = strchr(token, ':'); - if (colon != NULL) { - *colon = '\0'; - char *key = token; - char *val = colon + 1; + char *token = strtok(value, ","); + while (token != NULL) { + char *colon = strchr(token, ':'); + if (colon != NULL) { + *colon = '\0'; + char *key = token; + char *val = colon + 1; - trim_whitespace(key); - trim_whitespace(val); + trim_whitespace(key); + trim_whitespace(val); - 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_open") == 0) { - rule->animation_type_open = strdup(val); - } else if (strcmp(key, "animation_type_close") == 0) { - rule->animation_type_close = 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, "offsetx") == 0) { - rule->offsetx = atoi(val); - } else if (strcmp(key, "offsety") == 0) { - rule->offsety = atoi(val); - } else if (strcmp(key, "nofadein") == 0) { - rule->nofadein = atoi(val); - } else if (strcmp(key, "nofadeout") == 0) { - rule->nofadeout = atoi(val); - } else if (strcmp(key, "no_force_center") == 0) { - rule->no_force_center = atoi(val); - } else if (strcmp(key, "scratchpad_width") == 0) { - rule->scratchpad_width = atoi(val); - } else if (strcmp(key, "scratchpad_height") == 0) { - rule->scratchpad_height = 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, "isopensilent") == 0) { - rule->isopensilent = atoi(val); - } else if (strcmp(key, "isopenscratchpad") == 0) { - rule->isopenscratchpad = atoi(val); - } else if (strcmp(key, "isunglobal") == 0) { - rule->isunglobal = atoi(val); - } else if (strcmp(key, "isglobal") == 0) { - rule->isglobal = atoi(val); - } else if (strcmp(key, "isoverlay") == 0) { - rule->isoverlay = atoi(val); - } else if (strcmp(key, "isterm") == 0) { - rule->isterm = atoi(val); - } else if (strcmp(key, "noswallow") == 0) { - rule->noswallow = atoi(val); - } else if (strcmp(key, "scroller_proportion") == 0) { - rule->scroller_proportion = atof(val); - } else if (strcmp(key, "isfullscreen") == 0) { - rule->isfullscreen = atoi(val); - } else if (strcmp(key, "globalkeybinding") == 0) { - char mod_str[256], keysym_str[256]; - sscanf(val, "%[^-]-%[a-zA-Z]", mod_str, keysym_str); - trim_whitespace(mod_str); - trim_whitespace(keysym_str); - rule->globalkeybinding.mod = parse_mod(mod_str); - rule->globalkeybinding.keysym = parse_keysym(keysym_str); - } - } - 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; - } + 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_open") == 0) { + rule->animation_type_open = strdup(val); + } else if (strcmp(key, "animation_type_close") == 0) { + rule->animation_type_close = 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, "offsetx") == 0) { + rule->offsetx = atoi(val); + } else if (strcmp(key, "offsety") == 0) { + rule->offsety = atoi(val); + } else if (strcmp(key, "nofadein") == 0) { + rule->nofadein = atoi(val); + } else if (strcmp(key, "nofadeout") == 0) { + rule->nofadeout = atoi(val); + } else if (strcmp(key, "no_force_center") == 0) { + rule->no_force_center = atoi(val); + } else if (strcmp(key, "scratchpad_width") == 0) { + rule->scratchpad_width = atoi(val); + } else if (strcmp(key, "scratchpad_height") == 0) { + rule->scratchpad_height = 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, "isopensilent") == 0) { + rule->isopensilent = atoi(val); + } else if (strcmp(key, "isopenscratchpad") == 0) { + rule->isopenscratchpad = atoi(val); + } else if (strcmp(key, "isunglobal") == 0) { + rule->isunglobal = atoi(val); + } else if (strcmp(key, "isglobal") == 0) { + rule->isglobal = atoi(val); + } else if (strcmp(key, "isoverlay") == 0) { + rule->isoverlay = atoi(val); + } else if (strcmp(key, "isterm") == 0) { + rule->isterm = atoi(val); + } else if (strcmp(key, "noswallow") == 0) { + rule->noswallow = atoi(val); + } else if (strcmp(key, "scroller_proportion") == 0) { + rule->scroller_proportion = atof(val); + } else if (strcmp(key, "isfullscreen") == 0) { + rule->isfullscreen = atoi(val); + } else if (strcmp(key, "globalkeybinding") == 0) { + char mod_str[256], keysym_str[256]; + sscanf(val, "%[^-]-%[a-zA-Z]", mod_str, keysym_str); + trim_whitespace(mod_str); + trim_whitespace(keysym_str); + rule->globalkeybinding.mod = parse_mod(mod_str); + rule->globalkeybinding.keysym = parse_keysym(keysym_str); + } + } + 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)); + ConfigMonitorRule *rule = + &config->monitor_rules[config->monitor_rules_count]; + memset(rule, 0, sizeof(ConfigMonitorRule)); - // 临时存储每个字段的原始字符串 - char raw_name[256], raw_layout[256]; - char raw_mfact[256], raw_nmaster[256], raw_rr[256]; - char raw_scale[256], raw_x[256], raw_y[256]; + // 临时存储每个字段的原始字符串 + char raw_name[256], raw_layout[256]; + char raw_mfact[256], raw_nmaster[256], raw_rr[256]; + char raw_scale[256], raw_x[256], raw_y[256]; - // 先读取所有字段为字符串 - int parsed = sscanf( - value, - "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255s", - raw_name, raw_mfact, raw_nmaster, raw_layout, raw_rr, raw_scale, raw_x, - raw_y); + // 先读取所有字段为字符串 + int parsed = sscanf(value, + "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[" + "^,],%255[^,],%255s", + raw_name, raw_mfact, raw_nmaster, raw_layout, + raw_rr, raw_scale, raw_x, raw_y); - if (parsed == 8) { - // 修剪每个字段的空格 - trim_whitespace(raw_name); - trim_whitespace(raw_mfact); - trim_whitespace(raw_nmaster); - trim_whitespace(raw_layout); - trim_whitespace(raw_rr); - trim_whitespace(raw_scale); - trim_whitespace(raw_x); - trim_whitespace(raw_y); + if (parsed == 8) { + // 修剪每个字段的空格 + trim_whitespace(raw_name); + trim_whitespace(raw_mfact); + trim_whitespace(raw_nmaster); + trim_whitespace(raw_layout); + trim_whitespace(raw_rr); + trim_whitespace(raw_scale); + trim_whitespace(raw_x); + trim_whitespace(raw_y); - // 转换修剪后的字符串为特定类型 - rule->name = strdup(raw_name); - rule->layout = strdup(raw_layout); - rule->mfact = atof(raw_mfact); - rule->nmaster = atoi(raw_nmaster); - rule->rr = atoi(raw_rr); - rule->scale = atof(raw_scale); - rule->x = atoi(raw_x); - rule->y = atoi(raw_y); + // 转换修剪后的字符串为特定类型 + rule->name = strdup(raw_name); + rule->layout = strdup(raw_layout); + rule->mfact = atof(raw_mfact); + rule->nmaster = atoi(raw_nmaster); + rule->rr = atoi(raw_rr); + rule->scale = atof(raw_scale); + rule->x = atoi(raw_x); + rule->y = atoi(raw_y); - 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; - } + 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, "env", 3) == 0) { + config->monitor_rules_count++; + } else { + fprintf(stderr, "Error: Invalid monitorrule format: %s\n", value); + } + } else if (strncmp(key, "env", 3) == 0) { - char env_type[256], env_value[256]; - if (sscanf(value, "%[^,],%[^\n]", env_type, env_value) < 2) { - fprintf(stderr, "Error: Invalid bind format: %s\n", value); - return; - } - trim_whitespace(env_type); - trim_whitespace(env_value); - setenv(env_type, env_value, 1); + char env_type[256], env_value[256]; + if (sscanf(value, "%[^,],%[^\n]", env_type, env_value) < 2) { + fprintf(stderr, "Error: Invalid bind format: %s\n", value); + return; + } + trim_whitespace(env_type); + trim_whitespace(env_value); + setenv(env_type, env_value, 1); - } else if (strncmp(key, "exec", 9) == 0) { - char **new_exec = - realloc(config->exec, (config->exec_count + 1) * sizeof(char *)); - if (!new_exec) { - fprintf(stderr, "Error: Failed to allocate memory for exec\n"); - return; - } - config->exec = new_exec; + } else if (strncmp(key, "exec", 9) == 0) { + char **new_exec = + realloc(config->exec, (config->exec_count + 1) * sizeof(char *)); + if (!new_exec) { + fprintf(stderr, "Error: Failed to allocate memory for exec\n"); + return; + } + config->exec = new_exec; - config->exec[config->exec_count] = strdup(value); - if (!config->exec[config->exec_count]) { - fprintf(stderr, "Error: Failed to duplicate exec string\n"); - return; - } + config->exec[config->exec_count] = strdup(value); + if (!config->exec[config->exec_count]) { + fprintf(stderr, "Error: Failed to duplicate exec string\n"); + return; + } - config->exec_count++; + config->exec_count++; - } else if (strncmp(key, "exec-once", 9) == 0) { + } else if (strncmp(key, "exec-once", 9) == 0) { - char **new_exec_once = realloc( - config->exec_once, (config->exec_once_count + 1) * sizeof(char *)); - if (!new_exec_once) { - fprintf(stderr, "Error: Failed to allocate memory for exec_once\n"); - return; - } - config->exec_once = new_exec_once; + char **new_exec_once = realloc( + config->exec_once, (config->exec_once_count + 1) * sizeof(char *)); + if (!new_exec_once) { + fprintf(stderr, "Error: Failed to allocate memory for exec_once\n"); + return; + } + config->exec_once = new_exec_once; - config->exec_once[config->exec_once_count] = strdup(value); - if (!config->exec_once[config->exec_once_count]) { - fprintf(stderr, "Error: Failed to duplicate exec_once string\n"); - return; - } + config->exec_once[config->exec_once_count] = strdup(value); + if (!config->exec_once[config->exec_once_count]) { + fprintf(stderr, "Error: Failed to duplicate exec_once string\n"); + return; + } - config->exec_once_count++; + config->exec_once_count++; - } 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; - } + } 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)); + 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", arg_value2[256] = "none", - arg_value3[256] = "none", arg_value4[256] = "none", - arg_value5[256] = "none"; - if (sscanf(value, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", - mod_str, keysym_str, func_name, arg_value, arg_value2, - arg_value3, arg_value4, arg_value5) < 3) { - fprintf(stderr, "Error: Invalid bind format: %s\n", value); - return; - } - trim_whitespace(mod_str); - trim_whitespace(keysym_str); - trim_whitespace(func_name); - trim_whitespace(arg_value); - trim_whitespace(arg_value2); - trim_whitespace(arg_value3); - trim_whitespace(arg_value4); - trim_whitespace(arg_value5); + char mod_str[256], keysym_str[256], func_name[256], + arg_value[256] = "none", arg_value2[256] = "none", + arg_value3[256] = "none", arg_value4[256] = "none", + arg_value5[256] = "none"; + if (sscanf(value, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", + mod_str, keysym_str, func_name, arg_value, arg_value2, + arg_value3, arg_value4, arg_value5) < 3) { + fprintf(stderr, "Error: Invalid bind format: %s\n", value); + return; + } + trim_whitespace(mod_str); + trim_whitespace(keysym_str); + trim_whitespace(func_name); + trim_whitespace(arg_value); + trim_whitespace(arg_value2); + trim_whitespace(arg_value3); + trim_whitespace(arg_value4); + trim_whitespace(arg_value5); - binding->mod = parse_mod(mod_str); - binding->keysym = parse_keysym(keysym_str); - binding->arg.v = NULL; - binding->arg.v2 = NULL; - binding->arg.v3 = NULL; - binding->func = - parse_func_name(func_name, &binding->arg, arg_value, arg_value2, - arg_value3, arg_value4, arg_value5); - if (!binding->func) { - if (binding->arg.v) { - free(binding->arg.v); - binding->arg.v = NULL; - } - if (binding->arg.v2) { - free(binding->arg.v2); - binding->arg.v2 = NULL; - } - if (binding->arg.v3) { - free(binding->arg.v3); - binding->arg.v3 = NULL; - } - fprintf(stderr, "Error: Unknown function in bind: %s\n", func_name); - } else { - config->key_bindings_count++; - } + binding->mod = parse_mod(mod_str); + binding->keysym = parse_keysym(keysym_str); + binding->arg.v = NULL; + binding->arg.v2 = NULL; + binding->arg.v3 = NULL; + binding->func = + parse_func_name(func_name, &binding->arg, arg_value, arg_value2, + arg_value3, arg_value4, arg_value5); + if (!binding->func) { + if (binding->arg.v) { + free(binding->arg.v); + binding->arg.v = NULL; + } + if (binding->arg.v2) { + free(binding->arg.v2); + binding->arg.v2 = NULL; + } + if (binding->arg.v3) { + free(binding->arg.v3); + binding->arg.v3 = NULL; + } + 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; - } + } 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)); + 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", arg_value2[256] = "none", - arg_value3[256] = "none", arg_value4[256] = "none", - arg_value5[256] = "none"; - if (sscanf(value, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", - mod_str, button_str, func_name, arg_value, arg_value2, - arg_value3, arg_value4, arg_value5) < 3) { - fprintf(stderr, "Error: Invalid mousebind format: %s\n", value); - return; - } - trim_whitespace(mod_str); - trim_whitespace(button_str); - trim_whitespace(func_name); - trim_whitespace(arg_value); - trim_whitespace(arg_value2); - trim_whitespace(arg_value3); - trim_whitespace(arg_value4); - trim_whitespace(arg_value5); + char mod_str[256], button_str[256], func_name[256], + arg_value[256] = "none", arg_value2[256] = "none", + arg_value3[256] = "none", arg_value4[256] = "none", + arg_value5[256] = "none"; + if (sscanf(value, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", + mod_str, button_str, func_name, arg_value, arg_value2, + arg_value3, arg_value4, arg_value5) < 3) { + fprintf(stderr, "Error: Invalid mousebind format: %s\n", value); + return; + } + trim_whitespace(mod_str); + trim_whitespace(button_str); + trim_whitespace(func_name); + trim_whitespace(arg_value); + trim_whitespace(arg_value2); + trim_whitespace(arg_value3); + trim_whitespace(arg_value4); + trim_whitespace(arg_value5); - binding->mod = parse_mod(mod_str); - binding->button = parse_button(button_str); - binding->arg.v = NULL; - binding->arg.v2 = NULL; - binding->arg.v3 = NULL; - binding->func = - parse_func_name(func_name, &binding->arg, arg_value, arg_value2, - arg_value3, arg_value4, arg_value5); - if (!binding->func) { - if (binding->arg.v) { - free(binding->arg.v); - binding->arg.v = NULL; - } - if (binding->arg.v2) { - free(binding->arg.v2); - binding->arg.v2 = NULL; - } - if (binding->arg.v3) { - free(binding->arg.v3); - binding->arg.v3 = NULL; - } - 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; - } + binding->mod = parse_mod(mod_str); + binding->button = parse_button(button_str); + binding->arg.v = NULL; + binding->arg.v2 = NULL; + binding->arg.v3 = NULL; + binding->func = + parse_func_name(func_name, &binding->arg, arg_value, arg_value2, + arg_value3, arg_value4, arg_value5); + if (!binding->func) { + if (binding->arg.v) { + free(binding->arg.v); + binding->arg.v = NULL; + } + if (binding->arg.v2) { + free(binding->arg.v2); + binding->arg.v2 = NULL; + } + if (binding->arg.v3) { + free(binding->arg.v3); + binding->arg.v3 = NULL; + } + 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)); + 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", arg_value2[256] = "none", - arg_value3[256] = "none", arg_value4[256] = "none", - arg_value5[256] = "none"; - if (sscanf(value, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", - mod_str, dir_str, func_name, arg_value, arg_value2, arg_value3, - arg_value4, arg_value5) < 3) { - fprintf(stderr, "Error: Invalid axisbind format: %s\n", value); - return; - } + char mod_str[256], dir_str[256], func_name[256], + arg_value[256] = "none", arg_value2[256] = "none", + arg_value3[256] = "none", arg_value4[256] = "none", + arg_value5[256] = "none"; + if (sscanf(value, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", + mod_str, dir_str, func_name, arg_value, arg_value2, + arg_value3, arg_value4, arg_value5) < 3) { + fprintf(stderr, "Error: Invalid axisbind format: %s\n", value); + return; + } - trim_whitespace(mod_str); - trim_whitespace(dir_str); - trim_whitespace(func_name); - trim_whitespace(arg_value); - trim_whitespace(arg_value2); - trim_whitespace(arg_value3); - trim_whitespace(arg_value4); - trim_whitespace(arg_value5); + trim_whitespace(mod_str); + trim_whitespace(dir_str); + trim_whitespace(func_name); + trim_whitespace(arg_value); + trim_whitespace(arg_value2); + trim_whitespace(arg_value3); + trim_whitespace(arg_value4); + trim_whitespace(arg_value5); - binding->mod = parse_mod(mod_str); - binding->dir = parse_direction(dir_str); - binding->arg.v = NULL; - binding->arg.v2 = NULL; - binding->arg.v3 = NULL; - binding->func = - parse_func_name(func_name, &binding->arg, arg_value, arg_value2, - arg_value3, arg_value4, arg_value5); + binding->mod = parse_mod(mod_str); + binding->dir = parse_direction(dir_str); + binding->arg.v = NULL; + binding->arg.v2 = NULL; + binding->arg.v3 = NULL; + binding->func = + parse_func_name(func_name, &binding->arg, arg_value, arg_value2, + arg_value3, arg_value4, arg_value5); - if (!binding->func) { - if (binding->arg.v) { - free(binding->arg.v); - binding->arg.v = NULL; - } - if (binding->arg.v2) { - free(binding->arg.v2); - binding->arg.v2 = NULL; - } - if (binding->arg.v3) { - free(binding->arg.v3); - binding->arg.v3 = NULL; - } - fprintf(stderr, "Error: Unknown function in axisbind: %s\n", func_name); - } else { - config->axis_bindings_count++; - } + if (!binding->func) { + if (binding->arg.v) { + free(binding->arg.v); + binding->arg.v = NULL; + } + if (binding->arg.v2) { + free(binding->arg.v2); + binding->arg.v2 = NULL; + } + if (binding->arg.v3) { + free(binding->arg.v3); + binding->arg.v3 = NULL; + } + fprintf(stderr, "Error: Unknown function in axisbind: %s\n", + func_name); + } else { + config->axis_bindings_count++; + } - } else if (strncmp(key, "gesturebind", 11) == 0) { - config->gesture_bindings = - realloc(config->gesture_bindings, - (config->gesture_bindings_count + 1) * sizeof(GestureBinding)); - if (!config->gesture_bindings) { - fprintf(stderr, - "Error: Failed to allocate memory for axis gesturebind\n"); - return; - } + } else if (strncmp(key, "gesturebind", 11) == 0) { + config->gesture_bindings = realloc( + config->gesture_bindings, + (config->gesture_bindings_count + 1) * sizeof(GestureBinding)); + if (!config->gesture_bindings) { + fprintf(stderr, + "Error: Failed to allocate memory for axis gesturebind\n"); + return; + } - GestureBinding *binding = - &config->gesture_bindings[config->gesture_bindings_count]; - memset(binding, 0, sizeof(GestureBinding)); + GestureBinding *binding = + &config->gesture_bindings[config->gesture_bindings_count]; + memset(binding, 0, sizeof(GestureBinding)); - char mod_str[256], motion_str[256], fingers_count_str[256], func_name[256], - arg_value[256] = "none", arg_value2[256] = "none", - arg_value3[256] = "none", arg_value4[256] = "none", - arg_value5[256] = "none"; - if (sscanf(value, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", - mod_str, motion_str, fingers_count_str, func_name, arg_value, - arg_value2, arg_value3, arg_value4, arg_value5) < 4) { - fprintf(stderr, "Error: Invalid gesturebind format: %s\n", value); - return; - } + char mod_str[256], motion_str[256], fingers_count_str[256], + func_name[256], arg_value[256] = "none", arg_value2[256] = "none", + arg_value3[256] = "none", arg_value4[256] = "none", + arg_value5[256] = "none"; + if (sscanf(value, + "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", + mod_str, motion_str, fingers_count_str, func_name, arg_value, + arg_value2, arg_value3, arg_value4, arg_value5) < 4) { + fprintf(stderr, "Error: Invalid gesturebind format: %s\n", value); + return; + } - trim_whitespace(mod_str); - trim_whitespace(motion_str); - trim_whitespace(fingers_count_str); - trim_whitespace(func_name); - trim_whitespace(arg_value); - trim_whitespace(arg_value2); - trim_whitespace(arg_value3); - trim_whitespace(arg_value4); - trim_whitespace(arg_value5); + trim_whitespace(mod_str); + trim_whitespace(motion_str); + trim_whitespace(fingers_count_str); + trim_whitespace(func_name); + trim_whitespace(arg_value); + trim_whitespace(arg_value2); + trim_whitespace(arg_value3); + trim_whitespace(arg_value4); + trim_whitespace(arg_value5); - binding->mod = parse_mod(mod_str); - binding->motion = parse_direction(motion_str); - binding->fingers_count = atoi(fingers_count_str); - binding->arg.v = NULL; - binding->arg.v2 = NULL; - binding->arg.v3 = NULL; - binding->func = - parse_func_name(func_name, &binding->arg, arg_value, arg_value2, - arg_value3, arg_value4, arg_value5); + binding->mod = parse_mod(mod_str); + binding->motion = parse_direction(motion_str); + binding->fingers_count = atoi(fingers_count_str); + binding->arg.v = NULL; + binding->arg.v2 = NULL; + binding->arg.v3 = NULL; + binding->func = + parse_func_name(func_name, &binding->arg, arg_value, arg_value2, + arg_value3, arg_value4, arg_value5); - if (!binding->func) { - if (binding->arg.v) { - free(binding->arg.v); - binding->arg.v = NULL; - } - if (binding->arg.v2) { - free(binding->arg.v2); - binding->arg.v2 = NULL; - } - if (binding->arg.v3) { - free(binding->arg.v3); - binding->arg.v3 = NULL; - } - fprintf(stderr, "Error: Unknown function in axisbind: %s\n", func_name); - } else { - config->gesture_bindings_count++; - } + if (!binding->func) { + if (binding->arg.v) { + free(binding->arg.v); + binding->arg.v = NULL; + } + if (binding->arg.v2) { + free(binding->arg.v2); + binding->arg.v2 = NULL; + } + if (binding->arg.v3) { + free(binding->arg.v3); + binding->arg.v3 = NULL; + } + fprintf(stderr, "Error: Unknown function in axisbind: %s\n", + func_name); + } else { + config->gesture_bindings_count++; + } - } else if (strncmp(key, "source", 6) == 0) { - parse_config_file(config, value); - } else { - fprintf(stderr, "Error: Unknown key: %s\n", key); - } + } else if (strncmp(key, "source", 6) == 0) { + parse_config_file(config, value); + } else { + fprintf(stderr, "Error: Unknown key: %s\n", key); + } } void parse_config_file(Config *config, const char *file_path) { - FILE *file; - // 检查路径是否以 ~/ 开头 - if (file_path[0] == '~' && (file_path[1] == '/' || file_path[1] == '\0')) { - const char *home = getenv("HOME"); - if (!home) { - fprintf(stderr, "Error: HOME environment variable not set.\n"); - return; - } + FILE *file; + // 检查路径是否以 ~/ 开头 + if (file_path[0] == '~' && (file_path[1] == '/' || file_path[1] == '\0')) { + const char *home = getenv("HOME"); + if (!home) { + fprintf(stderr, "Error: HOME environment variable not set.\n"); + return; + } - // 构建完整路径(家目录 + / + 原路径去掉 ~) - char full_path[1024]; - snprintf(full_path, sizeof(full_path), "%s%s", home, file_path + 1); + // 构建完整路径(家目录 + / + 原路径去掉 ~) + char full_path[1024]; + snprintf(full_path, sizeof(full_path), "%s%s", home, file_path + 1); - file = fopen(full_path, "r"); - if (!file) { - perror("Error opening file"); - return; - } - } else { - file = fopen(file_path, "r"); - if (!file) { - perror("Error opening file"); - return; - } - } + file = fopen(full_path, "r"); + if (!file) { + perror("Error opening file"); + return; + } + } else { + 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); } void free_circle_layout(Config *config) { - if (config->circle_layout) { - // 释放每个字符串 - for (int i = 0; i < config->circle_layout_count; i++) { - if (config->circle_layout[i]) { - free(config->circle_layout[i]); // 释放单个字符串 - config->circle_layout[i] = NULL; // 防止野指针 - } - } - // 释放 circle_layout 数组本身 - free(config->circle_layout); - config->circle_layout = NULL; // 防止野指针 - } - config->circle_layout_count = 0; // 重置计数 + if (config->circle_layout) { + // 释放每个字符串 + for (int i = 0; i < config->circle_layout_count; i++) { + if (config->circle_layout[i]) { + free(config->circle_layout[i]); // 释放单个字符串 + config->circle_layout[i] = NULL; // 防止野指针 + } + } + // 释放 circle_layout 数组本身 + free(config->circle_layout); + config->circle_layout = NULL; // 防止野指针 + } + config->circle_layout_count = 0; // 重置计数 } void free_baked_points(void) { - if (baked_points_move) { - free(baked_points_move); - baked_points_move = NULL; - } - if (baked_points_open) { - free(baked_points_open); - baked_points_open = NULL; - } - if (baked_points_close) { - free(baked_points_close); - baked_points_close = NULL; - } - if (baked_points_tag) { - free(baked_points_tag); - baked_points_tag = NULL; - } + if (baked_points_move) { + free(baked_points_move); + baked_points_move = NULL; + } + if (baked_points_open) { + free(baked_points_open); + baked_points_open = NULL; + } + if (baked_points_close) { + free(baked_points_close); + baked_points_close = NULL; + } + if (baked_points_tag) { + free(baked_points_tag); + baked_points_tag = NULL; + } } void free_config(void) { - // 释放内存 - int i; + // 释放内存 + int i; - // 释放 window_rules - if (config.window_rules) { - for (int i = 0; i < config.window_rules_count; i++) { - ConfigWinRule *rule = &config.window_rules[i]; - free((void *)rule->id); - free((void *)rule->title); - free((void *)rule->animation_type_open); - free((void *)rule->animation_type_close); - // 释放 globalkeybinding 的 arg.v(如果动态分配) - if (rule->globalkeybinding.arg.v) { - free((void *)rule->globalkeybinding.arg.v); - } - } - free(config.window_rules); - config.window_rules = NULL; - config.window_rules_count = 0; - } + // 释放 window_rules + if (config.window_rules) { + for (int i = 0; i < config.window_rules_count; i++) { + ConfigWinRule *rule = &config.window_rules[i]; + free((void *)rule->id); + free((void *)rule->title); + free((void *)rule->animation_type_open); + free((void *)rule->animation_type_close); + // 释放 globalkeybinding 的 arg.v(如果动态分配) + if (rule->globalkeybinding.arg.v) { + free((void *)rule->globalkeybinding.arg.v); + } + } + free(config.window_rules); + config.window_rules = NULL; + config.window_rules_count = 0; + } - // 释放 monitor_rules - if (config.monitor_rules) { - for (int i = 0; i < config.monitor_rules_count; i++) { - ConfigMonitorRule *rule = &config.monitor_rules[i]; - free((void *)rule->name); - free((void *)rule->layout); - } - free(config.monitor_rules); - config.monitor_rules = NULL; - config.monitor_rules_count = 0; - } + // 释放 monitor_rules + if (config.monitor_rules) { + for (int i = 0; i < config.monitor_rules_count; i++) { + ConfigMonitorRule *rule = &config.monitor_rules[i]; + free((void *)rule->name); + free((void *)rule->layout); + } + free(config.monitor_rules); + config.monitor_rules = NULL; + config.monitor_rules_count = 0; + } - // 释放 key_bindings - if (config.key_bindings) { - 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; - } - if (config.key_bindings[i].arg.v2) { - free((void *)config.key_bindings[i].arg.v2); - config.key_bindings[i].arg.v2 = NULL; - } - if (config.key_bindings[i].arg.v3) { - free((void *)config.key_bindings[i].arg.v3); - config.key_bindings[i].arg.v3 = NULL; - } - } - free(config.key_bindings); - config.key_bindings = NULL; - config.key_bindings_count = 0; - } + // 释放 key_bindings + if (config.key_bindings) { + 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; + } + if (config.key_bindings[i].arg.v2) { + free((void *)config.key_bindings[i].arg.v2); + config.key_bindings[i].arg.v2 = NULL; + } + if (config.key_bindings[i].arg.v3) { + free((void *)config.key_bindings[i].arg.v3); + config.key_bindings[i].arg.v3 = NULL; + } + } + free(config.key_bindings); + config.key_bindings = NULL; + config.key_bindings_count = 0; + } - // 释放 mouse_bindings - if (config.mouse_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; - } - if (config.mouse_bindings[i].arg.v2) { - free((void *)config.mouse_bindings[i].arg.v2); - config.mouse_bindings[i].arg.v2 = NULL; - } - if (config.mouse_bindings[i].arg.v3) { - free((void *)config.mouse_bindings[i].arg.v3); - config.mouse_bindings[i].arg.v3 = NULL; - } - } - free(config.mouse_bindings); - config.mouse_bindings = NULL; - config.mouse_bindings_count = 0; - } + // 释放 mouse_bindings + if (config.mouse_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; + } + if (config.mouse_bindings[i].arg.v2) { + free((void *)config.mouse_bindings[i].arg.v2); + config.mouse_bindings[i].arg.v2 = NULL; + } + if (config.mouse_bindings[i].arg.v3) { + free((void *)config.mouse_bindings[i].arg.v3); + config.mouse_bindings[i].arg.v3 = NULL; + } + } + free(config.mouse_bindings); + config.mouse_bindings = NULL; + config.mouse_bindings_count = 0; + } - // 释放 axis_bindings - if (config.axis_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; - } - if (config.axis_bindings[i].arg.v2) { - free((void *)config.axis_bindings[i].arg.v2); - config.axis_bindings[i].arg.v2 = NULL; - } - if (config.axis_bindings[i].arg.v3) { - free((void *)config.axis_bindings[i].arg.v3); - config.axis_bindings[i].arg.v3 = NULL; - } - } - free(config.axis_bindings); - config.axis_bindings = NULL; - config.axis_bindings_count = 0; - } + // 释放 axis_bindings + if (config.axis_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; + } + if (config.axis_bindings[i].arg.v2) { + free((void *)config.axis_bindings[i].arg.v2); + config.axis_bindings[i].arg.v2 = NULL; + } + if (config.axis_bindings[i].arg.v3) { + free((void *)config.axis_bindings[i].arg.v3); + config.axis_bindings[i].arg.v3 = NULL; + } + } + free(config.axis_bindings); + config.axis_bindings = NULL; + config.axis_bindings_count = 0; + } - // 释放 gesture_bindings - if (config.gesture_bindings) { - for (i = 0; i < config.gesture_bindings_count; i++) { - if (config.gesture_bindings[i].arg.v) { - free((void *)config.gesture_bindings[i].arg.v); - config.gesture_bindings[i].arg.v = NULL; - } - if (config.gesture_bindings[i].arg.v2) { - free((void *)config.gesture_bindings[i].arg.v2); - config.gesture_bindings[i].arg.v2 = NULL; - } - if (config.gesture_bindings[i].arg.v3) { - free((void *)config.gesture_bindings[i].arg.v3); - config.gesture_bindings[i].arg.v3 = NULL; - } - } - free(config.gesture_bindings); - config.gesture_bindings = NULL; - config.gesture_bindings_count = 0; - } + // 释放 gesture_bindings + if (config.gesture_bindings) { + for (i = 0; i < config.gesture_bindings_count; i++) { + if (config.gesture_bindings[i].arg.v) { + free((void *)config.gesture_bindings[i].arg.v); + config.gesture_bindings[i].arg.v = NULL; + } + if (config.gesture_bindings[i].arg.v2) { + free((void *)config.gesture_bindings[i].arg.v2); + config.gesture_bindings[i].arg.v2 = NULL; + } + if (config.gesture_bindings[i].arg.v3) { + free((void *)config.gesture_bindings[i].arg.v3); + config.gesture_bindings[i].arg.v3 = NULL; + } + } + free(config.gesture_bindings); + config.gesture_bindings = NULL; + config.gesture_bindings_count = 0; + } - // 释放 tag_rules - if (config.tag_rules) { - for (int i = 0; i < config.tag_rules_count; i++) { - free((void *)config.tag_rules[i].layout_name); - } - free(config.tag_rules); - config.tag_rules = NULL; - config.tag_rules_count = 0; - } + // 释放 tag_rules + if (config.tag_rules) { + for (int i = 0; i < config.tag_rules_count; i++) { + free((void *)config.tag_rules[i].layout_name); + } + free(config.tag_rules); + config.tag_rules = NULL; + config.tag_rules_count = 0; + } - // 释放 exec - if (config.exec) { - for (i = 0; i < config.exec_count; i++) { - free(config.exec[i]); - } - free(config.exec); - config.exec = NULL; - config.exec_count = 0; - } + // 释放 exec + if (config.exec) { + for (i = 0; i < config.exec_count; i++) { + free(config.exec[i]); + } + free(config.exec); + config.exec = NULL; + config.exec_count = 0; + } - // 释放 exec_once - if (config.exec_once) { - for (i = 0; i < config.exec_once_count; i++) { - free(config.exec_once[i]); - } - free(config.exec_once); - config.exec_once = NULL; - config.exec_once_count = 0; - } + // 释放 exec_once + if (config.exec_once) { + for (i = 0; i < config.exec_once_count; i++) { + free(config.exec_once[i]); + } + free(config.exec_once); + config.exec_once = NULL; + config.exec_once_count = 0; + } - // 释放 scroller_proportion_preset - if (config.scroller_proportion_preset) { - free(config.scroller_proportion_preset); - config.scroller_proportion_preset = NULL; - config.scroller_proportion_preset_count = 0; - } + // 释放 scroller_proportion_preset + if (config.scroller_proportion_preset) { + free(config.scroller_proportion_preset); + config.scroller_proportion_preset = NULL; + config.scroller_proportion_preset_count = 0; + } - if (config.cursor_theme) { - free(config.cursor_theme); - config.cursor_theme = NULL; - } + if (config.cursor_theme) { + free(config.cursor_theme); + config.cursor_theme = NULL; + } - // 释放 circle_layout - free_circle_layout(&config); + // 释放 circle_layout + free_circle_layout(&config); - // 释放动画资源 - free_baked_points(); + // 释放动画资源 + free_baked_points(); } void override_config(void) { - animations = config.animations; - animation_type_open = config.animation_type_open; - animation_type_close = config.animation_type_close; - animation_fade_in = config.animation_fade_in; - animation_fade_out = config.animation_fade_out; - tag_animation_direction = config.tag_animation_direction; - zoom_initial_ratio = config.zoom_initial_ratio; - fadein_begin_opacity = config.fadein_begin_opacity; - fadeout_begin_opacity = config.fadeout_begin_opacity; - animation_duration_move = config.animation_duration_move; - animation_duration_open = config.animation_duration_open; - animation_duration_tag = config.animation_duration_tag; - animation_duration_close = config.animation_duration_close; + animations = config.animations; + animation_type_open = config.animation_type_open; + animation_type_close = config.animation_type_close; + animation_fade_in = config.animation_fade_in; + animation_fade_out = config.animation_fade_out; + tag_animation_direction = config.tag_animation_direction; + zoom_initial_ratio = config.zoom_initial_ratio; + fadein_begin_opacity = config.fadein_begin_opacity; + fadeout_begin_opacity = config.fadeout_begin_opacity; + animation_duration_move = config.animation_duration_move; + animation_duration_open = config.animation_duration_open; + animation_duration_tag = config.animation_duration_tag; + animation_duration_close = config.animation_duration_close; - // 复制数组类型的变量 - memcpy(animation_curve_move, config.animation_curve_move, - sizeof(animation_curve_move)); - memcpy(animation_curve_open, config.animation_curve_open, - sizeof(animation_curve_open)); - memcpy(animation_curve_tag, config.animation_curve_tag, - sizeof(animation_curve_tag)); - memcpy(animation_curve_close, config.animation_curve_close, - sizeof(animation_curve_close)); + // 复制数组类型的变量 + memcpy(animation_curve_move, config.animation_curve_move, + sizeof(animation_curve_move)); + memcpy(animation_curve_open, config.animation_curve_open, + sizeof(animation_curve_open)); + memcpy(animation_curve_tag, config.animation_curve_tag, + sizeof(animation_curve_tag)); + memcpy(animation_curve_close, config.animation_curve_close, + sizeof(animation_curve_close)); - scroller_structs = config.scroller_structs; - scroller_default_proportion = config.scroller_default_proportion; - scroller_default_proportion_single = - config.scroller_default_proportion_single; - scroller_focus_center = config.scroller_focus_center; - focus_cross_monitor = config.focus_cross_monitor; - focus_cross_tag = config.focus_cross_tag; - single_scratchpad = config.single_scratchpad; - xwayland_persistence = config.xwayland_persistence; - no_border_when_single = config.no_border_when_single; - snap_distance = config.snap_distance; - drag_tile_to_tile = config.drag_tile_to_tile; - enable_floating_snap = config.enable_floating_snap; - swipe_min_threshold = config.swipe_min_threshold; - scroller_prefer_center = config.scroller_prefer_center; + scroller_structs = config.scroller_structs; + scroller_default_proportion = config.scroller_default_proportion; + scroller_default_proportion_single = + config.scroller_default_proportion_single; + scroller_focus_center = config.scroller_focus_center; + focus_cross_monitor = config.focus_cross_monitor; + focus_cross_tag = config.focus_cross_tag; + single_scratchpad = config.single_scratchpad; + xwayland_persistence = config.xwayland_persistence; + no_border_when_single = config.no_border_when_single; + snap_distance = config.snap_distance; + drag_tile_to_tile = config.drag_tile_to_tile; + enable_floating_snap = config.enable_floating_snap; + swipe_min_threshold = config.swipe_min_threshold; + scroller_prefer_center = config.scroller_prefer_center; - new_is_master = config.new_is_master; - default_mfact = config.default_mfact; - default_smfact = config.default_smfact; - 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; - cursor_hide_timeout = config.cursor_hide_timeout; - 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; - repeat_rate = config.repeat_rate; - repeat_delay = config.repeat_delay; - tap_to_click = config.tap_to_click; - tap_and_drag = config.tap_and_drag; - drag_lock = config.drag_lock; - mouse_natural_scrolling = config.mouse_natural_scrolling; - cursor_size = config.cursor_size; - trackpad_natural_scrolling = config.trackpad_natural_scrolling; - disable_while_typing = config.disable_while_typing; - left_handed = config.left_handed; - middle_button_emulation = config.middle_button_emulation; - accel_profile = config.accel_profile; - accel_speed = config.accel_speed; + new_is_master = config.new_is_master; + default_mfact = config.default_mfact; + default_smfact = config.default_smfact; + 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; + cursor_hide_timeout = config.cursor_hide_timeout; + 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; + repeat_rate = config.repeat_rate; + repeat_delay = config.repeat_delay; + tap_to_click = config.tap_to_click; + tap_and_drag = config.tap_and_drag; + drag_lock = config.drag_lock; + mouse_natural_scrolling = config.mouse_natural_scrolling; + cursor_size = config.cursor_size; + trackpad_natural_scrolling = config.trackpad_natural_scrolling; + disable_while_typing = config.disable_while_typing; + left_handed = config.left_handed; + middle_button_emulation = config.middle_button_emulation; + accel_profile = config.accel_profile; + accel_speed = config.accel_speed; - // 复制颜色数组 - 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(overlaycolor, config.overlaycolor, sizeof(overlaycolor)); + // 复制颜色数组 + 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(overlaycolor, config.overlaycolor, sizeof(overlaycolor)); } void set_value_default() { - /* animaion */ - config.animations = animations; // 是否启用动画 - config.animation_fade_in = animation_fade_in; // Enable animation fade in - config.animation_fade_out = animation_fade_out; // Enable animation fade out - config.tag_animation_direction = tag_animation_direction; // 标签动画方向 - config.zoom_initial_ratio = zoom_initial_ratio; // 动画起始窗口比例 - config.fadein_begin_opacity = - fadein_begin_opacity; // Begin opac window ratio for animations - config.fadeout_begin_opacity = fadeout_begin_opacity; - config.animation_duration_move = - animation_duration_move; // Animation move speed - config.animation_duration_open = - animation_duration_open; // Animation open speed - config.animation_duration_tag = animation_duration_tag; // Animation tag speed - config.animation_duration_close = - animation_duration_close; // Animation tag speed + /* animaion */ + config.animations = animations; // 是否启用动画 + config.animation_fade_in = animation_fade_in; // Enable animation fade in + config.animation_fade_out = animation_fade_out; // Enable animation fade out + config.tag_animation_direction = tag_animation_direction; // 标签动画方向 + config.zoom_initial_ratio = zoom_initial_ratio; // 动画起始窗口比例 + config.fadein_begin_opacity = + fadein_begin_opacity; // Begin opac window ratio for animations + config.fadeout_begin_opacity = fadeout_begin_opacity; + config.animation_duration_move = + animation_duration_move; // Animation move speed + config.animation_duration_open = + animation_duration_open; // Animation open speed + config.animation_duration_tag = + animation_duration_tag; // Animation tag speed + config.animation_duration_close = + animation_duration_close; // Animation tag speed - /* appearance */ - config.axis_bind_apply_timeout = - axis_bind_apply_timeout; // 滚轮绑定动作的触发的时间间隔 - config.focus_on_activate = - focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦 - config.new_is_master = new_is_master; // 新窗口是否插在头部 - config.default_mfact = default_mfact; // master 窗口比例 - config.default_smfact = default_smfact; // 第一个stack比例 - config.default_nmaster = default_nmaster; // 默认master数量 + /* appearance */ + config.axis_bind_apply_timeout = + axis_bind_apply_timeout; // 滚轮绑定动作的触发的时间间隔 + config.focus_on_activate = + focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦 + config.new_is_master = new_is_master; // 新窗口是否插在头部 + config.default_mfact = default_mfact; // master 窗口比例 + config.default_smfact = default_smfact; // 第一个stack比例 + config.default_nmaster = default_nmaster; // 默认master数量 - config.numlockon = numlockon; // 是否打开右边小键盘 + config.numlockon = numlockon; // 是否打开右边小键盘 - config.ov_tab_mode = ov_tab_mode; // alt tab切换模式 - config.hotarea_size = hotarea_size; // 热区大小,10x10 - config.enable_hotarea = enable_hotarea; // 是否启用鼠标热区 - config.smartgaps = - smartgaps; /* 1 means no outer gap when there is only one window */ - config.sloppyfocus = sloppyfocus; /* focus follows mouse */ - config.gappih = gappih; /* horiz inner gap between windows */ - config.gappiv = gappiv; /* vert inner gap between windows */ - config.gappoh = gappoh; /* horiz outer gap between windows and screen edge */ - config.gappov = gappov; /* vert outer gap between windows and screen edge */ + config.ov_tab_mode = ov_tab_mode; // alt tab切换模式 + config.hotarea_size = hotarea_size; // 热区大小,10x10 + config.enable_hotarea = enable_hotarea; // 是否启用鼠标热区 + config.smartgaps = + smartgaps; /* 1 means no outer gap when there is only one window */ + config.sloppyfocus = sloppyfocus; /* focus follows mouse */ + config.gappih = gappih; /* horiz inner gap between windows */ + config.gappiv = gappiv; /* vert inner gap between windows */ + config.gappoh = + gappoh; /* horiz outer gap between windows and screen edge */ + config.gappov = gappov; /* vert outer gap between windows and screen edge */ - config.scroller_structs = scroller_structs; - config.scroller_default_proportion = scroller_default_proportion; - config.scroller_default_proportion_single = - scroller_default_proportion_single; - config.scroller_focus_center = scroller_focus_center; - config.scroller_prefer_center = scroller_prefer_center; - config.focus_cross_monitor = focus_cross_monitor; - config.focus_cross_tag = focus_cross_tag; - config.single_scratchpad = single_scratchpad; - config.xwayland_persistence = xwayland_persistence; - config.no_border_when_single = no_border_when_single; - config.snap_distance = snap_distance; - config.drag_tile_to_tile = drag_tile_to_tile; - config.enable_floating_snap = enable_floating_snap; - config.swipe_min_threshold = swipe_min_threshold; + config.scroller_structs = scroller_structs; + config.scroller_default_proportion = scroller_default_proportion; + config.scroller_default_proportion_single = + scroller_default_proportion_single; + config.scroller_focus_center = scroller_focus_center; + config.scroller_prefer_center = scroller_prefer_center; + config.focus_cross_monitor = focus_cross_monitor; + config.focus_cross_tag = focus_cross_tag; + config.single_scratchpad = single_scratchpad; + config.xwayland_persistence = xwayland_persistence; + config.no_border_when_single = no_border_when_single; + config.snap_distance = snap_distance; + config.drag_tile_to_tile = drag_tile_to_tile; + config.enable_floating_snap = enable_floating_snap; + config.swipe_min_threshold = swipe_min_threshold; - config.bypass_surface_visibility = - bypass_surface_visibility; /* 1 means idle inhibitors will disable idle - tracking even if it's surface isn't visible - */ + config.bypass_surface_visibility = + bypass_surface_visibility; /* 1 means idle inhibitors will disable idle + tracking even if it's surface isn't + visible + */ - config.borderpx = borderpx; - config.overviewgappi = overviewgappi; /* overview时 窗口与边缘 缝隙大小 */ - config.overviewgappo = overviewgappo; /* overview时 窗口与窗口 缝隙大小 */ - config.cursor_hide_timeout = cursor_hide_timeout; + config.borderpx = borderpx; + config.overviewgappi = overviewgappi; /* overview时 窗口与边缘 缝隙大小 */ + config.overviewgappo = overviewgappo; /* overview时 窗口与窗口 缝隙大小 */ + config.cursor_hide_timeout = cursor_hide_timeout; - config.warpcursor = warpcursor; /* Warp cursor to focused client */ + config.warpcursor = warpcursor; /* Warp cursor to focused client */ - config.repeat_rate = repeat_rate; - config.repeat_delay = repeat_delay; + config.repeat_rate = repeat_rate; + config.repeat_delay = repeat_delay; - /* Trackpad */ - config.tap_to_click = tap_to_click; - config.tap_and_drag = tap_and_drag; - config.drag_lock = drag_lock; - config.mouse_natural_scrolling = mouse_natural_scrolling; - config.cursor_size = cursor_size; - config.trackpad_natural_scrolling = trackpad_natural_scrolling; - config.disable_while_typing = disable_while_typing; - config.left_handed = left_handed; - config.middle_button_emulation = middle_button_emulation; - config.accel_profile = accel_profile; - config.accel_speed = accel_speed; + /* Trackpad */ + config.tap_to_click = tap_to_click; + config.tap_and_drag = tap_and_drag; + config.drag_lock = drag_lock; + config.mouse_natural_scrolling = mouse_natural_scrolling; + config.cursor_size = cursor_size; + config.trackpad_natural_scrolling = trackpad_natural_scrolling; + config.disable_while_typing = disable_while_typing; + config.left_handed = left_handed; + config.middle_button_emulation = middle_button_emulation; + config.accel_profile = accel_profile; + config.accel_speed = accel_speed; - memcpy(config.animation_curve_move, animation_curve_move, - sizeof(animation_curve_move)); - memcpy(config.animation_curve_open, animation_curve_open, - sizeof(animation_curve_open)); - memcpy(config.animation_curve_tag, animation_curve_tag, - sizeof(animation_curve_tag)); - memcpy(config.animation_curve_close, animation_curve_close, - sizeof(animation_curve_close)); + memcpy(config.animation_curve_move, animation_curve_move, + sizeof(animation_curve_move)); + memcpy(config.animation_curve_open, animation_curve_open, + sizeof(animation_curve_open)); + memcpy(config.animation_curve_tag, animation_curve_tag, + sizeof(animation_curve_tag)); + memcpy(config.animation_curve_close, animation_curve_close, + sizeof(animation_curve_close)); - memcpy(config.rootcolor, rootcolor, sizeof(rootcolor)); - memcpy(config.bordercolor, bordercolor, sizeof(bordercolor)); - memcpy(config.focuscolor, focuscolor, sizeof(focuscolor)); - memcpy(config.maxmizescreencolor, maxmizescreencolor, - sizeof(maxmizescreencolor)); - memcpy(config.urgentcolor, urgentcolor, sizeof(urgentcolor)); - memcpy(config.scratchpadcolor, scratchpadcolor, sizeof(scratchpadcolor)); - memcpy(config.globalcolor, globalcolor, sizeof(globalcolor)); - memcpy(config.overlaycolor, overlaycolor, sizeof(overlaycolor)); + memcpy(config.rootcolor, rootcolor, sizeof(rootcolor)); + memcpy(config.bordercolor, bordercolor, sizeof(bordercolor)); + memcpy(config.focuscolor, focuscolor, sizeof(focuscolor)); + memcpy(config.maxmizescreencolor, maxmizescreencolor, + sizeof(maxmizescreencolor)); + memcpy(config.urgentcolor, urgentcolor, sizeof(urgentcolor)); + memcpy(config.scratchpadcolor, scratchpadcolor, sizeof(scratchpadcolor)); + memcpy(config.globalcolor, globalcolor, sizeof(globalcolor)); + memcpy(config.overlaycolor, overlaycolor, sizeof(overlaycolor)); } void set_default_key_bindings(Config *config) { - // 计算默认按键绑定的数量 - size_t default_key_bindings_count = - sizeof(default_key_bindings) / sizeof(KeyBinding); + // 计算默认按键绑定的数量 + size_t default_key_bindings_count = + sizeof(default_key_bindings) / sizeof(KeyBinding); - // 重新分配内存以容纳新的默认按键绑定 - config->key_bindings = - realloc(config->key_bindings, - (config->key_bindings_count + default_key_bindings_count) * - sizeof(KeyBinding)); - if (!config->key_bindings) { - return; - } + // 重新分配内存以容纳新的默认按键绑定 + config->key_bindings = + realloc(config->key_bindings, + (config->key_bindings_count + default_key_bindings_count) * + sizeof(KeyBinding)); + if (!config->key_bindings) { + return; + } - // 将默认按键绑定复制到配置的按键绑定数组中 - for (size_t i = 0; i < default_key_bindings_count; i++) { - config->key_bindings[config->key_bindings_count + i] = - default_key_bindings[i]; - } + // 将默认按键绑定复制到配置的按键绑定数组中 + for (size_t i = 0; i < default_key_bindings_count; i++) { + config->key_bindings[config->key_bindings_count + i] = + default_key_bindings[i]; + } - // 更新按键绑定的总数 - config->key_bindings_count += default_key_bindings_count; + // 更新按键绑定的总数 + config->key_bindings_count += default_key_bindings_count; } void parse_config(void) { - char filename[1024]; + char filename[1024]; - free_config(); + free_config(); - // 重置config结构体,确保所有指针初始化为NULL - memset(&config, 0, sizeof(config)); + // 重置config结构体,确保所有指针初始化为NULL + memset(&config, 0, sizeof(config)); - // 初始化动态数组的指针为NULL,避免野指针 - config.window_rules = NULL; - config.window_rules_count = 0; - config.monitor_rules = NULL; - config.monitor_rules_count = 0; - config.key_bindings = NULL; - config.key_bindings_count = 0; - config.mouse_bindings = NULL; - config.mouse_bindings_count = 0; - config.axis_bindings = NULL; - config.axis_bindings_count = 0; - config.gesture_bindings = NULL; - config.gesture_bindings_count = 0; - config.exec = NULL; - config.exec_count = 0; - config.exec_once = NULL; - config.exec_once_count = 0; - config.scroller_proportion_preset = NULL; - config.scroller_proportion_preset_count = 0; - config.circle_layout = NULL; - config.circle_layout_count = 0; - config.tag_rules = NULL; - config.tag_rules_count = 0; - config.cursor_theme = NULL; + // 初始化动态数组的指针为NULL,避免野指针 + config.window_rules = NULL; + config.window_rules_count = 0; + config.monitor_rules = NULL; + config.monitor_rules_count = 0; + config.key_bindings = NULL; + config.key_bindings_count = 0; + config.mouse_bindings = NULL; + config.mouse_bindings_count = 0; + config.axis_bindings = NULL; + config.axis_bindings_count = 0; + config.gesture_bindings = NULL; + config.gesture_bindings_count = 0; + config.exec = NULL; + config.exec_count = 0; + config.exec_once = NULL; + config.exec_once_count = 0; + config.scroller_proportion_preset = NULL; + config.scroller_proportion_preset_count = 0; + config.circle_layout = NULL; + config.circle_layout_count = 0; + config.tag_rules = NULL; + config.tag_rules_count = 0; + config.cursor_theme = NULL; - // 获取 MAOMAOCONFIG 环境变量 - const char *maomaoconfig = getenv("MAOMAOCONFIG"); + // 获取 MAOMAOCONFIG 环境变量 + const char *maomaoconfig = getenv("MAOMAOCONFIG"); - // 如果 MAOMAOCONFIG 环境变量不存在或为空,则使用 HOME 环境变量 - if (!maomaoconfig || maomaoconfig[0] == '\0') { - // 获取当前用户家目录 - const char *homedir = getenv("HOME"); - if (!homedir) { - // 如果获取失败,则无法继续 - return; - } - // 构建日志文件路径 - snprintf(filename, sizeof(filename), "%s/.config/maomao/config.conf", - homedir); + // 如果 MAOMAOCONFIG 环境变量不存在或为空,则使用 HOME 环境变量 + if (!maomaoconfig || maomaoconfig[0] == '\0') { + // 获取当前用户家目录 + const char *homedir = getenv("HOME"); + if (!homedir) { + // 如果获取失败,则无法继续 + return; + } + // 构建日志文件路径 + snprintf(filename, sizeof(filename), "%s/.config/maomao/config.conf", + homedir); - // 检查文件是否存在 - if (access(filename, F_OK) != 0) { - // 如果文件不存在,则使用 /etc/maomao/config.conf - snprintf(filename, sizeof(filename), "%s/maomao/config.conf", SYSCONFDIR); - } - } else { - // 使用 MAOMAOCONFIG 环境变量作为配置文件夹路径 - snprintf(filename, sizeof(filename), "%s/config.conf", maomaoconfig); - } + // 检查文件是否存在 + if (access(filename, F_OK) != 0) { + // 如果文件不存在,则使用 /etc/maomao/config.conf + snprintf(filename, sizeof(filename), "%s/maomao/config.conf", + SYSCONFDIR); + } + } else { + // 使用 MAOMAOCONFIG 环境变量作为配置文件夹路径 + snprintf(filename, sizeof(filename), "%s/config.conf", maomaoconfig); + } - set_value_default(); - parse_config_file(&config, filename); - set_default_key_bindings(&config); - override_config(); + set_value_default(); + parse_config_file(&config, filename); + set_default_key_bindings(&config); + override_config(); } void reload_config(const Arg *arg) { - Client *c; - Monitor *m; - int i, jk; - Keyboard *kb; - parse_config(); - init_baked_points(); - handlecursoractivity(); - run_exec(); + Client *c; + Monitor *m; + int i, jk; + Keyboard *kb; + parse_config(); + init_baked_points(); + handlecursoractivity(); + run_exec(); - // reset border width when config change - wl_list_for_each(c, &clients, link) { - if (c && !c->iskilling) { - if (c->bw) { - c->bw = borderpx; - } - } - } + // reset border width when config change + wl_list_for_each(c, &clients, link) { + if (c && !c->iskilling) { + if (c->bw) { + c->bw = borderpx; + } + } + } - // reset keyboard repeat rate when config change - wl_list_for_each(kb, &keyboards, link) { - wlr_keyboard_set_repeat_info(kb->wlr_keyboard, repeat_rate, repeat_delay); - } + // reset keyboard repeat rate when config change + wl_list_for_each(kb, &keyboards, link) { + wlr_keyboard_set_repeat_info(kb->wlr_keyboard, repeat_rate, + repeat_delay); + } - // reset master status when config change - for (i = 0; i <= LENGTH(tags); i++) { - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) { - continue; - } - m->pertag->nmasters[i] = default_nmaster; - m->pertag->mfacts[i] = default_mfact; - m->pertag->smfacts[i] = default_smfact; - m->gappih = gappih; - m->gappiv = gappiv; - m->gappoh = gappoh; - m->gappov = gappov; - } - } + // reset master status when config change + for (i = 0; i <= LENGTH(tags); i++) { + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + m->pertag->nmasters[i] = default_nmaster; + m->pertag->mfacts[i] = default_mfact; + m->pertag->smfacts[i] = default_smfact; + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; + } + } - // reset tag status by tag rules - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) { - continue; - } + // reset tag status by tag rules + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } - for (i = 0; i <= LENGTH(tags); i++) { + for (i = 0; i <= LENGTH(tags); i++) { - if (i > 0 && config.tag_rules && strlen(config.tag_rules[i - 1].layout_name) > 0) { - for (jk = 0; jk < LENGTH(layouts); jk++) { - if (strcmp(layouts[jk].name, config.tag_rules[i - 1].layout_name) == - 0) { - m->pertag->ltidxs[i] = &layouts[jk]; - } - } - } - } - } + if (i > 0 && config.tag_rules && + strlen(config.tag_rules[i - 1].layout_name) > 0) { + for (jk = 0; jk < LENGTH(layouts); jk++) { + if (strcmp(layouts[jk].name, + config.tag_rules[i - 1].layout_name) == 0) { + m->pertag->ltidxs[i] = &layouts[jk]; + } + } + } + } + } - arrange(selmon, false); + arrange(selmon, false); } diff --git a/src/config/preset_config.h b/src/config/preset_config.h index 403085c..71b8bbf 100644 --- a/src/config/preset_config.h +++ b/src/config/preset_config.h @@ -4,22 +4,22 @@ /* 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} + {((hex >> 24) & 0xFF) / 255.0f, ((hex >> 16) & 0xFF) / 255.0f, \ + ((hex >> 8) & 0xFF) / 255.0f, (hex & 0xFF) / 255.0f} /* animaion */ -char *animation_type_open = "slide"; // 是否启用动画 //slide,zoom -char *animation_type_close = "slide"; // 是否启用动画 //slide,zoom -int animations = 1; // 是否启用动画 +char *animation_type_open = "slide"; // 是否启用动画 //slide,zoom +char *animation_type_close = "slide"; // 是否启用动画 //slide,zoom +int animations = 1; // 是否启用动画 int tag_animation_direction = HORIZONTAL; // 标签动画方向 -int animation_fade_in = 1; // Enable animation fade in -int animation_fade_out = 1; // Enable animation fade out -float zoom_initial_ratio = 0.5; // 动画起始窗口比例 +int animation_fade_in = 1; // Enable animation fade in +int animation_fade_out = 1; // Enable animation fade out +float zoom_initial_ratio = 0.5; // 动画起始窗口比例 float fadein_begin_opacity = 0.5; // Begin opac window ratio for animations float fadeout_begin_opacity = 0.5; // 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 +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 uint32_t animation_duration_close = 300; // Animation close speed double animation_curve_move[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 double animation_curve_open[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 @@ -28,20 +28,20 @@ double animation_curve_close[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 窗口比例 -double default_smfact = 0.5f; // 第一个stack窗口比例 -unsigned int default_nmaster = 1; // 默认master数量 +unsigned int focus_on_activate = 1; // 收到窗口激活请求是否自动跳转聚焦 +unsigned int new_is_master = 1; // 新窗口是否插在头部 +double default_mfact = 0.55f; // master 窗口比例 +double default_smfact = 0.5f; // 第一个stack窗口比例 +unsigned int default_nmaster = 1; // 默认master数量 /* logging */ int log_level = WLR_ERROR; unsigned int numlockon = 1; // 是否打开右边小键盘 -unsigned int capslock = 0; // 是否启用快捷键 +unsigned int capslock = 0; // 是否启用快捷键 -unsigned int ov_tab_mode = 0; // alt tab切换模式 -unsigned int hotarea_size = 10; // 热区大小,10x10 +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 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 */ @@ -65,8 +65,8 @@ unsigned int cursor_hide_timeout = 0; unsigned int swipe_min_threshold = 20; int bypass_surface_visibility = - 0; /* 1 means idle inhibitors will disable idle tracking even if it's - surface isn't visible */ + 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); @@ -78,36 +78,36 @@ float globalcolor[] = COLOR(0xb153a7ff); float overlaycolor[] = COLOR(0x14a57cff); // 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}; -int warpcursor = 1; /* Warp cursor to focused client */ +int warpcursor = 1; /* Warp cursor to focused client */ int xwayland_persistence = 1; /* xwayland persistence */ /* layout(s) */ 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"}, - {"K", deck, "deck"}, + // 最少两个,不能删除少于两个 + /* symbol arrange function name */ + {"S", scroller, "scroller"}, // 滚动布局 + {"T", tile, "tile"}, // 堆栈布局 + {"G", grid, "grid"}, {"M", monocle, "monocle"}, + {"D", dwindle, "dwindle"}, {"P", spiral, "spiral"}, + {"K", deck, "deck"}, }; /* 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; @@ -138,7 +138,7 @@ LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER */ enum libinput_config_click_method click_method = - LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; + LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; /* You can choose between: LIBINPUT_CONFIG_SEND_EVENTS_ENABLED @@ -152,7 +152,7 @@ LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE */ enum libinput_config_accel_profile accel_profile = - LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; + 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 @@ -164,5 +164,5 @@ 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", }; diff --git a/src/layout/layout.h b/src/layout/layout.h index cdcb738..c8490af 100644 --- a/src/layout/layout.h +++ b/src/layout/layout.h @@ -1,119 +1,122 @@ void fibonacci(Monitor *mon, int s) { - unsigned int i = 0, n = 0, nx, ny, nw, nh; - Client *c; - unsigned int cur_gappih = enablegaps ? mon->gappih : 0; - unsigned int cur_gappiv = enablegaps ? mon->gappiv : 0; - unsigned int cur_gappoh = enablegaps ? mon->gappoh : 0; - unsigned int cur_gappov = enablegaps ? mon->gappov : 0; + unsigned int i = 0, n = 0, nx, ny, nw, nh; + Client *c; + unsigned int cur_gappih = enablegaps ? mon->gappih : 0; + unsigned int cur_gappiv = enablegaps ? mon->gappiv : 0; + unsigned int cur_gappoh = enablegaps ? mon->gappoh : 0; + unsigned int cur_gappov = enablegaps ? mon->gappov : 0; - cur_gappih = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappih; - cur_gappiv = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappiv; - cur_gappoh = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappoh; - cur_gappov = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappov; - // Count visible clients - wl_list_for_each(c, &clients, link) if (VISIBLEON(c, mon) && ISTILED(c)) n++; + cur_gappih = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappih; + cur_gappiv = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappiv; + cur_gappoh = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappoh; + cur_gappov = smartgaps && mon->visible_clients == 1 ? 0 : cur_gappov; + // Count visible clients + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, mon) && ISTILED(c)) + n++; - if (n == 0) - return; + if (n == 0) + return; - // Initial dimensions including outer gaps - nx = mon->w.x + cur_gappoh; - ny = mon->w.y + cur_gappov; - nw = mon->w.width - 2 * cur_gappoh; - nh = mon->w.height - 2 * cur_gappov; + // Initial dimensions including outer gaps + nx = mon->w.x + cur_gappoh; + ny = mon->w.y + cur_gappov; + nw = mon->w.width - 2 * cur_gappoh; + nh = mon->w.height - 2 * cur_gappov; - // First pass: calculate client geometries - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, mon) || !ISTILED(c)) - continue; + // First pass: calculate client geometries + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, mon) || !ISTILED(c)) + continue; - c->bw = mon->visible_clients == 1 && no_border_when_single && smartgaps - ? 0 - : borderpx; - if ((i % 2 && nh / 2 > 2 * c->bw) || (!(i % 2) && nw / 2 > 2 * c->bw)) { - if (i < n - 1) { - if (i % 2) { - if (i == 1) { - nh = nh * mon->pertag->smfacts[mon->pertag->curtag]; - } else { - nh = (nh - cur_gappiv) / 2; - } - } else { - nw = (nw - cur_gappih) / 2; - } + c->bw = mon->visible_clients == 1 && no_border_when_single && smartgaps + ? 0 + : borderpx; + if ((i % 2 && nh / 2 > 2 * c->bw) || (!(i % 2) && nw / 2 > 2 * c->bw)) { + if (i < n - 1) { + if (i % 2) { + if (i == 1) { + nh = nh * mon->pertag->smfacts[mon->pertag->curtag]; + } else { + nh = (nh - cur_gappiv) / 2; + } + } else { + nw = (nw - cur_gappih) / 2; + } - if ((i % 4) == 2 && !s) - nx += nw + cur_gappih; - else if ((i % 4) == 3 && !s) - ny += nh + cur_gappiv; - } + if ((i % 4) == 2 && !s) + nx += nw + cur_gappih; + else if ((i % 4) == 3 && !s) + ny += nh + cur_gappiv; + } - if ((i % 4) == 0) { - if (s) - ny += nh + cur_gappiv; - else - ny -= nh + cur_gappiv; - } else if ((i % 4) == 1) - nx += nw + cur_gappih; - else if ((i % 4) == 2) - ny += nh + cur_gappiv; - else if ((i % 4) == 3) { - if (s) - nx += nw + cur_gappih; - else - nx -= nw + cur_gappih; - } + if ((i % 4) == 0) { + if (s) + ny += nh + cur_gappiv; + else + ny -= nh + cur_gappiv; + } else if ((i % 4) == 1) + nx += nw + cur_gappih; + else if ((i % 4) == 2) + ny += nh + cur_gappiv; + else if ((i % 4) == 3) { + if (s) + nx += nw + cur_gappih; + else + nx -= nw + cur_gappih; + } - if (i == 0) { - if (n != 1) - nw = (mon->w.width - 2 * cur_gappoh) * - mon->pertag->mfacts[mon->pertag->curtag]; - ny = mon->w.y + cur_gappov; - } else if (i == 1) { - nw = mon->w.width - 2 * cur_gappoh - nw - cur_gappih; - } else if (i == 2) { - nh = mon->w.height - 2 * cur_gappov - nh - cur_gappiv; - } - i++; - } + if (i == 0) { + if (n != 1) + nw = (mon->w.width - 2 * cur_gappoh) * + mon->pertag->mfacts[mon->pertag->curtag]; + ny = mon->w.y + cur_gappov; + } else if (i == 1) { + nw = mon->w.width - 2 * cur_gappoh - nw - cur_gappih; + } else if (i == 2) { + nh = mon->w.height - 2 * cur_gappov - nh - cur_gappiv; + } + i++; + } - c->geom = (struct wlr_box){.x = nx, .y = ny, .width = nw, .height = nh}; - } + c->geom = (struct wlr_box){.x = nx, .y = ny, .width = nw, .height = nh}; + } - // Second pass: apply gaps between clients - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, mon) || !ISTILED(c)) - continue; + // Second pass: apply gaps between clients + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, mon) || !ISTILED(c)) + continue; - unsigned int right_gap = 0; - unsigned int bottom_gap = 0; - Client *nc; + unsigned int right_gap = 0; + unsigned int bottom_gap = 0; + Client *nc; - wl_list_for_each(nc, &clients, link) { - if (!VISIBLEON(nc, mon) || !ISTILED(nc)) - continue; + wl_list_for_each(nc, &clients, link) { + if (!VISIBLEON(nc, mon) || !ISTILED(nc)) + continue; - if (c == nc) - continue; + if (c == nc) + continue; - // Check for right neighbor - if (c->geom.y == nc->geom.y && c->geom.x + c->geom.width == nc->geom.x) { - right_gap = cur_gappih; - } + // Check for right neighbor + if (c->geom.y == nc->geom.y && + c->geom.x + c->geom.width == nc->geom.x) { + right_gap = cur_gappih; + } - // Check for bottom neighbor - if (c->geom.x == nc->geom.x && c->geom.y + c->geom.height == nc->geom.y) { - bottom_gap = cur_gappiv; - } - } + // Check for bottom neighbor + if (c->geom.x == nc->geom.x && + c->geom.y + c->geom.height == nc->geom.y) { + bottom_gap = cur_gappiv; + } + } - resize(c, - (struct wlr_box){.x = c->geom.x, - .y = c->geom.y, - .width = c->geom.width - right_gap, - .height = c->geom.height - bottom_gap}, - 0); - } + resize(c, + (struct wlr_box){.x = c->geom.x, + .y = c->geom.y, + .width = c->geom.width - right_gap, + .height = c->geom.height - bottom_gap}, + 0); + } } void dwindle(Monitor *mon) { fibonacci(mon, 1); } @@ -122,370 +125,377 @@ void spiral(Monitor *mon) { fibonacci(mon, 0); } // 网格布局窗口大小和位置计算 void grid(Monitor *m) { - unsigned int i, n; - unsigned int cx, cy, cw, ch; - unsigned int dx; - unsigned int cols, rows, overcols; - Client *c; - n = 0; + unsigned int i, n; + unsigned int cx, cy, cw, ch; + unsigned int dx; + unsigned int cols, rows, overcols; + Client *c; + n = 0; - // 第一次遍历,计算 n 的值 - wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { - n++; - } - } + // 第一次遍历,计算 n 的值 + wl_list_for_each(c, &clients, link) { + if (VISIBLEON(c, c->mon) && !c->isunglobal && + (m->isoverview || ISTILED(c))) { + n++; + } + } - if (n == 0) { - return; // 没有需要处理的客户端,直接返回 - } + if (n == 0) { + return; // 没有需要处理的客户端,直接返回 + } - if (n == 1) { - wl_list_for_each(c, &clients, link) { - c->bw = m->visible_clients == 1 && no_border_when_single && smartgaps - ? 0 - : borderpx; - if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { - cw = (m->w.width - 2 * overviewgappo) * 0.7; - ch = (m->w.height - 2 * overviewgappo) * 0.8; - c->geom.x = m->w.x + (m->w.width - cw) / 2; - c->geom.y = m->w.y + (m->w.height - ch) / 2; - c->geom.width = cw - 2 * c->bw; - c->geom.height = ch - 2 * c->bw; - resize(c, c->geom, 0); - return; - } - } - } + if (n == 1) { + wl_list_for_each(c, &clients, link) { + c->bw = + m->visible_clients == 1 && no_border_when_single && smartgaps + ? 0 + : borderpx; + if (VISIBLEON(c, c->mon) && !c->isunglobal && + (m->isoverview || ISTILED(c))) { + cw = (m->w.width - 2 * overviewgappo) * 0.7; + ch = (m->w.height - 2 * overviewgappo) * 0.8; + c->geom.x = m->w.x + (m->w.width - cw) / 2; + c->geom.y = m->w.y + (m->w.height - ch) / 2; + c->geom.width = cw - 2 * c->bw; + c->geom.height = ch - 2 * c->bw; + resize(c, c->geom, 0); + return; + } + } + } - if (n == 2) { - cw = (m->w.width - 2 * overviewgappo - overviewgappi) / 2; - ch = (m->w.height - 2 * overviewgappo) * 0.65; - i = 0; - wl_list_for_each(c, &clients, link) { - c->bw = m->visible_clients == 1 && no_border_when_single && smartgaps - ? 0 - : borderpx; - if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { - if (i == 0) { - c->geom.x = m->w.x + overviewgappo; - c->geom.y = m->w.y + (m->w.height - ch) / 2 + overviewgappo; - c->geom.width = cw - 2 * c->bw; - c->geom.height = ch - 2 * c->bw; - resize(c, c->geom, 0); - } else if (i == 1) { - c->geom.x = m->w.x + cw + overviewgappo + overviewgappi; - c->geom.y = m->w.y + (m->w.height - ch) / 2 + overviewgappo; - c->geom.width = cw - 2 * c->bw; - c->geom.height = ch - 2 * c->bw; - resize(c, c->geom, 0); - } - i++; - } - } - return; - } + if (n == 2) { + cw = (m->w.width - 2 * overviewgappo - overviewgappi) / 2; + ch = (m->w.height - 2 * overviewgappo) * 0.65; + i = 0; + wl_list_for_each(c, &clients, link) { + c->bw = + m->visible_clients == 1 && no_border_when_single && smartgaps + ? 0 + : borderpx; + if (VISIBLEON(c, c->mon) && !c->isunglobal && + (m->isoverview || ISTILED(c))) { + if (i == 0) { + c->geom.x = m->w.x + overviewgappo; + c->geom.y = m->w.y + (m->w.height - ch) / 2 + overviewgappo; + c->geom.width = cw - 2 * c->bw; + c->geom.height = ch - 2 * c->bw; + resize(c, c->geom, 0); + } else if (i == 1) { + c->geom.x = m->w.x + cw + overviewgappo + overviewgappi; + c->geom.y = m->w.y + (m->w.height - ch) / 2 + overviewgappo; + c->geom.width = cw - 2 * c->bw; + c->geom.height = ch - 2 * c->bw; + resize(c, c->geom, 0); + } + i++; + } + } + return; + } - // 计算列数和行数 - for (cols = 0; cols <= n / 2; cols++) { - if (cols * cols >= n) { - break; - } - } - rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols; + // 计算列数和行数 + for (cols = 0; cols <= n / 2; cols++) { + if (cols * cols >= n) { + break; + } + } + rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols; - // 计算每个客户端的高度和宽度 - ch = (m->w.height - 2 * overviewgappo - (rows - 1) * overviewgappi) / rows; - cw = (m->w.width - 2 * overviewgappo - (cols - 1) * overviewgappi) / cols; + // 计算每个客户端的高度和宽度 + ch = (m->w.height - 2 * overviewgappo - (rows - 1) * overviewgappi) / rows; + cw = (m->w.width - 2 * overviewgappo - (cols - 1) * overviewgappi) / cols; - // 处理多余的列 - overcols = n % cols; - if (overcols) { - dx = (m->w.width - overcols * cw - (overcols - 1) * overviewgappi) / 2 - - overviewgappo; - } + // 处理多余的列 + overcols = n % cols; + if (overcols) { + dx = (m->w.width - overcols * cw - (overcols - 1) * overviewgappi) / 2 - + overviewgappo; + } - // 调整每个客户端的位置和大小 - i = 0; - wl_list_for_each(c, &clients, link) { - c->bw = m->visible_clients == 1 && no_border_when_single && smartgaps - ? 0 - : borderpx; - if (VISIBLEON(c, c->mon) && !c->isunglobal && (m->isoverview || ISTILED(c))) { - cx = m->w.x + (i % cols) * (cw + overviewgappi); - cy = m->w.y + (i / cols) * (ch + overviewgappi); - if (overcols && i >= n - overcols) { - cx += dx; - } - c->geom.x = cx + overviewgappo; - c->geom.y = cy + overviewgappo; - c->geom.width = cw - 2 * c->bw; - c->geom.height = ch - 2 * c->bw; - resize(c, c->geom, 0); - i++; - } - } + // 调整每个客户端的位置和大小 + i = 0; + wl_list_for_each(c, &clients, link) { + c->bw = m->visible_clients == 1 && no_border_when_single && smartgaps + ? 0 + : borderpx; + if (VISIBLEON(c, c->mon) && !c->isunglobal && + (m->isoverview || ISTILED(c))) { + cx = m->w.x + (i % cols) * (cw + overviewgappi); + cy = m->w.y + (i / cols) * (ch + overviewgappi); + if (overcols && i >= n - overcols) { + cx += dx; + } + c->geom.x = cx + overviewgappo; + c->geom.y = cy + overviewgappo; + c->geom.width = cw - 2 * c->bw; + c->geom.height = ch - 2 * c->bw; + resize(c, c->geom, 0); + i++; + } + } } void deck(Monitor *m) { - unsigned int mw, my; - int i, n = 0; - Client *c; - unsigned int cur_gappih = enablegaps ? m->gappih : 0; - unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; + unsigned int mw, my; + int i, n = 0; + Client *c; + unsigned int cur_gappih = enablegaps ? m->gappih : 0; + unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + unsigned int cur_gappov = enablegaps ? m->gappov : 0; - cur_gappih = smartgaps && m->visible_clients == 1 ? 0 : cur_gappih; - cur_gappiv = smartgaps && m->visible_clients == 1 ? 0 : cur_gappiv; - cur_gappoh = smartgaps && m->visible_clients == 1 ? 0 : cur_gappoh; - cur_gappov = smartgaps && m->visible_clients == 1 ? 0 : cur_gappov; + cur_gappih = smartgaps && m->visible_clients == 1 ? 0 : cur_gappih; + cur_gappiv = smartgaps && m->visible_clients == 1 ? 0 : cur_gappiv; + cur_gappoh = smartgaps && m->visible_clients == 1 ? 0 : cur_gappoh; + cur_gappov = smartgaps && m->visible_clients == 1 ? 0 : cur_gappov; - wl_list_for_each(c, &clients, link) if (VISIBLEON(c, m) && ISTILED(c)) n++; - if (n == 0) - return; + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, m) && ISTILED(c)) n++; + if (n == 0) + return; - // Calculate master width using mfact from pertag - float mfact = m->pertag ? m->pertag->mfacts[m->pertag->curtag] : m->mfact; + // Calculate master width using mfact from pertag + float mfact = m->pertag ? m->pertag->mfacts[m->pertag->curtag] : m->mfact; - // Calculate master width including outer gaps - if (n > m->nmaster) - mw = m->nmaster ? round((m->w.width - 2 * cur_gappoh) * mfact) : 0; - else - mw = m->w.width - 2 * cur_gappoh; + // Calculate master width including outer gaps + if (n > m->nmaster) + mw = m->nmaster ? round((m->w.width - 2 * cur_gappoh) * mfact) : 0; + else + mw = m->w.width - 2 * cur_gappoh; - i = my = 0; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || !ISTILED(c)) - continue; - if (i < m->nmaster) { - // Master area clients - resize(c, - (struct wlr_box){.x = m->w.x + cur_gappoh, - .y = m->w.y + cur_gappov + my, - .width = mw, - .height = - (m->w.height - cur_gappov - my - cur_gappiv) / - (MIN(n, m->nmaster) - i)}, - 0); - my += c->geom.height + cur_gappiv; - } else { - // Stack area clients - resize(c, - (struct wlr_box){.x = m->w.x + mw + cur_gappoh + cur_gappih, - .y = m->w.y + cur_gappov, - .width = - m->w.width - mw - 2 * cur_gappoh - cur_gappih, - .height = m->w.height - 2 * cur_gappov}, - 0); - if (c == focustop(m)) - wlr_scene_node_raise_to_top(&c->scene->node); - } - i++; - } + i = my = 0; + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || !ISTILED(c)) + continue; + if (i < m->nmaster) { + // Master area clients + resize(c, + (struct wlr_box){ + .x = m->w.x + cur_gappoh, + .y = m->w.y + cur_gappov + my, + .width = mw, + .height = (m->w.height - cur_gappov - my - cur_gappiv) / + (MIN(n, m->nmaster) - i)}, + 0); + my += c->geom.height + cur_gappiv; + } else { + // Stack area clients + resize(c, + (struct wlr_box){.x = m->w.x + mw + cur_gappoh + cur_gappih, + .y = m->w.y + cur_gappov, + .width = m->w.width - mw - 2 * cur_gappoh - + cur_gappih, + .height = m->w.height - 2 * cur_gappov}, + 0); + if (c == focustop(m)) + wlr_scene_node_raise_to_top(&c->scene->node); + } + i++; + } } // 滚动布局 void scroller(Monitor *m) { - unsigned int i, n; + unsigned int i, n; - Client *c, *root_client = NULL; - Client **tempClients = NULL; // 初始化为 NULL - n = 0; - struct wlr_box target_geom; - int focus_client_index = 0; - bool need_scroller = false; - unsigned int cur_gappih = enablegaps ? m->gappih : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; + Client *c, *root_client = NULL; + Client **tempClients = NULL; // 初始化为 NULL + n = 0; + struct wlr_box target_geom; + int focus_client_index = 0; + bool need_scroller = false; + unsigned int cur_gappih = enablegaps ? m->gappih : 0; + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + unsigned int cur_gappov = enablegaps ? m->gappov : 0; - cur_gappih = smartgaps && m->visible_clients == 1 ? 0 : cur_gappih; - cur_gappoh = smartgaps && m->visible_clients == 1 ? 0 : cur_gappoh; - cur_gappov = smartgaps && m->visible_clients == 1 ? 0 : cur_gappov; + cur_gappih = smartgaps && m->visible_clients == 1 ? 0 : cur_gappih; + cur_gappoh = smartgaps && m->visible_clients == 1 ? 0 : cur_gappoh; + cur_gappov = smartgaps && m->visible_clients == 1 ? 0 : cur_gappov; - unsigned int max_client_width = - m->w.width - 2 * scroller_structs - cur_gappih; + unsigned int max_client_width = + m->w.width - 2 * scroller_structs - cur_gappih; - // 第一次遍历,计算 n 的值 - wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && ISTILED(c)) { - n++; - } - } + // 第一次遍历,计算 n 的值 + wl_list_for_each(c, &clients, link) { + if (VISIBLEON(c, c->mon) && ISTILED(c)) { + n++; + } + } - if (n == 0) { - return; // 没有需要处理的客户端,直接返回 - } + if (n == 0) { + return; // 没有需要处理的客户端,直接返回 + } - // 动态分配内存 - tempClients = malloc(n * sizeof(Client *)); - if (!tempClients) { - // 处理内存分配失败的情况 - return; - } + // 动态分配内存 + tempClients = malloc(n * sizeof(Client *)); + if (!tempClients) { + // 处理内存分配失败的情况 + return; + } - // 第二次遍历,填充 tempClients - n = 0; - wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, c->mon) && ISTILED(c)) { - tempClients[n] = c; - n++; - } - } + // 第二次遍历,填充 tempClients + n = 0; + wl_list_for_each(c, &clients, link) { + if (VISIBLEON(c, c->mon) && ISTILED(c)) { + tempClients[n] = c; + n++; + } + } - if (n == 1) { - c = tempClients[0]; - target_geom.height = m->w.height - 2 * cur_gappov; - target_geom.width = - (m->w.width - 2 * cur_gappoh) * scroller_default_proportion_single; - 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; - resize(c, target_geom, 0); - free(tempClients); // 释放内存 - return; - } + if (n == 1) { + c = tempClients[0]; + target_geom.height = m->w.height - 2 * cur_gappov; + target_geom.width = + (m->w.width - 2 * cur_gappoh) * scroller_default_proportion_single; + 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; + resize(c, target_geom, 0); + free(tempClients); // 释放内存 + return; + } - if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating && - !m->sel->ismaxmizescreen && !m->sel->isfullscreen) { - root_client = m->sel; - } else if (m->prevsel && !client_is_unmanaged(m->prevsel) && - !m->prevsel->isfloating && !m->prevsel->ismaxmizescreen && - !m->prevsel->isfullscreen) { - root_client = m->prevsel; - } else { - root_client = center_select(m); - } + if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating && + !m->sel->ismaxmizescreen && !m->sel->isfullscreen) { + root_client = m->sel; + } else if (m->prevsel && !client_is_unmanaged(m->prevsel) && + !m->prevsel->isfloating && !m->prevsel->ismaxmizescreen && + !m->prevsel->isfullscreen) { + root_client = m->prevsel; + } else { + root_client = center_select(m); + } - if (!root_client) { - free(tempClients); // 释放内存 - return; - } + if (!root_client) { + free(tempClients); // 释放内存 + return; + } - for (i = 0; i < n; i++) { - c = tempClients[i]; - if (root_client == c) { - if (!c->is_open_animation && c->geom.x >= m->w.x + scroller_structs && - c->geom.x + c->geom.width <= m->w.x + m->w.width - scroller_structs) { - need_scroller = false; - } else { - need_scroller = true; - } - focus_client_index = i; - break; - } - } + for (i = 0; i < n; i++) { + c = tempClients[i]; + if (root_client == c) { + if (!c->is_open_animation && + c->geom.x >= m->w.x + scroller_structs && + c->geom.x + c->geom.width <= + m->w.x + m->w.width - scroller_structs) { + need_scroller = false; + } else { + need_scroller = true; + } + focus_client_index = i; + break; + } + } - target_geom.height = m->w.height - 2 * cur_gappov; - target_geom.width = max_client_width * c->scroller_proportion; - target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; + target_geom.height = m->w.height - 2 * cur_gappov; + target_geom.width = max_client_width * c->scroller_proportion; + target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; - if (need_scroller) { - if (scroller_focus_center || - ((!m->prevsel || - (m->prevsel->scroller_proportion * max_client_width) + - (root_client->scroller_proportion * max_client_width) > - m->w.width - 2 * scroller_structs - cur_gappih) && - scroller_prefer_center)) { - 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; - } - resize(tempClients[focus_client_index], target_geom, 0); - } else { - target_geom.x = c->geom.x; - resize(tempClients[focus_client_index], target_geom, 0); - } + if (need_scroller) { + if (scroller_focus_center || + ((!m->prevsel || + (m->prevsel->scroller_proportion * max_client_width) + + (root_client->scroller_proportion * max_client_width) > + m->w.width - 2 * scroller_structs - cur_gappih) && + scroller_prefer_center)) { + 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; + } + resize(tempClients[focus_client_index], target_geom, 0); + } else { + target_geom.x = c->geom.x; + resize(tempClients[focus_client_index], target_geom, 0); + } - for (i = 1; i <= focus_client_index; i++) { - c = tempClients[focus_client_index - i]; - target_geom.width = max_client_width * c->scroller_proportion; - target_geom.x = tempClients[focus_client_index - i + 1]->geom.x - - cur_gappih - target_geom.width; - resize(c, target_geom, 0); - } + for (i = 1; i <= focus_client_index; i++) { + c = tempClients[focus_client_index - i]; + target_geom.width = max_client_width * c->scroller_proportion; + target_geom.x = tempClients[focus_client_index - i + 1]->geom.x - + cur_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.width = max_client_width * c->scroller_proportion; - target_geom.x = tempClients[focus_client_index + i - 1]->geom.x + - cur_gappih + - tempClients[focus_client_index + i - 1]->geom.width; - resize(c, target_geom, 0); - } + for (i = 1; i < n - focus_client_index; i++) { + c = tempClients[focus_client_index + i]; + target_geom.width = max_client_width * c->scroller_proportion; + target_geom.x = tempClients[focus_client_index + i - 1]->geom.x + + cur_gappih + + tempClients[focus_client_index + i - 1]->geom.width; + resize(c, target_geom, 0); + } - free(tempClients); // 最后释放内存 + free(tempClients); // 最后释放内存 } void tile(Monitor *m) { - unsigned int i, n = 0, h, r, ie = enablegaps, mw, my, ty; - Client *c; + unsigned int i, n = 0, h, r, ie = enablegaps, mw, my, ty; + Client *c; - wl_list_for_each(c, &clients, - link) if (VISIBLEON(c, m) && ISTILED(c)) n++; - if (n == 0) - return; + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, m) && ISTILED(c)) n++; + if (n == 0) + return; - unsigned int cur_gappih = enablegaps ? m->gappih : 0; - unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; + unsigned int cur_gappih = enablegaps ? m->gappih : 0; + unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + unsigned int cur_gappov = enablegaps ? m->gappov : 0; - cur_gappih = smartgaps && m->visible_clients == 1 ? 0 : cur_gappih; - cur_gappiv = smartgaps && m->visible_clients == 1 ? 0 : cur_gappiv; - cur_gappoh = smartgaps && m->visible_clients == 1 ? 0 : cur_gappoh; - cur_gappov = smartgaps && m->visible_clients == 1 ? 0 : cur_gappov; + cur_gappih = smartgaps && m->visible_clients == 1 ? 0 : cur_gappih; + cur_gappiv = smartgaps && m->visible_clients == 1 ? 0 : cur_gappiv; + cur_gappoh = smartgaps && m->visible_clients == 1 ? 0 : cur_gappoh; + cur_gappov = smartgaps && m->visible_clients == 1 ? 0 : cur_gappov; - if (n > selmon->pertag->nmasters[selmon->pertag->curtag]) - mw = selmon->pertag->nmasters[selmon->pertag->curtag] - ? (m->w.width + cur_gappiv * ie) * - selmon->pertag->mfacts[selmon->pertag->curtag] - : 0; - else - mw = m->w.width - 2 * cur_gappov + cur_gappiv * ie; - i = 0; - my = ty = cur_gappoh; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || !ISTILED(c)) - continue; - if (i < selmon->pertag->nmasters[selmon->pertag->curtag]) { - r = MIN(n, selmon->pertag->nmasters[selmon->pertag->curtag]) - i; - h = (m->w.height - my - cur_gappoh - cur_gappih * ie * (r - 1)) / r; - resize(c, - (struct wlr_box){.x = m->w.x + cur_gappov, - .y = m->w.y + my, - .width = mw - cur_gappiv * ie, - .height = h}, - 0); - my += c->geom.height + cur_gappih * ie; - } else { - r = n - i; - h = (m->w.height - ty - cur_gappoh - cur_gappih * ie * (r - 1)) / r; - resize(c, - (struct wlr_box){.x = m->w.x + mw + cur_gappov, - .y = m->w.y + ty, - .width = m->w.width - mw - 2 * cur_gappov, - .height = h}, - 0); - ty += c->geom.height + cur_gappih * ie; - } - i++; - } + if (n > selmon->pertag->nmasters[selmon->pertag->curtag]) + mw = selmon->pertag->nmasters[selmon->pertag->curtag] + ? (m->w.width + cur_gappiv * ie) * + selmon->pertag->mfacts[selmon->pertag->curtag] + : 0; + else + mw = m->w.width - 2 * cur_gappov + cur_gappiv * ie; + i = 0; + my = ty = cur_gappoh; + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || !ISTILED(c)) + continue; + if (i < selmon->pertag->nmasters[selmon->pertag->curtag]) { + r = MIN(n, selmon->pertag->nmasters[selmon->pertag->curtag]) - i; + h = (m->w.height - my - cur_gappoh - cur_gappih * ie * (r - 1)) / r; + resize(c, + (struct wlr_box){.x = m->w.x + cur_gappov, + .y = m->w.y + my, + .width = mw - cur_gappiv * ie, + .height = h}, + 0); + my += c->geom.height + cur_gappih * ie; + } else { + r = n - i; + h = (m->w.height - ty - cur_gappoh - cur_gappih * ie * (r - 1)) / r; + resize(c, + (struct wlr_box){.x = m->w.x + mw + cur_gappov, + .y = m->w.y + ty, + .width = m->w.width - mw - 2 * cur_gappov, + .height = h}, + 0); + ty += c->geom.height + cur_gappih * ie; + } + i++; + } } void // 17 monocle(Monitor *m) { - Client *c; + Client *c; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || !ISTILED(c)) - continue; - resize(c, m->w, 0); - } - if ((c = focustop(m))) - wlr_scene_node_raise_to_top(&c->scene->node); + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || !ISTILED(c)) + continue; + resize(c, m->w, 0); + } + if ((c = focustop(m))) + wlr_scene_node_raise_to_top(&c->scene->node); } \ No newline at end of file diff --git a/src/maomao.c b/src/maomao.c index f51e926..d9a7d34 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -91,23 +91,24 @@ #define GEZERO(A) ((A) >= 0 ? (A) : 0) #define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) #define ISTILED(A) \ - (!(A)->isfloating && !(A)->isminied && !(A)->iskilling && !client_should_ignore_focus(A) && \ - !(A)->isunglobal && !(A)->animation.tagouting && !(A)->ismaxmizescreen && !(A)->isfullscreen) + (!(A)->isfloating && !(A)->isminied && !(A)->iskilling && \ + !client_should_ignore_focus(A) && !(A)->isunglobal && \ + !(A)->animation.tagouting && !(A)->ismaxmizescreen && !(A)->isfullscreen) #define VISIBLEON(C, M) \ - ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) + ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) #define END(A) ((A) + LENGTH(A)) #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)->overview_ismaxmizescreenbak || (A)->overview_isfullscreenbak) + ((A)->isfullscreen || (A)->ismaxmizescreen || \ + (A)->overview_ismaxmizescreenbak || (A)->overview_isfullscreenbak) #define LISTEN_STATIC(E, H) \ - do { \ - struct wl_listener *_l = ecalloc(1, sizeof(*_l)); \ - _l->notify = (H); \ - wl_signal_add((E), _l); \ - } while (0) + do { \ + struct wl_listener *_l = ecalloc(1, sizeof(*_l)); \ + _l->notify = (H); \ + wl_signal_add((E), _l); \ + } while (0) #define BAKED_POINTS_COUNT 256 @@ -115,329 +116,329 @@ enum { VERTICAL, HORIZONTAL }; enum { SWIPE_UP, SWIPE_DOWN, SWIPE_LEFT, SWIPE_RIGHT }; enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ -enum { XDGShell, LayerShell, X11 }; /* client types */ -enum { AxisUp, AxisDown, AxisLeft, AxisRight }; // 滚轮滚动的方向 +enum { XDGShell, LayerShell, X11 }; /* client types */ +enum { AxisUp, AxisDown, AxisLeft, AxisRight }; // 滚轮滚动的方向 enum { - LyrBg, - LyrBottom, - LyrTile, - LyrFloat, - LyrFS, - LyrTop, - LyrOverlay, - LyrIMPopup, // text-input layer - LyrFadeOut, - LyrBlock, - NUM_LAYERS + LyrBg, + LyrBottom, + LyrTile, + LyrFloat, + LyrFS, + LyrTop, + LyrOverlay, + LyrIMPopup, // text-input layer + LyrFadeOut, + LyrBlock, + NUM_LAYERS }; /* scene layers */ #ifdef XWAYLAND enum { - NetWMWindowTypeDialog, - NetWMWindowTypeSplash, - NetWMWindowTypeToolbar, - NetWMWindowTypeUtility, - NetLast + NetWMWindowTypeDialog, + NetWMWindowTypeSplash, + NetWMWindowTypeToolbar, + NetWMWindowTypeUtility, + NetLast }; /* EWMH atoms */ #endif enum { UP, DOWN, LEFT, RIGHT, UNDIR }; /* smartmovewin */ enum { NONE, OPEN, MOVE, CLOSE, TAG }; struct vec2 { - double x, y; + double x, y; }; struct uvec2 { - int x, y; + int x, y; }; typedef struct { - int i; - int i2; - float f; - float f2; - char *v; - char *v2; - char *v3; - unsigned int ui; - unsigned int ui2; + int i; + int i2; + float f; + float f2; + char *v; + char *v2; + char *v3; + unsigned int ui; + unsigned int ui2; } Arg; typedef struct { - unsigned int mod; - unsigned int button; - void (*func)(const Arg *); - const Arg arg; + unsigned int mod; + unsigned int button; + void (*func)(const Arg *); + const Arg arg; } Button; // 鼠标按键 typedef struct { - unsigned int mod; - unsigned int dir; - void (*func)(const Arg *); - const Arg arg; + unsigned int mod; + unsigned int dir; + void (*func)(const Arg *); + const Arg arg; } Axis; struct dwl_animation { - bool should_animate; - bool running; - bool tagining; - bool tagouted; - bool tagouting; - bool begin_fade_in; - bool from_rule; - uint32_t total_frames; - uint32_t passed_frames; - uint32_t duration; - struct wlr_box initial; - struct wlr_box current; - int action; + bool should_animate; + bool running; + bool tagining; + bool tagouted; + bool tagouting; + bool begin_fade_in; + bool from_rule; + uint32_t total_frames; + uint32_t passed_frames; + uint32_t duration; + struct wlr_box initial; + struct wlr_box current; + int action; }; typedef struct Pertag Pertag; typedef struct Monitor Monitor; typedef struct { - float width_scale; - float height_scale; - int width; - int height; - bool should_scale; + float width_scale; + float height_scale; + int width; + int height; + bool should_scale; } animationScale; typedef struct Client Client; struct Client { - /* Must keep these three elements in this order */ - unsigned int type; /* XDGShell or X11* */ - struct wlr_box geom, pending, oldgeom, scratchpad_geom, animainit_geom, - overview_backup_geom, current; /* layout-relative, includes border */ - Monitor *mon; - struct wlr_scene_tree *scene; - struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ - struct wlr_scene_tree *scene_surface; - struct wl_list link; - struct wl_list flink; - struct wl_list fadeout_link; - union { - struct wlr_xdg_surface *xdg; - struct wlr_xwayland_surface *xwayland; - } surface; - struct wl_listener commit; - struct wl_listener map; - struct wl_listener maximize; - struct wl_listener minimize; - struct wl_listener unmap; - struct wl_listener destroy; - struct wl_listener set_title; - struct wl_listener fullscreen; + /* Must keep these three elements in this order */ + unsigned int type; /* XDGShell or X11* */ + struct wlr_box geom, pending, oldgeom, scratchpad_geom, animainit_geom, + overview_backup_geom, current; /* layout-relative, includes border */ + Monitor *mon; + struct wlr_scene_tree *scene; + struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ + struct wlr_scene_tree *scene_surface; + struct wl_list link; + struct wl_list flink; + struct wl_list fadeout_link; + union { + struct wlr_xdg_surface *xdg; + struct wlr_xwayland_surface *xwayland; + } surface; + struct wl_listener commit; + struct wl_listener map; + struct wl_listener maximize; + struct wl_listener minimize; + struct wl_listener unmap; + struct wl_listener destroy; + struct wl_listener set_title; + struct wl_listener fullscreen; #ifdef XWAYLAND - struct wl_listener activate; - struct wl_listener associate; - struct wl_listener dissociate; - struct wl_listener configure; - struct wl_listener set_hints; - struct wl_listener set_geometry; + struct wl_listener activate; + struct wl_listener associate; + struct wl_listener dissociate; + struct wl_listener configure; + struct wl_listener set_hints; + struct wl_listener set_geometry; #endif - unsigned int bw; - unsigned int tags, oldtags, mini_restore_tag; - bool dirty; - uint32_t configure_serial; - struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel; - int isfloating, isurgent, isfullscreen, isfakefullscreen, - need_float_size_reduce, isminied, isoverlay; - int ismaxmizescreen; - int overview_backup_bw; - int fullscreen_backup_x, fullscreen_backup_y, fullscreen_backup_w, - fullscreen_backup_h; - int overview_isfullscreenbak, overview_ismaxmizescreenbak, - overview_isfloatingbak; + unsigned int bw; + unsigned int tags, oldtags, mini_restore_tag; + bool dirty; + uint32_t configure_serial; + struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel; + int isfloating, isurgent, isfullscreen, isfakefullscreen, + need_float_size_reduce, isminied, isoverlay; + int ismaxmizescreen; + int overview_backup_bw; + int fullscreen_backup_x, fullscreen_backup_y, fullscreen_backup_w, + fullscreen_backup_h; + int overview_isfullscreenbak, overview_ismaxmizescreenbak, + overview_isfloatingbak; - struct wlr_xdg_toplevel_decoration_v1 *decoration; - struct wl_listener foreign_activate_request; - struct wl_listener foreign_fullscreen_request; - struct wl_listener foreign_close_request; - struct wl_listener foreign_destroy; - struct wl_listener set_decoration_mode; - struct wl_listener destroy_decoration; + struct wlr_xdg_toplevel_decoration_v1 *decoration; + struct wl_listener foreign_activate_request; + struct wl_listener foreign_fullscreen_request; + struct wl_listener foreign_close_request; + struct wl_listener foreign_destroy; + struct wl_listener set_decoration_mode; + struct wl_listener destroy_decoration; - const char *animation_type_open; - const char *animation_type_close; - int is_in_scratchpad; - int is_scratchpad_show; - int isglobal; - int isnoborder; - int isopensilent; - int isopenscratchpad; - int iskilling; - int isnamedscratchpand; - struct wlr_box bounds; - bool is_open_animation; - bool is_restoring_from_ov; - float scroller_proportion; - bool need_output_flush; - struct dwl_animation animation; - int isterm, noswallow; - pid_t pid; - Client *swallowing, *swallowedby; - bool is_clip_to_hide; - bool drag_to_tile; - bool fake_no_border; - int nofadein; - int nofadeout; - int no_force_center; - int isunglobal; + const char *animation_type_open; + const char *animation_type_close; + int is_in_scratchpad; + int is_scratchpad_show; + int isglobal; + int isnoborder; + int isopensilent; + int isopenscratchpad; + int iskilling; + int isnamedscratchpand; + struct wlr_box bounds; + bool is_open_animation; + bool is_restoring_from_ov; + float scroller_proportion; + bool need_output_flush; + struct dwl_animation animation; + int isterm, noswallow; + pid_t pid; + Client *swallowing, *swallowedby; + bool is_clip_to_hide; + bool drag_to_tile; + bool fake_no_border; + int nofadein; + int nofadeout; + int no_force_center; + int isunglobal; }; typedef struct { - struct wl_list link; - struct wl_resource *resource; - Monitor *mon; + struct wl_list link; + struct wl_resource *resource; + Monitor *mon; } DwlIpcOutput; typedef struct { - uint32_t mod; - xkb_keysym_t keysym; - void (*func)(const Arg *); - const Arg arg; + uint32_t mod; + xkb_keysym_t keysym; + void (*func)(const Arg *); + const Arg arg; } Key; typedef struct { - struct wlr_keyboard_group *wlr_group; + struct wlr_keyboard_group *wlr_group; - int nsyms; - const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ - uint32_t mods; /* invalid if nsyms == 0 */ - struct wl_event_source *key_repeat_source; + int nsyms; + const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ + uint32_t mods; /* invalid if nsyms == 0 */ + struct wl_event_source *key_repeat_source; - struct wl_listener modifiers; - struct wl_listener key; - struct wl_listener destroy; + struct wl_listener modifiers; + struct wl_listener key; + struct wl_listener destroy; } KeyboardGroup; typedef struct { - struct wl_list link; - struct wlr_keyboard *wlr_keyboard; + struct wl_list link; + struct wlr_keyboard *wlr_keyboard; - int nsyms; - const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ - uint32_t mods; /* invalid if nsyms == 0 */ - struct wl_event_source *key_repeat_source; + int nsyms; + const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ + uint32_t mods; /* invalid if nsyms == 0 */ + struct wl_event_source *key_repeat_source; - struct wl_listener modifiers; - struct wl_listener key; - struct wl_listener destroy; + struct wl_listener modifiers; + struct wl_listener key; + struct wl_listener destroy; } Keyboard; typedef struct { - /* Must keep these three elements in this order */ - unsigned int type; /* LayerShell */ - struct wlr_box geom; - Monitor *mon; - struct wlr_scene_tree *scene; - struct wlr_scene_tree *popups; - struct wlr_scene_layer_surface_v1 *scene_layer; - struct wl_list link; - int mapped; - struct wlr_layer_surface_v1 *layer_surface; + /* Must keep these three elements in this order */ + unsigned int type; /* LayerShell */ + struct wlr_box geom; + Monitor *mon; + struct wlr_scene_tree *scene; + struct wlr_scene_tree *popups; + struct wlr_scene_layer_surface_v1 *scene_layer; + struct wl_list link; + int mapped; + struct wlr_layer_surface_v1 *layer_surface; - struct wl_listener destroy; - struct wl_listener map; - struct wl_listener unmap; - struct wl_listener surface_commit; + struct wl_listener destroy; + struct wl_listener map; + struct wl_listener unmap; + struct wl_listener surface_commit; } LayerSurface; typedef struct { - const char *symbol; - void (*arrange)(Monitor *); - const char *name; + const char *symbol; + void (*arrange)(Monitor *); + const char *name; } Layout; struct Monitor { - struct wl_list link; - struct wlr_output *wlr_output; - struct wlr_scene_output *scene_output; - // struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */ - struct wl_listener frame; - struct wl_listener destroy; - struct wl_listener request_state; - struct wl_listener destroy_lock_surface; - struct wlr_session_lock_surface_v1 *lock_surface; - struct wlr_box m; /* monitor area, layout-relative */ - struct wlr_box w; /* window area, layout-relative */ - struct wl_list layers[4]; /* LayerSurface::link */ - const Layout *lt; - unsigned int seltags; - uint32_t tagset[2]; - double mfact; - int nmaster; + struct wl_list link; + struct wlr_output *wlr_output; + struct wlr_scene_output *scene_output; + // struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */ + struct wl_listener frame; + struct wl_listener destroy; + struct wl_listener request_state; + struct wl_listener destroy_lock_surface; + struct wlr_session_lock_surface_v1 *lock_surface; + struct wlr_box m; /* monitor area, layout-relative */ + struct wlr_box w; /* window area, layout-relative */ + struct wl_list layers[4]; /* LayerSurface::link */ + const Layout *lt; + unsigned int seltags; + uint32_t tagset[2]; + double mfact; + int nmaster; - struct wl_list dwl_ipc_outputs; - int gappih; /* horizontal gap between windows */ - int gappiv; /* vertical gap between windows */ - int gappoh; /* horizontal outer gaps */ - int gappov; /* vertical outer gaps */ - Pertag *pertag; - Client *sel, *prevsel; - int isoverview; - int is_in_hotarea; - int gamma_lut_changed; - int asleep; - unsigned int visible_clients; + struct wl_list dwl_ipc_outputs; + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ + Pertag *pertag; + Client *sel, *prevsel; + int isoverview; + int is_in_hotarea; + int gamma_lut_changed; + int asleep; + unsigned int visible_clients; }; typedef struct { - const char *name; - float mfact; - int nmaster; - float scale; - const Layout *lt; - enum wl_output_transform rr; - int x, y; + const char *name; + float mfact; + int nmaster; + float scale; + const Layout *lt; + enum wl_output_transform rr; + int x, y; } MonitorRule; typedef struct { - struct wlr_pointer_constraint_v1 *constraint; - struct wl_listener destroy; + struct wlr_pointer_constraint_v1 *constraint; + struct wl_listener destroy; } PointerConstraint; typedef struct { - const char *id; - const char *title; - unsigned int tags; - int isfloating; - int isfullscreen; - float scroller_proportion; - const char *animation_type_open; - const char *animation_type_close; - int isnoborder; - int monitor; - unsigned int width; - unsigned int height; + const char *id; + const char *title; + unsigned int tags; + int isfloating; + int isfullscreen; + float scroller_proportion; + const char *animation_type_open; + const char *animation_type_close; + int isnoborder; + int monitor; + unsigned int width; + unsigned int height; } Rule; typedef struct { - struct wlr_scene_tree *scene; + struct wlr_scene_tree *scene; - struct wlr_session_lock_v1 *lock; - struct wl_listener new_surface; - struct wl_listener unlock; - struct wl_listener destroy; + struct wlr_session_lock_v1 *lock; + struct wl_listener new_surface; + struct wl_listener unlock; + struct wl_listener destroy; } SessionLock; /* function declarations */ static void applybounds( - Client *c, - struct wlr_box *bbox); // 设置边界规则,能让一些窗口拥有比较适合的大小 + Client *c, + struct wlr_box *bbox); // 设置边界规则,能让一些窗口拥有比较适合的大小 static void applyrules(Client *c); // 窗口规则应用,应用config.h中定义的窗口规则 static void arrange(Monitor *m, - bool want_animation); // 布局函数,让窗口俺平铺规则移动和重置大小 + bool want_animation); // 布局函数,让窗口俺平铺规则移动和重置大小 static void arrangelayer(Monitor *m, struct wl_list *list, - struct wlr_box *usable_area, int exclusive); + struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); static char *get_autostart_path(char *, size_t); // 自启动命令执行 static void axisnotify(struct wl_listener *listener, - void *data); // 滚轮事件处理 + void *data); // 滚轮事件处理 static void buttonpress(struct wl_listener *listener, - void *data); // 鼠标按键事件处理 + void *data); // 鼠标按键事件处理 static int ongesture(struct wlr_pointer_swipe_end_event *event); static void swipe_begin(struct wl_listener *listener, void *data); static void swipe_update(struct wl_listener *listener, void *data); @@ -450,7 +451,7 @@ static void hold_end(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 cleanuplisteners(void); @@ -485,35 +486,35 @@ 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, - uint32_t version, uint32_t id); + uint32_t version, uint32_t 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, - uint32_t id, struct wl_resource *output); + struct wl_resource *resource, + uint32_t id, struct wl_resource *output); static void dwl_ipc_manager_release(struct wl_client *client, - struct wl_resource *resource); + 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, - uint32_t and_tags, - uint32_t xor_tags); + struct wl_resource *resource, + uint32_t and_tags, + uint32_t xor_tags); static void dwl_ipc_output_set_layout(struct wl_client *client, - struct wl_resource *resource, - uint32_t index); + struct wl_resource *resource, + uint32_t index); static void dwl_ipc_output_set_tags(struct wl_client *client, - struct wl_resource *resource, - uint32_t tagmask, uint32_t toggle_tagset); + struct wl_resource *resource, + uint32_t tagmask, uint32_t toggle_tagset); static void dwl_ipc_output_quit(struct wl_client *client, - struct wl_resource *resource); + 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); + 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); + struct wl_resource *resource); static void focusclient(Client *c, int lift); static void setborder_color(Client *c); @@ -528,9 +529,9 @@ static int keybinding(uint32_t mods, xkb_keysym_t sym); static void keypress(struct wl_listener *listener, void *data); static void keypressmod(struct wl_listener *listener, void *data); static bool keypressglobal(struct wlr_surface *last_surface, - struct wlr_keyboard *keyboard, - struct wlr_keyboard_key_event *event, uint32_t mods, - xkb_keysym_t keysym); + struct wlr_keyboard *keyboard, + struct wlr_keyboard_key_event *event, uint32_t mods, + xkb_keysym_t keysym); static void locksession(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); @@ -538,8 +539,8 @@ static void minimizenotify(struct wl_listener *listener, void *data); static void monocle(Monitor *m); 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, - double sy_unaccel); + double sx, double sy, double sx_unaccel, + double sy_unaccel); static void motionrelative(struct wl_listener *listener, void *data); static void reset_foreign_tolevel(Client *c); @@ -548,10 +549,10 @@ static void add_foreign_topleve(Client *c); static void exchange_two_client(Client *c1, Client *c2); static void outputmgrapply(struct wl_listener *listener, void *data); static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, - int test); + int test); static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, - double sy, uint32_t time); + double sy, uint32_t time); static void printstatus(void); static void quitsignal(int signo); static void powermgrsetmode(struct wl_listener *listener, void *data); @@ -596,7 +597,7 @@ static void virtualpointer(struct wl_listener *listener, void *data); static void warp_cursor(const Client *c); static Monitor *xytomon(double x, double y); static void xytonode(double x, double y, struct wlr_surface **psurface, - Client **pc, LayerSurface **pl, double *nx, double *ny); + Client **pc, LayerSurface **pl, double *nx, double *ny); static void clear_fullscreen_flag(Client *c); static pid_t getparentprocess(pid_t p); static int isdescprocess(pid_t p, pid_t c); @@ -615,32 +616,32 @@ 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); + void *data); static void handle_foreign_fullscreen_request(struct wl_listener *listener, - void *data); + void *data); static void handle_foreign_close_request(struct wl_listener *listener, - void *data); + 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); + struct wlr_box geom, + int offsetx, int offsety); static unsigned int get_tags_first_tag(unsigned int tags); static void client_commit(Client *c); static void apply_border(Client *c, struct wlr_box clip_box, int offsetx, - int offsety); + int offsety); static void client_set_opacity(Client *c, double opacity); static void init_baked_points(void); static void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx, - int sy, void *data); + int sy, void *data); static Client *direction_select(const Arg *arg); static void view_in_mon(const Arg *arg, bool want_animation, Monitor *m); static void buffer_set_effect(Client *c, animationScale scale_data); static void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, - int sx, int sy, void *data); + int sx, int sy, void *data); static void client_set_pending_state(Client *c); static void set_rect_size(struct wlr_scene_rect *rect, int width, int height); static Client *center_select(Monitor *m); @@ -729,34 +730,34 @@ struct vec2 *baked_points_close; static struct wl_event_source *hide_source; static bool cursor_hidden = false; static struct { - enum wp_cursor_shape_device_v1_shape shape; - struct wlr_surface *surface; - int hotspot_x; - int hotspot_y; + enum wp_cursor_shape_device_v1_shape shape; + struct wlr_surface *surface; + int hotspot_x; + int hotspot_y; } last_cursor; #include "config/preset_config.h" 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 */ - float smfacts[LENGTH(tags) + 1]; /* smfacts per tag */ - const Layout - *ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */ + 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 */ + float smfacts[LENGTH(tags) + 1]; /* smfacts per tag */ + const Layout + *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}; + .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}; + .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}; @@ -770,7 +771,7 @@ static struct wl_listener new_input_device = {.notify = inputdevice}; static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard}; static struct wl_listener new_virtual_pointer = {.notify = virtualpointer}; static struct wl_listener new_pointer_constraint = { - .notify = createpointerconstraint}; + .notify = createpointerconstraint}; static struct wl_listener new_output = {.notify = createmon}; static struct wl_listener new_xdg_toplevel = {.notify = createnotify}; static struct wl_listener new_xdg_popup = {.notify = createpopup}; @@ -779,7 +780,7 @@ static struct wl_listener new_layer_surface = {.notify = createlayersurface}; static struct wl_listener output_mgr_apply = {.notify = outputmgrapply}; static struct wl_listener output_mgr_test = {.notify = outputmgrtest}; static struct wl_listener output_power_mgr_set_mode = {.notify = - powermgrsetmode}; + powermgrsetmode}; static struct wl_listener request_activate = {.notify = urgent}; static struct wl_listener request_cursor = {.notify = setcursor}; static struct wl_listener request_set_psel = {.notify = setpsel}; @@ -809,3209 +810,3268 @@ static struct wlr_xwayland *xwayland; #include "text_input/ime.h" struct vec2 calculate_animation_curve_at(double t, int type) { - struct vec2 point; - double *animation_curve; - if (type == MOVE) { - animation_curve = animation_curve_move; - } else if (type == OPEN) { - animation_curve = animation_curve_open; - } else if (type == TAG) { - animation_curve = animation_curve_tag; - } else if (type == CLOSE) { - animation_curve = animation_curve_close; - } else { - animation_curve = animation_curve_move; - } + struct vec2 point; + double *animation_curve; + if (type == MOVE) { + animation_curve = animation_curve_move; + } else if (type == OPEN) { + animation_curve = animation_curve_open; + } else if (type == TAG) { + animation_curve = animation_curve_tag; + } else if (type == CLOSE) { + animation_curve = animation_curve_close; + } else { + animation_curve = animation_curve_move; + } - point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] + - 3 * t * t * (1 - t) * animation_curve[2] + t * t * t; + point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] + + 3 * t * t * (1 - t) * animation_curve[2] + t * t * t; - point.y = 3 * t * (1 - t) * (1 - t) * animation_curve[1] + - 3 * t * t * (1 - t) * animation_curve[3] + t * t * t; + point.y = 3 * t * (1 - t) * (1 - t) * animation_curve[1] + + 3 * t * t * (1 - t) * animation_curve[3] + t * t * t; - return point; + return point; } void init_baked_points(void) { - baked_points_move = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_move)); - baked_points_open = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_open)); - baked_points_tag = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_tag)); - baked_points_close = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close)); + baked_points_move = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_move)); + baked_points_open = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_open)); + baked_points_tag = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_tag)); + baked_points_close = + calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close)); - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_move[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), MOVE); - } - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_open[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), OPEN); - } - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_tag[i] = - calculate_animation_curve_at((double)i / (BAKED_POINTS_COUNT - 1), TAG); - } - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_close[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), CLOSE); - } + for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + baked_points_move[i] = calculate_animation_curve_at( + (double)i / (BAKED_POINTS_COUNT - 1), MOVE); + } + for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + baked_points_open[i] = calculate_animation_curve_at( + (double)i / (BAKED_POINTS_COUNT - 1), OPEN); + } + for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + baked_points_tag[i] = calculate_animation_curve_at( + (double)i / (BAKED_POINTS_COUNT - 1), TAG); + } + for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + baked_points_close[i] = calculate_animation_curve_at( + (double)i / (BAKED_POINTS_COUNT - 1), CLOSE); + } } double find_animation_curve_at(double t, int type) { - size_t down = 0; - size_t up = BAKED_POINTS_COUNT - 1; + size_t down = 0; + size_t up = BAKED_POINTS_COUNT - 1; - size_t middle = (up + down) / 2; - struct vec2 *baked_points; - if (type == MOVE) { - baked_points = baked_points_move; - } else if (type == OPEN) { - baked_points = baked_points_open; - } else if (type == TAG) { - baked_points = baked_points_tag; - } else if (type == CLOSE) { - baked_points = baked_points_close; - } else { - baked_points = baked_points_move; - } + size_t middle = (up + down) / 2; + struct vec2 *baked_points; + if (type == MOVE) { + baked_points = baked_points_move; + } else if (type == OPEN) { + baked_points = baked_points_open; + } else if (type == TAG) { + baked_points = baked_points_tag; + } else if (type == CLOSE) { + baked_points = baked_points_close; + } else { + baked_points = baked_points_move; + } - while (up - down != 1) { - if (baked_points[middle].x <= t) { - down = middle; - } else { - up = middle; - } - middle = (up + down) / 2; - } - return baked_points[up].y; + while (up - down != 1) { + if (baked_points[middle].x <= t) { + down = middle; + } else { + up = middle; + } + middle = (up + down) / 2; + } + return baked_points[up].y; } void apply_opacity_to_rect_nodes(Client *c, struct wlr_scene_node *node, - double animation_passed) { - int offsetx = 0; - int offsety = 0; - if (node->type == WLR_SCENE_NODE_RECT) { - struct wlr_scene_rect *rect = wlr_scene_rect_from_node(node); - // Assuming the rect has a color field and we can modify it - rect->color[0] = (1 - animation_passed) * rect->color[0]; - rect->color[1] = (1 - animation_passed) * rect->color[1]; - rect->color[2] = (1 - animation_passed) * rect->color[2]; - rect->color[3] = (1 - animation_passed) * rect->color[3]; - wlr_scene_rect_set_color(rect, rect->color); + double animation_passed) { + int offsetx = 0; + int offsety = 0; + if (node->type == WLR_SCENE_NODE_RECT) { + struct wlr_scene_rect *rect = wlr_scene_rect_from_node(node); + // Assuming the rect has a color field and we can modify it + rect->color[0] = (1 - animation_passed) * rect->color[0]; + rect->color[1] = (1 - animation_passed) * rect->color[1]; + rect->color[2] = (1 - animation_passed) * rect->color[2]; + rect->color[3] = (1 - animation_passed) * rect->color[3]; + wlr_scene_rect_set_color(rect, rect->color); - offsetx = c->geom.width - c->animation.current.width; - offsety = c->geom.height - c->animation.current.height; - if (node->y > c->geom.y + c->geom.height / 2) { - wlr_scene_node_set_position(node, c->geom.x, - c->geom.y + c->geom.height - offsety); - wlr_scene_rect_set_size(rect, c->animation.current.width, c->bw); // down - } else if (node->y < c->geom.y + c->geom.height / 2 && - rect->width > rect->height) { - wlr_scene_node_set_position(node, c->geom.x, c->geom.y); - wlr_scene_rect_set_size(rect, c->animation.current.width, c->bw); // up - } else if (node->x < c->geom.x + c->geom.width / 2 && - rect->width < rect->height) { - wlr_scene_rect_set_size(rect, c->bw, c->animation.current.height); // left - } else { - wlr_scene_node_set_position(node, c->geom.x + c->geom.width - offsetx, - c->geom.y); - wlr_scene_rect_set_size(rect, c->bw, - c->animation.current.height); // right - } - } + offsetx = c->geom.width - c->animation.current.width; + offsety = c->geom.height - c->animation.current.height; + if (node->y > c->geom.y + c->geom.height / 2) { + wlr_scene_node_set_position(node, c->geom.x, + c->geom.y + c->geom.height - offsety); + wlr_scene_rect_set_size(rect, c->animation.current.width, + c->bw); // down + } else if (node->y < c->geom.y + c->geom.height / 2 && + rect->width > rect->height) { + wlr_scene_node_set_position(node, c->geom.x, c->geom.y); + wlr_scene_rect_set_size(rect, c->animation.current.width, + c->bw); // up + } else if (node->x < c->geom.x + c->geom.width / 2 && + rect->width < rect->height) { + wlr_scene_rect_set_size(rect, c->bw, + c->animation.current.height); // left + } else { + wlr_scene_node_set_position( + node, c->geom.x + c->geom.width - offsetx, c->geom.y); + wlr_scene_rect_set_size(rect, c->bw, + c->animation.current.height); // right + } + } - // If the node is a tree, recursively traverse its children - if (node->type == WLR_SCENE_NODE_TREE) { - struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node); - struct wlr_scene_node *child; - wl_list_for_each(child, &scene_tree->children, link) { - apply_opacity_to_rect_nodes(c, child, animation_passed); - } - } + // If the node is a tree, recursively traverse its children + if (node->type == WLR_SCENE_NODE_TREE) { + struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node); + struct wlr_scene_node *child; + wl_list_for_each(child, &scene_tree->children, link) { + apply_opacity_to_rect_nodes(c, child, animation_passed); + } + } } void fadeout_client_animation_next_tick(Client *c) { - if (!c) - return; + if (!c) + return; - animationScale scale_data; + animationScale scale_data; - double animation_passed = - (double)c->animation.passed_frames / c->animation.total_frames; - int type = c->animation.action = c->animation.action; - double factor = find_animation_curve_at(animation_passed, type); - uint32_t width = c->animation.initial.width + - (c->current.width - c->animation.initial.width) * factor; - uint32_t height = c->animation.initial.height + - (c->current.height - c->animation.initial.height) * factor; + double animation_passed = + (double)c->animation.passed_frames / c->animation.total_frames; + int type = c->animation.action = c->animation.action; + double factor = find_animation_curve_at(animation_passed, type); + uint32_t width = c->animation.initial.width + + (c->current.width - c->animation.initial.width) * factor; + uint32_t height = + c->animation.initial.height + + (c->current.height - c->animation.initial.height) * factor; - uint32_t x = - c->animation.initial.x + (c->current.x - c->animation.initial.x) * factor; - uint32_t y = - c->animation.initial.y + (c->current.y - c->animation.initial.y) * factor; + uint32_t x = c->animation.initial.x + + (c->current.x - c->animation.initial.x) * factor; + uint32_t y = c->animation.initial.y + + (c->current.y - c->animation.initial.y) * factor; - wlr_scene_node_set_position(&c->scene->node, x, y); + wlr_scene_node_set_position(&c->scene->node, x, y); - c->animation.current = (struct wlr_box){ - .x = x, - .y = y, - .width = width, - .height = height, - }; + c->animation.current = (struct wlr_box){ + .x = x, + .y = y, + .width = width, + .height = height, + }; - double opacity = MAX(fadeout_begin_opacity - animation_passed, 0); + double opacity = MAX(fadeout_begin_opacity - animation_passed, 0); - if(animation_fade_out && !c->nofadeout) - wlr_scene_node_for_each_buffer(&c->scene->node, scene_buffer_apply_opacity, - &opacity); + if (animation_fade_out && !c->nofadeout) + wlr_scene_node_for_each_buffer(&c->scene->node, + scene_buffer_apply_opacity, &opacity); - apply_opacity_to_rect_nodes(c, &c->scene->node, animation_passed); + apply_opacity_to_rect_nodes(c, &c->scene->node, animation_passed); - if ((c->animation_type_close && - strcmp(c->animation_type_close, "zoom") == 0) || - (!c->animation_type_close && strcmp(animation_type_close, "zoom") == 0)) { + if ((c->animation_type_close && + strcmp(c->animation_type_close, "zoom") == 0) || + (!c->animation_type_close && + strcmp(animation_type_close, "zoom") == 0)) { - scale_data.width = width; - scale_data.height = height; - scale_data.width_scale = animation_passed; - scale_data.height_scale = animation_passed; + scale_data.width = width; + scale_data.height = height; + scale_data.width_scale = animation_passed; + scale_data.height_scale = animation_passed; - wlr_scene_node_for_each_buffer(&c->scene->node, - snap_scene_buffer_apply_effect, &scale_data); - } + wlr_scene_node_for_each_buffer( + &c->scene->node, snap_scene_buffer_apply_effect, &scale_data); + } - if (animation_passed == 1.0) { - wl_list_remove(&c->fadeout_link); - wlr_scene_node_destroy(&c->scene->node); - free(c); - c = NULL; - } else { - c->animation.passed_frames++; - } + if (animation_passed == 1.0) { + wl_list_remove(&c->fadeout_link); + wlr_scene_node_destroy(&c->scene->node); + free(c); + c = NULL; + } else { + c->animation.passed_frames++; + } } void client_animation_next_tick(Client *c) { - double animation_passed = - (double)c->animation.passed_frames / c->animation.total_frames; + double animation_passed = + (double)c->animation.passed_frames / c->animation.total_frames; - int type = c->animation.action == NONE ? MOVE : c->animation.action; - double factor = find_animation_curve_at(animation_passed, type); + int type = c->animation.action == NONE ? MOVE : c->animation.action; + double factor = find_animation_curve_at(animation_passed, type); - Client *pointer_c = NULL; - double sx = 0, sy = 0; - struct wlr_surface *surface = NULL; + Client *pointer_c = NULL; + double sx = 0, sy = 0; + struct wlr_surface *surface = NULL; - uint32_t width = c->animation.initial.width + - (c->current.width - c->animation.initial.width) * factor; - uint32_t height = c->animation.initial.height + - (c->current.height - c->animation.initial.height) * factor; + uint32_t width = c->animation.initial.width + + (c->current.width - c->animation.initial.width) * factor; + uint32_t height = + c->animation.initial.height + + (c->current.height - c->animation.initial.height) * factor; - uint32_t x = - c->animation.initial.x + (c->current.x - c->animation.initial.x) * factor; - uint32_t y = - c->animation.initial.y + (c->current.y - c->animation.initial.y) * factor; + uint32_t x = c->animation.initial.x + + (c->current.x - c->animation.initial.x) * factor; + uint32_t y = c->animation.initial.y + + (c->current.y - c->animation.initial.y) * factor; - wlr_scene_node_set_position(&c->scene->node, x, y); - c->animation.current = (struct wlr_box){ - .x = x, - .y = y, - .width = width, - .height = height, - }; + wlr_scene_node_set_position(&c->scene->node, x, y); + c->animation.current = (struct wlr_box){ + .x = x, + .y = y, + .width = width, + .height = height, + }; - if (!c->iskilling && (c->is_open_animation || c->animation.begin_fade_in) && - animation_fade_in && !c->nofadein) { - c->animation.begin_fade_in = true; - client_set_opacity(c, MIN(animation_passed + fadein_begin_opacity, 1.0)); - } + if (!c->iskilling && (c->is_open_animation || c->animation.begin_fade_in) && + animation_fade_in && !c->nofadein) { + c->animation.begin_fade_in = true; + client_set_opacity(c, + MIN(animation_passed + fadein_begin_opacity, 1.0)); + } - c->is_open_animation = false; + c->is_open_animation = false; - if (animation_passed == 1.0) { - if (c->animation.begin_fade_in) { - c->animation.begin_fade_in = false; - } + if (animation_passed == 1.0) { + if (c->animation.begin_fade_in) { + c->animation.begin_fade_in = false; + } - // clear the open action state - // To prevent him from being mistaken that - // it's still in the opening animation in resize - c->animation.action = MOVE; + // clear the open action state + // To prevent him from being mistaken that + // it's still in the opening animation in resize + c->animation.action = MOVE; - c->animation.tagining = false; - c->animation.running = false; + c->animation.tagining = false; + c->animation.running = false; - if (c->animation.tagouting) { - c->animation.tagouting = false; - wlr_scene_node_set_enabled(&c->scene->node, false); - client_set_suspended(c, true); - c->animation.tagouted = true; - c->animation.current = c->geom; - } + if (c->animation.tagouting) { + c->animation.tagouting = false; + wlr_scene_node_set_enabled(&c->scene->node, false); + client_set_suspended(c, true); + c->animation.tagouted = true; + c->animation.current = c->geom; + } - xytonode(cursor->x, cursor->y, NULL, &pointer_c, NULL, &sx, &sy); + 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); + } - // end flush in next frame, not the current frame - c->need_output_flush = false; - } else { - c->animation.passed_frames++; - } + // end flush in next frame, not the current frame + c->need_output_flush = false; + } else { + c->animation.passed_frames++; + } } void client_actual_size(Client *c, uint32_t *width, uint32_t *height) { - *width = c->animation.current.width; + *width = c->animation.current.width; - *height = c->animation.current.height; + *height = c->animation.current.height; } void set_rect_size(struct wlr_scene_rect *rect, int width, int height) { - wlr_scene_rect_set_size(rect, GEZERO(width), GEZERO(height)); + wlr_scene_rect_set_size(rect, GEZERO(width), GEZERO(height)); } bool check_hit_no_border(Client *c) { - int i; - bool hit_no_border = false; - if (!render_border) { - hit_no_border = true; - } + int i; + bool hit_no_border = false; + if (!render_border) { + hit_no_border = true; + } - for (i = 0; i < config.tag_rules_count; i++) { - if (c->tags & (1 << (config.tag_rules[i].id - 1)) && - config.tag_rules[i].no_render_border) { - hit_no_border = true; - } - } + for (i = 0; i < config.tag_rules_count; i++) { + if (c->tags & (1 << (config.tag_rules[i].id - 1)) && + config.tag_rules[i].no_render_border) { + hit_no_border = true; + } + } - if (no_border_when_single && c && c->mon && c->mon->visible_clients == 1) { - hit_no_border = true; - } - return hit_no_border; + if (no_border_when_single && c && c->mon && c->mon->visible_clients == 1) { + hit_no_border = true; + } + return hit_no_border; } void apply_border(Client *c, struct wlr_box clip_box, int offsetx, - int offsety) { - bool hit_no_border = false; + int offsety) { + bool hit_no_border = false; - if (c->iskilling || !client_surface(c)->mapped) - return; + if (c->iskilling || !client_surface(c)->mapped) + return; - if (clip_box.width > c->animation.current.width) { - clip_box.width = c->animation.current.width; - } + if (clip_box.width > c->animation.current.width) { + clip_box.width = c->animation.current.width; + } - if (clip_box.height > c->animation.current.height) { - clip_box.height = c->animation.current.height; - } + if (clip_box.height > c->animation.current.height) { + clip_box.height = c->animation.current.height; + } - hit_no_border = check_hit_no_border(c); + hit_no_border = check_hit_no_border(c); - if (hit_no_border && smartgaps) { - c->bw = 0; - c->fake_no_border = true; - } else if (hit_no_border && !smartgaps) { - set_rect_size(c->border[0], 0, 0); - set_rect_size(c->border[1], 0, 0); - set_rect_size(c->border[2], 0, 0); - set_rect_size(c->border[3], 0, 0); - wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); - c->fake_no_border = true; - return; - } else if (!c->isfullscreen && VISIBLEON(c, c->mon)) { - c->bw = c->isnoborder ? 0 : borderpx; - c->fake_no_border = false; - } + if (hit_no_border && smartgaps) { + c->bw = 0; + c->fake_no_border = true; + } else if (hit_no_border && !smartgaps) { + set_rect_size(c->border[0], 0, 0); + set_rect_size(c->border[1], 0, 0); + set_rect_size(c->border[2], 0, 0); + set_rect_size(c->border[3], 0, 0); + wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); + c->fake_no_border = true; + return; + } else if (!c->isfullscreen && VISIBLEON(c, c->mon)) { + c->bw = c->isnoborder ? 0 : borderpx; + c->fake_no_border = false; + } - wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); - set_rect_size(c->border[0], clip_box.width, c->bw); - set_rect_size(c->border[1], clip_box.width, c->bw); - set_rect_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); - set_rect_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[3]->node, clip_box.width - c->bw, - c->bw); + wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); + set_rect_size(c->border[0], clip_box.width, c->bw); + set_rect_size(c->border[1], clip_box.width, c->bw); + set_rect_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); + set_rect_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[3]->node, clip_box.width - c->bw, + c->bw); - if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || - c->animation.tagouting) { - if (c->animation.current.x < c->mon->m.x) { - set_rect_size(c->border[2], GEZERO(c->bw - offsetx), - clip_box.height - 2 * c->bw); - } else if (c->animation.current.x + c->animation.current.width > - c->mon->m.x + c->mon->m.width) { - set_rect_size(c->border[3], - GEZERO(c->bw - GEZERO(c->animation.current.x + - c->animation.current.width - - c->mon->m.x - c->mon->m.width)), - clip_box.height - 2 * c->bw); - set_rect_size(c->border[0], clip_box.width + c->bw, - GEZERO(c->bw - offsety)); - set_rect_size(c->border[1], clip_box.width + c->bw, - GEZERO(c->bw - GEZERO(c->animation.current.y + - c->animation.current.height - - c->mon->m.y - c->mon->m.height))); - } else if (c->animation.current.y < c->mon->m.y) { - set_rect_size(c->border[0], clip_box.width, GEZERO(c->bw - offsety)); - } else if (c->animation.current.y + c->animation.current.height > - c->mon->m.y + c->mon->m.height) { - set_rect_size(c->border[1], clip_box.width, - GEZERO(c->bw - GEZERO(c->animation.current.y + - c->animation.current.height - - c->mon->m.y - c->mon->m.height))); - set_rect_size(c->border[2], GEZERO(c->bw - offsetx), - clip_box.height - c->bw); - set_rect_size(c->border[3], - GEZERO(c->bw - GEZERO(c->animation.current.x + - c->animation.current.width - - c->mon->m.x - c->mon->m.width)), - clip_box.height - c->bw); - } - } + if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || + c->animation.tagouting) { + if (c->animation.current.x < c->mon->m.x) { + set_rect_size(c->border[2], GEZERO(c->bw - offsetx), + clip_box.height - 2 * c->bw); + } else if (c->animation.current.x + c->animation.current.width > + c->mon->m.x + c->mon->m.width) { + set_rect_size(c->border[3], + GEZERO(c->bw - GEZERO(c->animation.current.x + + c->animation.current.width - + c->mon->m.x - c->mon->m.width)), + clip_box.height - 2 * c->bw); + set_rect_size(c->border[0], clip_box.width + c->bw, + GEZERO(c->bw - offsety)); + set_rect_size( + c->border[1], clip_box.width + c->bw, + GEZERO(c->bw - GEZERO(c->animation.current.y + + c->animation.current.height - + c->mon->m.y - c->mon->m.height))); + } else if (c->animation.current.y < c->mon->m.y) { + set_rect_size(c->border[0], clip_box.width, + GEZERO(c->bw - offsety)); + } else if (c->animation.current.y + c->animation.current.height > + c->mon->m.y + c->mon->m.height) { + set_rect_size( + c->border[1], clip_box.width, + GEZERO(c->bw - GEZERO(c->animation.current.y + + c->animation.current.height - + c->mon->m.y - c->mon->m.height))); + set_rect_size(c->border[2], GEZERO(c->bw - offsetx), + clip_box.height - c->bw); + set_rect_size(c->border[3], + GEZERO(c->bw - GEZERO(c->animation.current.x + + c->animation.current.width - + c->mon->m.x - c->mon->m.width)), + clip_box.height - c->bw); + } + } - wlr_scene_node_set_position(&c->border[0]->node, offsetx, offsety); - wlr_scene_node_set_position(&c->border[2]->node, offsetx, c->bw + offsety); - wlr_scene_node_set_position(&c->border[1]->node, offsetx, - clip_box.height - c->bw + offsety); - wlr_scene_node_set_position( - &c->border[3]->node, clip_box.width - c->bw + offsetx, c->bw + offsety); + wlr_scene_node_set_position(&c->border[0]->node, offsetx, offsety); + wlr_scene_node_set_position(&c->border[2]->node, offsetx, c->bw + offsety); + wlr_scene_node_set_position(&c->border[1]->node, offsetx, + clip_box.height - c->bw + offsety); + wlr_scene_node_set_position( + &c->border[3]->node, clip_box.width - c->bw + offsetx, c->bw + offsety); } struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { - int offsetx = 0; - int offsety = 0; - struct uvec2 offset; - offset.x = 0; - offset.y = 0; + int offsetx = 0; + int offsety = 0; + struct uvec2 offset; + offset.x = 0; + offset.y = 0; - if (!ISTILED(c) && !c->animation.tagining && !c->animation.tagouted && - !c->animation.tagouting) - return offset; + if (!ISTILED(c) && !c->animation.tagining && !c->animation.tagouted && + !c->animation.tagouting) + return offset; - // // make tagout tagin animations not visible in other monitors - if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || - c->animation.tagouting) { - if (c->animation.current.x < c->mon->m.x) { - offsetx = c->mon->m.x - c->bw - c->animation.current.x; - offsetx = offsetx < 0 ? 0 : offsetx; - clip_box->x = clip_box->x + offsetx; - clip_box->width = clip_box->width - offsetx; - } else if (c->animation.current.x + c->animation.current.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) + - c->bw; - } + // // make tagout tagin animations not visible in other monitors + if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || + c->animation.tagouting) { + if (c->animation.current.x < c->mon->m.x) { + offsetx = c->mon->m.x - c->bw - c->animation.current.x; + offsetx = offsetx < 0 ? 0 : offsetx; + clip_box->x = clip_box->x + offsetx; + clip_box->width = clip_box->width - offsetx; + } else if (c->animation.current.x + c->animation.current.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) + + c->bw; + } - if (c->animation.current.y < c->mon->m.y) { - offsety = c->mon->m.y - c->bw - c->animation.current.y; - offsety = offsety < 0 ? 0 : offsety; - clip_box->y = clip_box->y + offsety; - clip_box->height = clip_box->height - offsety; - } else if (c->animation.current.y + c->animation.current.height > - c->mon->m.y + c->mon->m.height) { - clip_box->height = clip_box->height - - (c->animation.current.y + c->animation.current.height - - c->mon->m.y - c->mon->m.height) + - c->bw; - } - } + if (c->animation.current.y < c->mon->m.y) { + offsety = c->mon->m.y - c->bw - c->animation.current.y; + offsety = offsety < 0 ? 0 : offsety; + clip_box->y = clip_box->y + offsety; + clip_box->height = clip_box->height - offsety; + } else if (c->animation.current.y + c->animation.current.height > + c->mon->m.y + c->mon->m.height) { + clip_box->height = + clip_box->height - + (c->animation.current.y + c->animation.current.height - + c->mon->m.y - c->mon->m.height) + + c->bw; + } + } - offset.x = offsetx; - offset.y = offsety; + offset.x = offsetx; + offset.y = offsety; - if ((clip_box->width < 0 || clip_box->height < 0) && - (ISTILED(c) || c->animation.tagouting || c->animation.tagining)) { - c->is_clip_to_hide = true; - wlr_scene_node_set_enabled(&c->scene->node, false); - } else if (c->is_clip_to_hide && VISIBLEON(c, c->mon)) { - c->is_clip_to_hide = false; - wlr_scene_node_set_enabled(&c->scene->node, true); - } + if ((clip_box->width < 0 || clip_box->height < 0) && + (ISTILED(c) || c->animation.tagouting || c->animation.tagining)) { + c->is_clip_to_hide = true; + wlr_scene_node_set_enabled(&c->scene->node, false); + } else if (c->is_clip_to_hide && VISIBLEON(c, c->mon)) { + c->is_clip_to_hide = false; + wlr_scene_node_set_enabled(&c->scene->node, true); + } - if (clip_box->width > c->animation.current.width) { - clip_box->width = c->animation.current.width; - } + if (clip_box->width > c->animation.current.width) { + clip_box->width = c->animation.current.width; + } - if (clip_box->height > c->animation.current.height) { - clip_box->height = c->animation.current.height; - } + if (clip_box->height > c->animation.current.height) { + clip_box->height = c->animation.current.height; + } - return offset; + return offset; } void client_apply_clip(Client *c) { - if (c->iskilling || !client_surface(c)->mapped) - return; - struct wlr_box clip_box; - struct uvec2 offset; - animationScale scale_data; + if (c->iskilling || !client_surface(c)->mapped) + return; + struct wlr_box clip_box; + struct uvec2 offset; + animationScale scale_data; - if (!animations) { - c->animation.running = false; - c->need_output_flush = false; - c->animainit_geom = c->current = c->pending = c->animation.current = - c->geom; - client_get_clip(c, &clip_box); - offset = clip_to_hide(c, &clip_box); - apply_border(c, clip_box, offset.x, offset.y); + if (!animations) { + c->animation.running = false; + c->need_output_flush = false; + c->animainit_geom = c->current = c->pending = c->animation.current = + c->geom; + client_get_clip(c, &clip_box); + offset = clip_to_hide(c, &clip_box); + apply_border(c, clip_box, offset.x, offset.y); - if (clip_box.width <= 0 || clip_box.height <= 0) - return; + if (clip_box.width <= 0 || clip_box.height <= 0) + return; - wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); - buffer_set_effect(c, (animationScale){0, 0, 0, 0, false}); - return; - } + wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); + buffer_set_effect(c, (animationScale){0, 0, 0, 0, false}); + return; + } - uint32_t width, height; - client_actual_size(c, &width, &height); + uint32_t width, height; + client_actual_size(c, &width, &height); - struct wlr_box geometry; - client_get_geometry(c, &geometry); - clip_box = (struct wlr_box){ - .x = geometry.x, - .y = geometry.y, - .width = width, - .height = height, - }; + struct wlr_box geometry; + client_get_geometry(c, &geometry); + clip_box = (struct wlr_box){ + .x = geometry.x, + .y = geometry.y, + .width = width, + .height = height, + }; - if (client_is_x11(c)) { - clip_box.x = 0; - clip_box.y = 0; - } + if (client_is_x11(c)) { + clip_box.x = 0; + clip_box.y = 0; + } - offset = clip_to_hide(c, &clip_box); - apply_border(c, clip_box, offset.x, offset.y); + offset = clip_to_hide(c, &clip_box); + apply_border(c, clip_box, offset.x, offset.y); - if (clip_box.width <= 0 || clip_box.height <= 0) - return; + if (clip_box.width <= 0 || clip_box.height <= 0) + return; - wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); + wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); - scale_data.should_scale = true; - scale_data.width = clip_box.width - 2 * c->bw; - scale_data.height = clip_box.height - 2 * c->bw; - scale_data.width_scale = - (float)scale_data.width / (geometry.width - offset.x); - scale_data.height_scale = - (float)scale_data.height / (geometry.height - offset.y); - buffer_set_effect(c, scale_data); + scale_data.should_scale = true; + scale_data.width = clip_box.width - 2 * c->bw; + scale_data.height = clip_box.height - 2 * c->bw; + scale_data.width_scale = + (float)scale_data.width / (geometry.width - offset.x); + scale_data.height_scale = + (float)scale_data.height / (geometry.height - offset.y); + buffer_set_effect(c, scale_data); } bool client_draw_frame(Client *c) { - if (!c || !client_surface(c)->mapped) - return false; + if (!c || !client_surface(c)->mapped) + return false; - if (!c->need_output_flush) - return false; + if (!c->need_output_flush) + return false; - if (animations && c->animation.running) { - client_animation_next_tick(c); - client_apply_clip(c); - } else { - wlr_scene_node_set_position(&c->scene->node, c->pending.x, c->pending.y); - c->animainit_geom = c->animation.initial = c->pending = c->current = - c->geom; - client_apply_clip(c); - c->need_output_flush = false; - } - return true; + if (animations && c->animation.running) { + client_animation_next_tick(c); + client_apply_clip(c); + } else { + wlr_scene_node_set_position(&c->scene->node, c->pending.x, + c->pending.y); + c->animainit_geom = c->animation.initial = c->pending = c->current = + c->geom; + client_apply_clip(c); + c->need_output_flush = false; + } + return true; } bool client_draw_fadeout_frame(Client *c) { - if (!c) - return false; + if (!c) + return false; - fadeout_client_animation_next_tick(c); - return true; + fadeout_client_animation_next_tick(c); + return true; } void applybounds(Client *c, struct wlr_box *bbox) { - /* set minimum possible */ - c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); - c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); + /* set minimum possible */ + c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); + c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); - if (c->geom.x >= bbox->x + bbox->width) - c->geom.x = bbox->x + bbox->width - c->geom.width; - if (c->geom.y >= bbox->y + bbox->height) - c->geom.y = bbox->y + bbox->height - c->geom.height; - if (c->geom.x + c->geom.width <= bbox->x) - c->geom.x = bbox->x; - if (c->geom.y + c->geom.height <= bbox->y) - c->geom.y = bbox->y; + if (c->geom.x >= bbox->x + bbox->width) + c->geom.x = bbox->x + bbox->width - c->geom.width; + if (c->geom.y >= bbox->y + bbox->height) + c->geom.y = bbox->y + bbox->height - c->geom.height; + if (c->geom.x + c->geom.width <= bbox->x) + c->geom.x = bbox->x; + if (c->geom.y + c->geom.height <= bbox->y) + c->geom.y = bbox->y; } /*清除全屏标志,还原全屏时清0的border*/ void clear_fullscreen_flag(Client *c) { - if (c->isfullscreen || c->ismaxmizescreen) { - c->isfullscreen = 0; - c->isfloating = 0; - c->ismaxmizescreen = 0; - c->bw = c->isnoborder ? 0 : borderpx; - client_set_fullscreen(c, false); - } + if (c->isfullscreen || c->ismaxmizescreen) { + c->isfullscreen = 0; + c->isfloating = 0; + c->ismaxmizescreen = 0; + c->bw = c->isnoborder ? 0 : borderpx; + client_set_fullscreen(c, false); + } } void toggleoverlay(const Arg *arg) { - if (!selmon->sel || !selmon->sel->mon || selmon->sel->isfullscreen) { - return; - } + if (!selmon->sel || !selmon->sel->mon || selmon->sel->isfullscreen) { + return; + } - selmon->sel->isoverlay ^= 1; + selmon->sel->isoverlay ^= 1; - if (selmon->sel->isoverlay) { - wlr_scene_node_reparent(&selmon->sel->scene->node, layers[LyrOverlay]); - wlr_scene_node_raise_to_top(&selmon->sel->scene->node); - } else { - wlr_scene_node_reparent( - &selmon->sel->scene->node, - layers[selmon->sel->isfloating ? LyrFloat : LyrTile]); - } - setborder_color(selmon->sel); + if (selmon->sel->isoverlay) { + wlr_scene_node_reparent(&selmon->sel->scene->node, layers[LyrOverlay]); + wlr_scene_node_raise_to_top(&selmon->sel->scene->node); + } else { + wlr_scene_node_reparent( + &selmon->sel->scene->node, + layers[selmon->sel->isfloating ? LyrFloat : LyrTile]); + } + setborder_color(selmon->sel); } void minized(const Arg *arg) { - if (selmon->sel && !selmon->sel->isminied) { - set_minized(selmon->sel); - } + if (selmon->sel && !selmon->sel->isminied) { + set_minized(selmon->sel); + } } void restore_minized(const Arg *arg) { - if (selmon && selmon->sel && selmon->sel->is_in_scratchpad && - selmon->sel->is_scratchpad_show) { - selmon->sel->isminied = 0; - selmon->sel->is_scratchpad_show = 0; - selmon->sel->is_in_scratchpad = 0; - selmon->sel->isnamedscratchpand = 0; - setborder_color(selmon->sel); - return; - } + if (selmon && selmon->sel && selmon->sel->is_in_scratchpad && + selmon->sel->is_scratchpad_show) { + selmon->sel->isminied = 0; + selmon->sel->is_scratchpad_show = 0; + selmon->sel->is_in_scratchpad = 0; + selmon->sel->isnamedscratchpand = 0; + setborder_color(selmon->sel); + return; + } - Client *c; - wl_list_for_each(c, &clients, link) { - if (c->isminied) { - show_hide_client(c); - c->is_scratchpad_show = 0; - c->is_in_scratchpad = 0; - c->isnamedscratchpand = 0; - setborder_color(c); - break; - } - } + Client *c; + wl_list_for_each(c, &clients, link) { + if (c->isminied) { + show_hide_client(c); + c->is_scratchpad_show = 0; + c->is_in_scratchpad = 0; + c->isnamedscratchpand = 0; + setborder_color(c); + break; + } + } } void show_scratchpad(Client *c) { - c->is_scratchpad_show = 1; - if (c->isfullscreen || c->ismaxmizescreen) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->ismaxmizescreen = 0; - c->bw = c->isnoborder ? 0 : borderpx; - } + c->is_scratchpad_show = 1; + if (c->isfullscreen || c->ismaxmizescreen) { + c->isfullscreen = 0; // 清除窗口全屏标志 + c->ismaxmizescreen = 0; + c->bw = c->isnoborder ? 0 : borderpx; + } - if (c->oldgeom.width) - c->scratchpad_geom.width = c->oldgeom.width; - if (c->oldgeom.height) - c->scratchpad_geom.height = c->oldgeom.height; + if (c->oldgeom.width) + c->scratchpad_geom.width = c->oldgeom.width; + if (c->oldgeom.height) + c->scratchpad_geom.height = c->oldgeom.height; - /* return if fullscreen */ - if (!c->isfloating) { - setfloating(c, 1); - c->geom.width = c->scratchpad_geom.width ? c->scratchpad_geom.width - : c->mon->w.width * 0.7; - c->geom.height = c->scratchpad_geom.height ? c->scratchpad_geom.height - : c->mon->w.height * 0.8; - // 重新计算居中的坐标 - c->geom = c->animainit_geom = c->animation.current = - setclient_coordinate_center(c, c->geom, 0, 0); - resize(c, c->geom, 0); - } else if (c->geom.width != c->scratchpad_geom.width || - c->geom.height != c->scratchpad_geom.height) { - c->geom.width = c->scratchpad_geom.width ? c->scratchpad_geom.width - : c->mon->w.width * 0.7; - c->geom.height = c->scratchpad_geom.height ? c->scratchpad_geom.height - : c->mon->w.height * 0.8; - c->geom = c->animainit_geom = c->animation.current = - setclient_coordinate_center(c, c->geom, 0, 0); - resize(c, c->geom, 0); - } - c->oldtags = selmon->tagset[selmon->seltags]; - c->is_clip_to_hide = false; - wl_list_remove(&c->link); // 从原来位置移除 - wl_list_insert(clients.prev->next, &c->link); // 插入开头 - show_hide_client(c); - setborder_color(c); + /* return if fullscreen */ + if (!c->isfloating) { + setfloating(c, 1); + c->geom.width = c->scratchpad_geom.width ? c->scratchpad_geom.width + : c->mon->w.width * 0.7; + c->geom.height = c->scratchpad_geom.height ? c->scratchpad_geom.height + : c->mon->w.height * 0.8; + // 重新计算居中的坐标 + c->geom = c->animainit_geom = c->animation.current = + setclient_coordinate_center(c, c->geom, 0, 0); + resize(c, c->geom, 0); + } else if (c->geom.width != c->scratchpad_geom.width || + c->geom.height != c->scratchpad_geom.height) { + c->geom.width = c->scratchpad_geom.width ? c->scratchpad_geom.width + : c->mon->w.width * 0.7; + c->geom.height = c->scratchpad_geom.height ? c->scratchpad_geom.height + : c->mon->w.height * 0.8; + c->geom = c->animainit_geom = c->animation.current = + setclient_coordinate_center(c, c->geom, 0, 0); + resize(c, c->geom, 0); + } + c->oldtags = selmon->tagset[selmon->seltags]; + c->is_clip_to_hide = false; + wl_list_remove(&c->link); // 从原来位置移除 + wl_list_insert(clients.prev->next, &c->link); // 插入开头 + show_hide_client(c); + setborder_color(c); } void remove_foreign_topleve(Client *c) { - wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); - c->foreign_toplevel = NULL; + 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; + 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); - } + 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); + remove_foreign_topleve(c); + add_foreign_toplevel(c); } pid_t getparentprocess(pid_t p) { - unsigned int v = 0; + unsigned int v = 0; - FILE *f; - char buf[256]; - snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); + FILE *f; + char buf[256]; + snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); - if (!(f = fopen(buf, "r"))) - return 0; + if (!(f = fopen(buf, "r"))) + return 0; - // 检查fscanf返回值,确保成功读取了1个参数 - if (fscanf(f, "%*u %*s %*c %u", &v) != 1) { - fclose(f); - return 0; - } + // 检查fscanf返回值,确保成功读取了1个参数 + if (fscanf(f, "%*u %*s %*c %u", &v) != 1) { + fclose(f); + return 0; + } - fclose(f); + fclose(f); - return (pid_t)v; + return (pid_t)v; } int isdescprocess(pid_t p, pid_t c) { - while (p != c && c != 0) - c = getparentprocess(c); + while (p != c && c != 0) + c = getparentprocess(c); - return (int)c; + return (int)c; } Client *termforwin(Client *w) { - Client *c; + Client *c; - if (!w->pid || w->isterm || w->noswallow) - return NULL; + if (!w->pid || w->isterm || w->noswallow) + return NULL; - wl_list_for_each(c, &fstack, - flink) if (c->isterm && !c->swallowing && c->pid && - isdescprocess(c->pid, w->pid)) return c; + wl_list_for_each(c, &fstack, + flink) if (c->isterm && !c->swallowing && c->pid && + isdescprocess(c->pid, w->pid)) return c; - return NULL; + return NULL; } void swallow(Client *c, Client *w) { - c->bw = w->bw; - c->isfloating = w->isfloating; - c->isurgent = w->isurgent; - c->isfullscreen = w->isfullscreen; - c->ismaxmizescreen = w->ismaxmizescreen; - c->isminied = w->isminied; - c->is_in_scratchpad = w->is_in_scratchpad; - c->is_scratchpad_show = w->is_scratchpad_show; - c->tags = w->tags; - c->geom = w->geom; - c->scroller_proportion = w->scroller_proportion; - wl_list_insert(&w->link, &c->link); - wl_list_insert(&w->flink, &c->flink); + c->bw = w->bw; + c->isfloating = w->isfloating; + c->isurgent = w->isurgent; + c->isfullscreen = w->isfullscreen; + c->ismaxmizescreen = w->ismaxmizescreen; + c->isminied = w->isminied; + c->is_in_scratchpad = w->is_in_scratchpad; + c->is_scratchpad_show = w->is_scratchpad_show; + c->tags = w->tags; + c->geom = w->geom; + c->scroller_proportion = w->scroller_proportion; + wl_list_insert(&w->link, &c->link); + wl_list_insert(&w->flink, &c->flink); - if (w->foreign_toplevel) - remove_foreign_topleve(w); + if (w->foreign_toplevel) + remove_foreign_topleve(w); - wlr_scene_node_set_enabled(&w->scene->node, false); - wlr_scene_node_set_enabled(&c->scene->node, true); + wlr_scene_node_set_enabled(&w->scene->node, false); + wlr_scene_node_set_enabled(&c->scene->node, true); - if (!c->foreign_toplevel && c->mon) - add_foreign_toplevel(c); + if (!c->foreign_toplevel && c->mon) + add_foreign_toplevel(c); - if (c->isminied) { - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false); - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); - } + if (c->isminied) { + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, + false); + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); + } } bool switch_scratchpad_client_state(Client *c) { - if (c->is_in_scratchpad && c->is_scratchpad_show && - (selmon->tagset[selmon->seltags] & c->tags) == 0) { - unsigned int target = get_tags_first_tag(selmon->tagset[selmon->seltags]); - tag_client(&(Arg){.ui = target}, c); - return true; - } else if (c->is_in_scratchpad && c->is_scratchpad_show && - (selmon->tagset[selmon->seltags] & c->tags) != 0) { - set_minized(c); - return true; - } else if (c && c->is_in_scratchpad && !c->is_scratchpad_show) { - show_scratchpad(c); - return true; - } + if (c->is_in_scratchpad && c->is_scratchpad_show && + (selmon->tagset[selmon->seltags] & c->tags) == 0) { + unsigned int target = + get_tags_first_tag(selmon->tagset[selmon->seltags]); + tag_client(&(Arg){.ui = target}, c); + return true; + } else if (c->is_in_scratchpad && c->is_scratchpad_show && + (selmon->tagset[selmon->seltags] & c->tags) != 0) { + set_minized(c); + return true; + } else if (c && c->is_in_scratchpad && !c->is_scratchpad_show) { + show_scratchpad(c); + return true; + } - return false; + return false; } void toggle_render_border(const Arg *arg) { - render_border = !render_border; - arrange(selmon, false); + render_border = !render_border; + arrange(selmon, false); } Client *get_client_by_id_or_title(const char *arg_id, const char *arg_title) { - Client *target_client = NULL; - const char *appid, *title; - Client *c = NULL; - wl_list_for_each(c, &clients, link) { - if (c->mon != selmon) { - continue; - } + Client *target_client = NULL; + const char *appid, *title; + Client *c = NULL; + wl_list_for_each(c, &clients, link) { + if (c->mon != selmon) { + continue; + } - if (!(appid = client_get_appid(c))) - appid = broken; - if (!(title = client_get_title(c))) - title = broken; + if (!(appid = client_get_appid(c))) + appid = broken; + if (!(title = client_get_title(c))) + title = broken; - if (arg_id && strncmp(arg_id, "none", 4) == 0) - arg_id = NULL; + if (arg_id && strncmp(arg_id, "none", 4) == 0) + arg_id = NULL; - if (arg_title && strncmp(arg_title, "none", 4) == 0) - arg_title = NULL; + if (arg_title && strncmp(arg_title, "none", 4) == 0) + arg_title = NULL; - if ((arg_title && regex_match(arg_title, title) && !arg_id) || - (arg_id && regex_match(arg_id, appid) && !arg_title) || - (arg_id && regex_match(arg_id, appid) && arg_title && - regex_match(arg_title, title))) { - target_client = c; - break; - } - } - return target_client; + if ((arg_title && regex_match(arg_title, title) && !arg_id) || + (arg_id && regex_match(arg_id, appid) && !arg_title) || + (arg_id && regex_match(arg_id, appid) && arg_title && + regex_match(arg_title, title))) { + target_client = c; + break; + } + } + return target_client; } void apply_named_scratchpad(Client *target_client) { - Client *c = NULL; - wl_list_for_each(c, &clients, link) { - if (c->mon != selmon) { - continue; - } - if (single_scratchpad && c->is_in_scratchpad && c->is_scratchpad_show && - c != target_client) { - set_minized(c); - } - } + Client *c = NULL; + wl_list_for_each(c, &clients, link) { + if (c->mon != selmon) { + continue; + } + if (single_scratchpad && c->is_in_scratchpad && c->is_scratchpad_show && + c != target_client) { + set_minized(c); + } + } - if (!target_client->is_in_scratchpad) { - set_minized(target_client); - switch_scratchpad_client_state(target_client); - } else - switch_scratchpad_client_state(target_client); + if (!target_client->is_in_scratchpad) { + set_minized(target_client); + switch_scratchpad_client_state(target_client); + } else + switch_scratchpad_client_state(target_client); } void toggle_named_scratchpad(const Arg *arg) { - Client *target_client = NULL; - char *arg_id = arg->v; - char *arg_title = arg->v2; + Client *target_client = NULL; + char *arg_id = arg->v; + char *arg_title = arg->v2; - target_client = get_client_by_id_or_title(arg_id, arg_title); + target_client = get_client_by_id_or_title(arg_id, arg_title); - if (!target_client && arg->v3) { - Arg arg_spawn = {.v = arg->v3}; - spawn(&arg_spawn); - return; - } + if (!target_client && arg->v3) { + Arg arg_spawn = {.v = arg->v3}; + spawn(&arg_spawn); + return; + } - target_client->isnamedscratchpand = 1; - target_client->scratchpad_geom.width = arg->ui; - target_client->scratchpad_geom.height = arg->ui2; + target_client->isnamedscratchpand = 1; + target_client->scratchpad_geom.width = arg->ui; + target_client->scratchpad_geom.height = arg->ui2; - apply_named_scratchpad(target_client); + apply_named_scratchpad(target_client); } void toggle_scratchpad(const Arg *arg) { - Client *c; - bool hit = false; - Client *tmp = NULL; - wl_list_for_each_safe(c, tmp, &clients, link) { - if (c->mon != selmon) { - continue; - } + Client *c; + bool hit = false; + Client *tmp = NULL; + wl_list_for_each_safe(c, tmp, &clients, link) { + if (c->mon != selmon) { + continue; + } - if (single_scratchpad && c->isnamedscratchpand && !c->isminied) { - set_minized(c); - continue; - } + if (single_scratchpad && c->isnamedscratchpand && !c->isminied) { + set_minized(c); + continue; + } - if (c->isnamedscratchpand) - continue; + if (c->isnamedscratchpand) + continue; - if (hit) - continue; + if (hit) + continue; - hit = switch_scratchpad_client_state(c); - } + hit = switch_scratchpad_client_state(c); + } } void gpureset(struct wl_listener *listener, void *data) { - struct wlr_renderer *old_drw = drw; - struct wlr_allocator *old_alloc = alloc; - struct Monitor *m; + struct wlr_renderer *old_drw = drw; + struct wlr_allocator *old_alloc = alloc; + struct Monitor *m; - wlr_log(WLR_DEBUG, "gpu reset"); + wlr_log(WLR_DEBUG, "gpu reset"); - if (!(drw = wlr_renderer_autocreate(backend))) - die("couldn't recreate renderer"); + if (!(drw = wlr_renderer_autocreate(backend))) + die("couldn't recreate renderer"); - if (!(alloc = wlr_allocator_autocreate(backend, drw))) - die("couldn't recreate allocator"); + if (!(alloc = wlr_allocator_autocreate(backend, drw))) + die("couldn't recreate allocator"); - wl_list_remove(&gpu_reset.link); - wl_signal_add(&drw->events.lost, &gpu_reset); + wl_list_remove(&gpu_reset.link); + wl_signal_add(&drw->events.lost, &gpu_reset); - wlr_compositor_set_renderer(compositor, drw); + wlr_compositor_set_renderer(compositor, drw); - wl_list_for_each(m, &mons, link) { - wlr_output_init_render(m->wlr_output, alloc, drw); - } + wl_list_for_each(m, &mons, link) { + wlr_output_init_render(m->wlr_output, alloc, drw); + } - wlr_allocator_destroy(old_alloc); - wlr_renderer_destroy(old_drw); + wlr_allocator_destroy(old_alloc); + wlr_renderer_destroy(old_drw); } void handlesig(int signo) { - if (signo == SIGCHLD) - while (waitpid(-1, NULL, WNOHANG) > 0) - ; - else if (signo == SIGINT || signo == SIGTERM) - quit(NULL); + if (signo == SIGCHLD) + while (waitpid(-1, NULL, WNOHANG) > 0) + ; + else if (signo == SIGINT || signo == SIGTERM) + quit(NULL); } void toggle_hotarea(int x_root, int y_root) { - // 左下角热区坐标计算,兼容多显示屏 - Arg arg = {0}; + // 左下角热区坐标计算,兼容多显示屏 + Arg arg = {0}; - // 在刚启动的时候,selmon为NULL,但鼠标可能已经处于热区, - // 必须判断避免奔溃 - if (!selmon) - return; + // 在刚启动的时候,selmon为NULL,但鼠标可能已经处于热区, + // 必须判断避免奔溃 + if (!selmon) + return; - if (grabc) - return; + if (grabc) + return; - unsigned hx = selmon->m.x + hotarea_size; - unsigned hy = selmon->m.y + selmon->m.height - hotarea_size; + unsigned hx = selmon->m.x + hotarea_size; + unsigned hy = selmon->m.y + selmon->m.height - hotarea_size; - if (enable_hotarea == 1 && selmon->is_in_hotarea == 0 && y_root > hy && - x_root < hx && x_root >= selmon->m.x && - y_root <= (selmon->m.y + selmon->m.height)) { - toggleoverview(&arg); - selmon->is_in_hotarea = 1; - } else if (enable_hotarea == 1 && selmon->is_in_hotarea == 1 && - (y_root <= hy || x_root >= hx || x_root < selmon->m.x || - y_root > (selmon->m.y + selmon->m.height))) { - selmon->is_in_hotarea = 0; - } + if (enable_hotarea == 1 && selmon->is_in_hotarea == 0 && y_root > hy && + x_root < hx && x_root >= selmon->m.x && + y_root <= (selmon->m.y + selmon->m.height)) { + toggleoverview(&arg); + selmon->is_in_hotarea = 1; + } else if (enable_hotarea == 1 && selmon->is_in_hotarea == 1 && + (y_root <= hy || x_root >= hx || x_root < selmon->m.x || + y_root > (selmon->m.y + selmon->m.height))) { + selmon->is_in_hotarea = 0; + } } struct wlr_box // 计算客户端居中坐标 setclient_coordinate_center(Client *c, struct wlr_box geom, int offsetx, - int offsety) { - struct wlr_box tempbox; - int offset = 0; - int len = 0; + int offsety) { + struct wlr_box tempbox; + int offset = 0; + int len = 0; - unsigned int cbw = check_hit_no_border(c) ? c->bw : 0; + unsigned int cbw = check_hit_no_border(c) ? c->bw : 0; - if(!c->no_force_center) { - tempbox.x = selmon->w.x + (selmon->w.width - geom.width) / 2; - tempbox.y = selmon->w.y + (selmon->w.height - geom.height) / 2; - } else { - tempbox.x = geom.x; - tempbox.y = geom.y; - } + if (!c->no_force_center) { + tempbox.x = selmon->w.x + (selmon->w.width - geom.width) / 2; + tempbox.y = selmon->w.y + (selmon->w.height - geom.height) / 2; + } else { + tempbox.x = geom.x; + tempbox.y = geom.y; + } - tempbox.width = geom.width; - tempbox.height = geom.height; + tempbox.width = geom.width; + tempbox.height = geom.height; - if (offsetx != 0) { - len = selmon->w.width / 2; - offset = len * (offsetx / 100.0); - tempbox.x += offset; + if (offsetx != 0) { + len = selmon->w.width / 2; + offset = len * (offsetx / 100.0); + tempbox.x += offset; - // 限制窗口在屏幕内 - if (tempbox.x < selmon->m.x) { - tempbox.x = selmon->m.x - cbw; - } - if (tempbox.x + tempbox.width > selmon->m.x + selmon->m.width) { - tempbox.x = selmon->m.x + selmon->m.width - tempbox.width + cbw; - } - } - if (offsety != 0) { - len = selmon->w.height; - offset = len * (offsety / 100.0); - tempbox.y += offset; + // 限制窗口在屏幕内 + if (tempbox.x < selmon->m.x) { + tempbox.x = selmon->m.x - cbw; + } + if (tempbox.x + tempbox.width > selmon->m.x + selmon->m.width) { + tempbox.x = selmon->m.x + selmon->m.width - tempbox.width + cbw; + } + } + if (offsety != 0) { + len = selmon->w.height; + offset = len * (offsety / 100.0); + tempbox.y += offset; - // 限制窗口在屏幕内 - if (tempbox.y < selmon->m.y) { - tempbox.y = selmon->m.y - cbw; - } - if (tempbox.y + tempbox.height > selmon->m.y + selmon->m.height) { - tempbox.y = selmon->m.y + selmon->m.height - tempbox.height + cbw; - } - } + // 限制窗口在屏幕内 + if (tempbox.y < selmon->m.y) { + tempbox.y = selmon->m.y - cbw; + } + if (tempbox.y + tempbox.height > selmon->m.y + selmon->m.height) { + tempbox.y = selmon->m.y + selmon->m.height - tempbox.height + cbw; + } + } - return tempbox; + return tempbox; } /* function implementations */ int // 0.5 custom applyrulesgeom(Client *c) { - /* rule matching */ - const char *appid, *title; - ConfigWinRule *r; - int hit = 0; - int ji; + /* rule matching */ + const char *appid, *title; + ConfigWinRule *r; + int hit = 0; + int ji; - if (!(appid = client_get_appid(c))) - appid = broken; - if (!(title = client_get_title(c))) - title = broken; + if (!(appid = client_get_appid(c))) + appid = broken; + if (!(title = client_get_title(c))) + title = broken; - for (ji = 0; ji < config.window_rules_count; ji++) { - if (config.window_rules_count < 1) - break; - r = &config.window_rules[ji]; - if ((regex_match(r->title, title) && !r->id) || - (r->id && regex_match(r->id, appid) && !r->title) || - (r->id && regex_match(r->id, appid) && r->title && - regex_match(r->title, title))) { - c->geom.width = r->width > 0 ? r->width : c->geom.width; - c->geom.height = r->height > 0 ? r->height : c->geom.height; - // 重新计算居中的坐标 - if (r->offsetx != 0 || r->offsety != 0 || r->width > 0 || r->height > 0) - c->geom = - setclient_coordinate_center(c, c->geom, r->offsetx, r->offsety); - hit = r->height > 0 || r->width > 0 || r->offsetx != 0 || r->offsety != 0 - ? 1 - : 0; - } - } - return hit; + for (ji = 0; ji < config.window_rules_count; ji++) { + if (config.window_rules_count < 1) + break; + r = &config.window_rules[ji]; + if ((regex_match(r->title, title) && !r->id) || + (r->id && regex_match(r->id, appid) && !r->title) || + (r->id && regex_match(r->id, appid) && r->title && + regex_match(r->title, title))) { + c->geom.width = r->width > 0 ? r->width : c->geom.width; + c->geom.height = r->height > 0 ? r->height : c->geom.height; + // 重新计算居中的坐标 + if (r->offsetx != 0 || r->offsety != 0 || r->width > 0 || + r->height > 0) + c->geom = setclient_coordinate_center(c, c->geom, r->offsetx, + r->offsety); + hit = r->height > 0 || r->width > 0 || r->offsetx != 0 || + r->offsety != 0 + ? 1 + : 0; + } + } + return hit; } void // 17 applyrules(Client *c) { - /* rule matching */ - const char *appid, *title; - uint32_t i, newtags = 0; - int ji; - const ConfigWinRule *r; - Monitor *mon = selmon, *m; - bool hit_rule_pos = false; + /* rule matching */ + const char *appid, *title; + uint32_t i, newtags = 0; + int ji; + const ConfigWinRule *r; + Monitor *mon = selmon, *m; + bool hit_rule_pos = false; - c->isfloating = client_is_float_type(c); - if (!(appid = client_get_appid(c))) - appid = broken; - if (!(title = client_get_title(c))) - title = broken; + c->isfloating = client_is_float_type(c); + if (!(appid = client_get_appid(c))) + appid = broken; + if (!(title = client_get_title(c))) + title = broken; - c->pid = client_get_pid(c); + c->pid = client_get_pid(c); - for (ji = 0; ji < config.window_rules_count; ji++) { - if (config.window_rules_count < 1) - break; - r = &config.window_rules[ji]; + for (ji = 0; ji < config.window_rules_count; ji++) { + if (config.window_rules_count < 1) + break; + r = &config.window_rules[ji]; - if ((r->title && regex_match(r->title, title) && !r->id) || - (r->id && regex_match(r->id, appid) && !r->title) || - (r->id && regex_match(r->id, appid) && r->title && - regex_match(r->title, title))) { - c->isterm = r->isterm >= 0 ? r->isterm : c->isterm; - c->noswallow = r->noswallow >= 0 ? r->noswallow : c->noswallow; - c->nofadein = r->nofadein >= 0 ? r->nofadein : c->nofadein; - c->nofadeout = r->nofadeout >= 0 ? r->nofadeout : c->nofadeout; - c->no_force_center = r->no_force_center >= 0 ? r->no_force_center - : c->no_force_center; - c->scratchpad_geom.width = r->scratchpad_width > 0 - ? r->scratchpad_width - : c->scratchpad_geom.width; - c->scratchpad_geom.height = r->scratchpad_height > 0 - ? r->scratchpad_height - : c->scratchpad_geom.height; - c->isfloating = r->isfloating >= 0 ? r->isfloating : c->isfloating; - c->isfullscreen = r->isfullscreen >= 0 ? r->isfullscreen : c->isfullscreen; - c->animation_type_open = r->animation_type_open == NULL - ? c->animation_type_open - : r->animation_type_open; - c->animation_type_close = r->animation_type_close == NULL - ? c->animation_type_close - : r->animation_type_close; - c->scroller_proportion = r->scroller_proportion > 0 - ? r->scroller_proportion - : c->scroller_proportion; - c->isnoborder = r->isnoborder >= 0 ? r->isnoborder : c->isnoborder; - c->isopensilent = r->isopensilent >= 0 ? r->isopensilent : c->isopensilent; - c->isopenscratchpad = - r->isopenscratchpad >= 0 ? r->isopenscratchpad : c->isopenscratchpad; - c->isglobal = r->isglobal >= 0 ? r->isglobal : c->isglobal; - c->isoverlay = r->isoverlay >= 0 ? r->isoverlay : c->isoverlay; - c->isunglobal = r->isunglobal >= 0 ? r->isunglobal : c->isunglobal; + if ((r->title && regex_match(r->title, title) && !r->id) || + (r->id && regex_match(r->id, appid) && !r->title) || + (r->id && regex_match(r->id, appid) && r->title && + regex_match(r->title, title))) { + c->isterm = r->isterm >= 0 ? r->isterm : c->isterm; + c->noswallow = r->noswallow >= 0 ? r->noswallow : c->noswallow; + c->nofadein = r->nofadein >= 0 ? r->nofadein : c->nofadein; + c->nofadeout = r->nofadeout >= 0 ? r->nofadeout : c->nofadeout; + c->no_force_center = r->no_force_center >= 0 ? r->no_force_center + : c->no_force_center; + c->scratchpad_geom.width = r->scratchpad_width > 0 + ? r->scratchpad_width + : c->scratchpad_geom.width; + c->scratchpad_geom.height = r->scratchpad_height > 0 + ? r->scratchpad_height + : c->scratchpad_geom.height; + c->isfloating = r->isfloating >= 0 ? r->isfloating : c->isfloating; + c->isfullscreen = + r->isfullscreen >= 0 ? r->isfullscreen : c->isfullscreen; + c->animation_type_open = r->animation_type_open == NULL + ? c->animation_type_open + : r->animation_type_open; + c->animation_type_close = r->animation_type_close == NULL + ? c->animation_type_close + : r->animation_type_close; + c->scroller_proportion = r->scroller_proportion > 0 + ? r->scroller_proportion + : c->scroller_proportion; + c->isnoborder = r->isnoborder >= 0 ? r->isnoborder : c->isnoborder; + c->isopensilent = + r->isopensilent >= 0 ? r->isopensilent : c->isopensilent; + c->isopenscratchpad = r->isopenscratchpad >= 0 + ? r->isopenscratchpad + : c->isopenscratchpad; + c->isglobal = r->isglobal >= 0 ? r->isglobal : c->isglobal; + c->isoverlay = r->isoverlay >= 0 ? r->isoverlay : c->isoverlay; + c->isunglobal = r->isunglobal >= 0 ? r->isunglobal : c->isunglobal; - newtags = r->tags > 0 ? r->tags | newtags : newtags; - i = 0; - wl_list_for_each(m, &mons, link) if (r->monitor == i++) mon = m; + newtags = r->tags > 0 ? r->tags | newtags : newtags; + i = 0; + wl_list_for_each(m, &mons, link) if (r->monitor == i++) mon = m; - if (c->isopenscratchpad) - c->isfloating = 1; + if (c->isopenscratchpad) + c->isfloating = 1; - if (c->isopenscratchpad == 2) - c->isnamedscratchpand = 1; + if (c->isopenscratchpad == 2) + c->isnamedscratchpand = 1; - if (c->isfloating) { - c->geom.width = r->width > 0 ? r->width : c->geom.width; - c->geom.height = r->height > 0 ? r->height : c->geom.height; - // 重新计算居中的坐标 - if (r->offsetx != 0 || r->offsety != 0 || r->width > 0 || r->height > 0) { - hit_rule_pos = true; - c->oldgeom = c->geom = - setclient_coordinate_center(c, c->geom, r->offsetx, r->offsety); - } - } - } - } + if (c->isfloating) { + c->geom.width = r->width > 0 ? r->width : c->geom.width; + c->geom.height = r->height > 0 ? r->height : c->geom.height; + // 重新计算居中的坐标 + if (r->offsetx != 0 || r->offsety != 0 || r->width > 0 || + r->height > 0) { + hit_rule_pos = true; + c->oldgeom = c->geom = setclient_coordinate_center( + c, c->geom, r->offsetx, r->offsety); + } + } + } + } - // if no geom rule hit, use the center pos and record the hit size - if (!hit_rule_pos && (!client_is_x11(c) || !client_should_ignore_focus(c))) { - c->oldgeom = c->geom = setclient_coordinate_center(c, c->geom, 0, 0); - } + // if no geom rule hit, use the center pos and record the hit size + if (!hit_rule_pos && + (!client_is_x11(c) || !client_should_ignore_focus(c))) { + c->oldgeom = c->geom = setclient_coordinate_center(c, c->geom, 0, 0); + } - if (!client_surface(c)->mapped) - return; + if (!client_surface(c)->mapped) + return; - if (!c->noswallow && !c->isfloating && !client_is_float_type(c) && - !c->surface.xdg->initial_commit) { - Client *p = termforwin(c); - if (p) { - c->swallowedby = p; - p->swallowing = c; - wl_list_remove(&c->link); - wl_list_remove(&c->flink); - swallow(c, p); - wl_list_remove(&p->link); - wl_list_remove(&p->flink); - mon = p->mon; - newtags = p->tags; - } - } + if (!c->noswallow && !c->isfloating && !client_is_float_type(c) && + !c->surface.xdg->initial_commit) { + Client *p = termforwin(c); + if (p) { + c->swallowedby = p; + p->swallowing = c; + wl_list_remove(&c->link); + wl_list_remove(&c->flink); + swallow(c, p); + wl_list_remove(&p->link); + wl_list_remove(&p->flink); + mon = p->mon; + newtags = p->tags; + } + } - Client *fc; - // 如果当前的tag中有新创建的非悬浮窗口,就让当前tag中的全屏窗口退出全屏参与平铺 - wl_list_for_each(fc, &clients, link) if (fc && fc != c && - c->tags & fc->tags && - ISFULLSCREEN(fc) && !c->isfloating) { - clear_fullscreen_flag(fc); - arrange(c->mon, false); - } + Client *fc; + // 如果当前的tag中有新创建的非悬浮窗口,就让当前tag中的全屏窗口退出全屏参与平铺 + wl_list_for_each(fc, &clients, + link) if (fc && fc != c && c->tags & fc->tags && + ISFULLSCREEN(fc) && !c->isfloating) { + clear_fullscreen_flag(fc); + arrange(c->mon, false); + } - int fullscreen_state_backup = c->isfullscreen; - setmon(c, mon, newtags, !c->isopensilent); + int fullscreen_state_backup = c->isfullscreen; + setmon(c, mon, newtags, !c->isopensilent); - if (!c->isopensilent && selmon && - !(c->tags & (1 << (selmon->pertag->curtag - 1)))) { - c->animation.from_rule = true; - view(&(Arg){.ui = c->tags}, true); - } + if (!c->isopensilent && selmon && + !(c->tags & (1 << (selmon->pertag->curtag - 1)))) { + c->animation.from_rule = true; + view(&(Arg){.ui = c->tags}, true); + } - setfullscreen(c, fullscreen_state_backup); + setfullscreen(c, fullscreen_state_backup); - if (c->isopenscratchpad) { - apply_named_scratchpad(c); - } + if (c->isopenscratchpad) { + apply_named_scratchpad(c); + } - if (c->isoverlay) { - wlr_scene_node_reparent(&selmon->sel->scene->node, layers[LyrOverlay]); - wlr_scene_node_raise_to_top(&selmon->sel->scene->node); - } + if (c->isoverlay) { + wlr_scene_node_reparent(&selmon->sel->scene->node, layers[LyrOverlay]); + wlr_scene_node_raise_to_top(&selmon->sel->scene->node); + } - setborder_color(c); + setborder_color(c); } void // 17 arrange(Monitor *m, bool want_animation) { - Client *c; + Client *c; - if (!m) - return; + if (!m) + return; - if (!m->wlr_output->enabled) - return; + if (!m->wlr_output->enabled) + return; - m->visible_clients = 0; - wl_list_for_each(c, &clients, link) { - if (c->iskilling) - continue; + m->visible_clients = 0; + wl_list_for_each(c, &clients, link) { + if (c->iskilling) + continue; - if (c->mon == m && (c->isglobal || c->isunglobal)) { - c->tags = m->tagset[m->seltags]; - if (selmon->sel == NULL) - focusclient(c, 0); - } + if (c->mon == m && (c->isglobal || c->isunglobal)) { + c->tags = m->tagset[m->seltags]; + if (selmon->sel == NULL) + focusclient(c, 0); + } - if (c->mon == m) { - if (VISIBLEON(c, m)) { + if (c->mon == m) { + if (VISIBLEON(c, m)) { - if (!client_is_unmanaged(c) && !client_should_ignore_focus(c)) { - m->visible_clients++; - } + if (!client_is_unmanaged(c) && !client_should_ignore_focus(c)) { + m->visible_clients++; + } - if (!c->is_clip_to_hide || - strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name, - "scroller") != 0) { - wlr_scene_node_set_enabled(&c->scene->node, true); - } - client_set_suspended(c, false); - if (!c->animation.from_rule && want_animation && - m->pertag->prevtag != 0 && m->pertag->curtag != 0 && animations) { - c->animation.tagining = true; - if (m->pertag->curtag > m->pertag->prevtag) { - if (c->animation.running) { - c->animainit_geom.x = c->animation.current.x; - c->animainit_geom.y = c->animation.current.y; - } else { - c->animainit_geom.x = tag_animation_direction == VERTICAL - ? c->animation.current.x - : c->mon->m.x + c->mon->m.width; - c->animainit_geom.y = tag_animation_direction == VERTICAL - ? c->mon->m.y + c->mon->m.height - : c->animation.current.y; - } + if (!c->is_clip_to_hide || + strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name, + "scroller") != 0) { + wlr_scene_node_set_enabled(&c->scene->node, true); + } + client_set_suspended(c, false); + if (!c->animation.from_rule && want_animation && + m->pertag->prevtag != 0 && m->pertag->curtag != 0 && + animations) { + c->animation.tagining = true; + if (m->pertag->curtag > m->pertag->prevtag) { + if (c->animation.running) { + c->animainit_geom.x = c->animation.current.x; + c->animainit_geom.y = c->animation.current.y; + } else { + c->animainit_geom.x = + tag_animation_direction == VERTICAL + ? c->animation.current.x + : c->mon->m.x + c->mon->m.width; + c->animainit_geom.y = + tag_animation_direction == VERTICAL + ? c->mon->m.y + c->mon->m.height + : c->animation.current.y; + } - } else { - if (c->animation.running) { - c->animainit_geom.x = c->animation.current.x; - c->animainit_geom.y = c->animation.current.y; - } else { - c->animainit_geom.x = tag_animation_direction == VERTICAL - ? c->animation.current.x - : m->m.x - c->geom.width; - c->animainit_geom.y = tag_animation_direction == VERTICAL - ? m->m.y - c->geom.height - : c->animation.current.y; - } - } - } else { - c->animainit_geom.x = c->animation.current.x; - c->animainit_geom.y = c->animation.current.y; - } + } else { + if (c->animation.running) { + c->animainit_geom.x = c->animation.current.x; + c->animainit_geom.y = c->animation.current.y; + } else { + c->animainit_geom.x = + tag_animation_direction == VERTICAL + ? c->animation.current.x + : m->m.x - c->geom.width; + c->animainit_geom.y = + tag_animation_direction == VERTICAL + ? m->m.y - c->geom.height + : c->animation.current.y; + } + } + } else { + c->animainit_geom.x = c->animation.current.x; + c->animainit_geom.y = c->animation.current.y; + } - c->animation.from_rule = false; - c->animation.tagouting = false; - c->animation.tagouted = false; - resize(c, c->geom, 0); + c->animation.from_rule = false; + c->animation.tagouting = false; + c->animation.tagouted = false; + resize(c, c->geom, 0); - } else { - if ((c->tags & (1 << (m->pertag->prevtag - 1))) && - m->pertag->prevtag != 0 && m->pertag->curtag != 0 && animations) { - c->animation.tagouting = true; - c->animation.tagining = false; - if (m->pertag->curtag > m->pertag->prevtag) { - c->pending = c->geom; - c->pending.x = tag_animation_direction == VERTICAL - ? c->animation.current.x - : c->mon->m.x - c->geom.width; - c->pending.y = tag_animation_direction == VERTICAL - ? c->mon->m.y - c->geom.height - : c->animation.current.y; + } else { + if ((c->tags & (1 << (m->pertag->prevtag - 1))) && + m->pertag->prevtag != 0 && m->pertag->curtag != 0 && + animations) { + c->animation.tagouting = true; + c->animation.tagining = false; + if (m->pertag->curtag > m->pertag->prevtag) { + c->pending = c->geom; + c->pending.x = tag_animation_direction == VERTICAL + ? c->animation.current.x + : c->mon->m.x - c->geom.width; + c->pending.y = tag_animation_direction == VERTICAL + ? c->mon->m.y - c->geom.height + : c->animation.current.y; - resize(c, c->geom, 0); - } else { - c->pending = c->geom; - c->pending.x = tag_animation_direction == VERTICAL - ? c->animation.current.x - : c->mon->m.x + c->mon->m.width; - c->pending.y = tag_animation_direction == VERTICAL - ? c->mon->m.y + c->mon->m.height - : c->animation.current.y; - resize(c, c->geom, 0); - } - } else { - wlr_scene_node_set_enabled(&c->scene->node, false); - client_set_suspended(c, true); - } - } - } + resize(c, c->geom, 0); + } else { + c->pending = c->geom; + c->pending.x = tag_animation_direction == VERTICAL + ? c->animation.current.x + : c->mon->m.x + c->mon->m.width; + c->pending.y = tag_animation_direction == VERTICAL + ? c->mon->m.y + c->mon->m.height + : c->animation.current.y; + resize(c, c->geom, 0); + } + } else { + wlr_scene_node_set_enabled(&c->scene->node, false); + client_set_suspended(c, true); + } + } + } - if (c->mon == m && c->ismaxmizescreen && !c->animation.tagouted && - !c->animation.tagouting && VISIBLEON(c, m)) { - reset_maxmizescreen_size(c); - } - } + if (c->mon == m && c->ismaxmizescreen && !c->animation.tagouted && + !c->animation.tagouting && VISIBLEON(c, m)) { + reset_maxmizescreen_size(c); + } + } - // 给全屏窗口设置背景为黑色 - // 好像要跟LyrFS图层一起使用,我不用这个图层,所以注释掉 - // wlr_scene_node_set_enabled(&m->fullscreen_bg->node, - // (c = focustop(m)) && c->isfullscreen); + // 给全屏窗口设置背景为黑色 + // 好像要跟LyrFS图层一起使用,我不用这个图层,所以注释掉 + // wlr_scene_node_set_enabled(&m->fullscreen_bg->node, + // (c = focustop(m)) && c->isfullscreen); - if (m->isoverview) { - overviewlayout.arrange(m); - } else if (m && m->pertag->ltidxs[m->pertag->curtag]->arrange) { - m->pertag->ltidxs[m->pertag->curtag]->arrange(m); - } + if (m->isoverview) { + overviewlayout.arrange(m); + } else if (m && m->pertag->ltidxs[m->pertag->curtag]->arrange) { + m->pertag->ltidxs[m->pertag->curtag]->arrange(m); + } - motionnotify(0, NULL, 0, 0, 0, 0); - checkidleinhibitor(NULL); + motionnotify(0, NULL, 0, 0, 0, 0); + checkidleinhibitor(NULL); } void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, - int exclusive) { - LayerSurface *l; - struct wlr_box full_area = m->m; + int exclusive) { + LayerSurface *l; + struct wlr_box full_area = m->m; - wl_list_for_each(l, list, link) { - struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; + wl_list_for_each(l, list, link) { + struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; - if (exclusive != (layer_surface->current.exclusive_zone > 0) || - !layer_surface->initialized) - continue; + if (exclusive != (layer_surface->current.exclusive_zone > 0) || + !layer_surface->initialized) + continue; - wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, - usable_area); - wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, - l->scene->node.y); - } + wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, + usable_area); + wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, + l->scene->node.y); + } } Client *center_select(Monitor *m) { - Client *c = NULL; - Client *target_c = NULL; - long int mini_distance = -1; - int dirx, diry; - long int distance; - wl_list_for_each(c, &clients, link) { - if (c && VISIBLEON(c, m) && client_surface(c)->mapped && !c->isfloating && - !client_is_unmanaged(c)) { - dirx = c->geom.x + c->geom.width / 2 - (m->w.x + m->w.width / 2); - diry = c->geom.y + c->geom.height / 2 - (m->w.y + m->w.height / 2); - distance = dirx * dirx + diry * diry; - if (distance < mini_distance || mini_distance == -1) { - mini_distance = distance; - target_c = c; - } - } - } - return target_c; + Client *c = NULL; + Client *target_c = NULL; + long int mini_distance = -1; + int dirx, diry; + long int distance; + wl_list_for_each(c, &clients, link) { + if (c && VISIBLEON(c, m) && client_surface(c)->mapped && + !c->isfloating && !client_is_unmanaged(c)) { + dirx = c->geom.x + c->geom.width / 2 - (m->w.x + m->w.width / 2); + diry = c->geom.y + c->geom.height / 2 - (m->w.y + m->w.height / 2); + distance = dirx * dirx + diry * diry; + if (distance < mini_distance || mini_distance == -1) { + mini_distance = distance; + target_c = c; + } + } + } + return target_c; } void apply_window_snap(Client *c) { - int snap_up = 99999, snap_down = 99999, snap_left = 99999, snap_right = 99999; - int snap_up_temp = 0, snap_down_temp = 0, snap_left_temp = 0, - snap_right_temp = 0; - int snap_up_screen = 0, snap_down_screen = 0, snap_left_screen = 0, - snap_right_screen = 0; - int snap_up_mon = 0, snap_down_mon = 0, snap_left_mon = 0, snap_right_mon = 0; + int snap_up = 99999, snap_down = 99999, snap_left = 99999, + snap_right = 99999; + int snap_up_temp = 0, snap_down_temp = 0, snap_left_temp = 0, + snap_right_temp = 0; + int snap_up_screen = 0, snap_down_screen = 0, snap_left_screen = 0, + snap_right_screen = 0; + int snap_up_mon = 0, snap_down_mon = 0, snap_left_mon = 0, + snap_right_mon = 0; - unsigned int cbw = !render_border || c->fake_no_border ? borderpx : 0; - unsigned int tcbw; - unsigned int cx, cy, cw, ch, tcx, tcy, tcw, tch; - cx = c->geom.x + cbw; - cy = c->geom.y + cbw; - cw = c->geom.width - 2 * cbw; - ch = c->geom.height - 2 * cbw; + unsigned int cbw = !render_border || c->fake_no_border ? borderpx : 0; + unsigned int tcbw; + unsigned int cx, cy, cw, ch, tcx, tcy, tcw, tch; + cx = c->geom.x + cbw; + cy = c->geom.y + cbw; + cw = c->geom.width - 2 * cbw; + ch = c->geom.height - 2 * cbw; - Client *tc; - if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) - return; + Client *tc; + if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) + return; - if (!c->isfloating || !enable_floating_snap) - return; + if (!c->isfloating || !enable_floating_snap) + return; - wl_list_for_each(tc, &clients, link) { - if (tc && tc->isfloating && !tc->iskilling && client_surface(tc)->mapped && - VISIBLEON(tc, c->mon)) { + wl_list_for_each(tc, &clients, link) { + if (tc && tc->isfloating && !tc->iskilling && + client_surface(tc)->mapped && VISIBLEON(tc, c->mon)) { - tcbw = !render_border || tc->fake_no_border ? borderpx : 0; - tcx = tc->geom.x + tcbw; - tcy = tc->geom.y + tcbw; - tcw = tc->geom.width - 2 * tcbw; - tch = tc->geom.height - 2 * tcbw; + tcbw = !render_border || tc->fake_no_border ? borderpx : 0; + tcx = tc->geom.x + tcbw; + tcy = tc->geom.y + tcbw; + tcw = tc->geom.width - 2 * tcbw; + tch = tc->geom.height - 2 * tcbw; - snap_left_temp = cx - tcx - tcw; - snap_right_temp = tcx - cx - cw; - snap_up_temp = cy - tcy - tch; - snap_down_temp = tcy - cy - ch; + snap_left_temp = cx - tcx - tcw; + snap_right_temp = tcx - cx - cw; + snap_up_temp = cy - tcy - tch; + snap_down_temp = tcy - cy - ch; - if (snap_left_temp < snap_left && snap_left_temp >= 0) { - snap_left = snap_left_temp; - } - if (snap_right_temp < snap_right && snap_right_temp >= 0) { - snap_right = snap_right_temp; - } - if (snap_up_temp < snap_up && snap_up_temp >= 0) { - snap_up = snap_up_temp; - } - if (snap_down_temp < snap_down && snap_down_temp >= 0) { - snap_down = snap_down_temp; - } - } - } + if (snap_left_temp < snap_left && snap_left_temp >= 0) { + snap_left = snap_left_temp; + } + if (snap_right_temp < snap_right && snap_right_temp >= 0) { + snap_right = snap_right_temp; + } + if (snap_up_temp < snap_up && snap_up_temp >= 0) { + snap_up = snap_up_temp; + } + if (snap_down_temp < snap_down && snap_down_temp >= 0) { + snap_down = snap_down_temp; + } + } + } - snap_left_mon = cx - c->mon->m.x; - snap_right_mon = c->mon->m.x + c->mon->m.width - cx - cw; - snap_up_mon = cy - c->mon->m.y; - snap_down_mon = c->mon->m.y + c->mon->m.height - cy - ch; + snap_left_mon = cx - c->mon->m.x; + snap_right_mon = c->mon->m.x + c->mon->m.width - cx - cw; + snap_up_mon = cy - c->mon->m.y; + snap_down_mon = c->mon->m.y + c->mon->m.height - cy - ch; - if (snap_up_mon >= 0 && snap_up_mon < snap_up) - snap_up = snap_up_mon; - if (snap_down_mon >= 0 && snap_down_mon < snap_down) - snap_down = snap_down_mon; - if (snap_left_mon >= 0 && snap_left_mon < snap_left) - snap_left = snap_left_mon; - if (snap_right_mon >= 0 && snap_right_mon < snap_right) - snap_right = snap_right_mon; + if (snap_up_mon >= 0 && snap_up_mon < snap_up) + snap_up = snap_up_mon; + if (snap_down_mon >= 0 && snap_down_mon < snap_down) + snap_down = snap_down_mon; + if (snap_left_mon >= 0 && snap_left_mon < snap_left) + snap_left = snap_left_mon; + if (snap_right_mon >= 0 && snap_right_mon < snap_right) + snap_right = snap_right_mon; - snap_left_screen = cx - c->mon->w.x; - snap_right_screen = c->mon->w.x + c->mon->w.width - cx - cw; - snap_up_screen = cy - c->mon->w.y; - snap_down_screen = c->mon->w.y + c->mon->w.height - cy - ch; + snap_left_screen = cx - c->mon->w.x; + snap_right_screen = c->mon->w.x + c->mon->w.width - cx - cw; + snap_up_screen = cy - c->mon->w.y; + snap_down_screen = c->mon->w.y + c->mon->w.height - cy - ch; - if (snap_up_screen >= 0 && snap_up_screen < snap_up) - snap_up = snap_up_screen; - if (snap_down_screen >= 0 && snap_down_screen < snap_down) - snap_down = snap_down_screen; - if (snap_left_screen >= 0 && snap_left_screen < snap_left) - snap_left = snap_left_screen; - if (snap_right_screen >= 0 && snap_right_screen < snap_right) - snap_right = snap_right_screen; + if (snap_up_screen >= 0 && snap_up_screen < snap_up) + snap_up = snap_up_screen; + if (snap_down_screen >= 0 && snap_down_screen < snap_down) + snap_down = snap_down_screen; + if (snap_left_screen >= 0 && snap_left_screen < snap_left) + snap_left = snap_left_screen; + if (snap_right_screen >= 0 && snap_right_screen < snap_right) + snap_right = snap_right_screen; - if (snap_left < snap_right && snap_left < snap_distance) { - c->geom.x = c->geom.x - snap_left; - } + if (snap_left < snap_right && snap_left < snap_distance) { + c->geom.x = c->geom.x - snap_left; + } - if (snap_right <= snap_left && snap_right < snap_distance) { - c->geom.x = c->geom.x + snap_right; - } + if (snap_right <= snap_left && snap_right < snap_distance) { + c->geom.x = c->geom.x + snap_right; + } - if (snap_up < snap_down && snap_up < snap_distance) { - c->geom.y = c->geom.y - snap_up; - } + if (snap_up < snap_down && snap_up < snap_distance) { + c->geom.y = c->geom.y - snap_up; + } - if (snap_down <= snap_up && snap_down < snap_distance) { - c->geom.y = c->geom.y + snap_down; - } + if (snap_down <= snap_up && snap_down < snap_distance) { + c->geom.y = c->geom.y + snap_down; + } - c->oldgeom = c->geom; - resize(c, c->geom, 0); + c->oldgeom = c->geom; + resize(c, c->geom, 0); } Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, - bool align) { - Client *c; - Client **tempClients = NULL; // 初始化为 NULL - int last = -1; + bool align) { + Client *c; + Client **tempClients = NULL; // 初始化为 NULL + int last = -1; - // 第一次遍历,计算客户端数量 - wl_list_for_each(c, &clients, link) { - if (c && (findfloating || !c->isfloating) && !c->isunglobal && - (focus_cross_monitor || c->mon == selmon) && - (c->tags & c->mon->tagset[c->mon->seltags])) { - last++; - } - } + // 第一次遍历,计算客户端数量 + wl_list_for_each(c, &clients, link) { + if (c && (findfloating || !c->isfloating) && !c->isunglobal && + (focus_cross_monitor || c->mon == selmon) && + (c->tags & c->mon->tagset[c->mon->seltags])) { + last++; + } + } - if (last < 0) { - return NULL; // 没有符合条件的客户端 - } + if (last < 0) { + return NULL; // 没有符合条件的客户端 + } - // 动态分配内存 - tempClients = malloc((last + 1) * sizeof(Client *)); - if (!tempClients) { - // 处理内存分配失败的情况 - return NULL; - } + // 动态分配内存 + tempClients = malloc((last + 1) * sizeof(Client *)); + if (!tempClients) { + // 处理内存分配失败的情况 + return NULL; + } - // 第二次遍历,填充 tempClients - last = -1; - wl_list_for_each(c, &clients, link) { - if (c && (findfloating || !c->isfloating) && !c->isunglobal && - (focus_cross_monitor || c->mon == selmon) && - (c->tags & c->mon->tagset[c->mon->seltags])) { - last++; - tempClients[last] = c; - } - } + // 第二次遍历,填充 tempClients + last = -1; + wl_list_for_each(c, &clients, link) { + if (c && (findfloating || !c->isfloating) && !c->isunglobal && + (focus_cross_monitor || c->mon == selmon) && + (c->tags & c->mon->tagset[c->mon->seltags])) { + last++; + tempClients[last] = c; + } + } - int sel_x = tc->geom.x; - int sel_y = tc->geom.y; - long long int distance = LLONG_MAX; - Client *tempFocusClients = NULL; + int sel_x = tc->geom.x; + int sel_y = tc->geom.y; + long long int distance = LLONG_MAX; + Client *tempFocusClients = NULL; - switch (arg->i) { - case UP: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y < sel_y && 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if (!tempFocusClients && !align) { - for (int _i = 0; _i <= last; _i++) { - 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - case DOWN: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y > sel_y && 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if (!tempFocusClients && !align) { - for (int _i = 0; _i <= last; _i++) { - 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - case LEFT: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x < sel_x && 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if (!tempFocusClients && !align) { - for (int _i = 0; _i <= last; _i++) { - 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - case RIGHT: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x > sel_x && 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - if (!tempFocusClients && !align) { - for (int _i = 0; _i <= last; _i++) { - 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; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; - } - } - } - } - break; - } + switch (arg->i) { + case UP: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y < sel_y && + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients && !align) { + for (int _i = 0; _i <= last; _i++) { + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + case DOWN: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y > sel_y && + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients && !align) { + for (int _i = 0; _i <= last; _i++) { + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + case LEFT: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x < sel_x && + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients && !align) { + for (int _i = 0; _i <= last; _i++) { + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + case RIGHT: + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x > sel_x && + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + if (!tempFocusClients && !align) { + for (int _i = 0; _i <= last; _i++) { + 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; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } + } + } + } + break; + } - free(tempClients); // 释放内存 - return tempFocusClients; + free(tempClients); // 释放内存 + return tempFocusClients; } Client *direction_select(const Arg *arg) { - Client *tc = selmon->sel; + Client *tc = selmon->sel; - if (!tc) - return NULL; + if (!tc) + return NULL; - if (tc && (tc->isfullscreen || tc->ismaxmizescreen)) { - // 不支持全屏窗口的焦点切换 - return NULL; - } + if (tc && (tc->isfullscreen || tc->ismaxmizescreen)) { + // 不支持全屏窗口的焦点切换 + return NULL; + } - return find_client_by_direction(tc, arg, true, false); + return find_client_by_direction(tc, arg, true, false); } void focusdir(const Arg *arg) { - Client *c; - c = direction_select(arg); - if (c) { - focusclient(c, 1); - if (warpcursor) - warp_cursor(c); - } else { - if (config.focus_cross_tag) { - if (arg->i == LEFT || arg->i == UP) - viewtoleft_have_client(NULL); - if (arg->i == RIGHT || arg->i == DOWN) - viewtoright_have_client(NULL); - } - } + Client *c; + c = direction_select(arg); + if (c) { + focusclient(c, 1); + if (warpcursor) + warp_cursor(c); + } else { + if (config.focus_cross_tag) { + if (arg->i == LEFT || arg->i == UP) + viewtoleft_have_client(NULL); + if (arg->i == RIGHT || arg->i == DOWN) + viewtoright_have_client(NULL); + } + } } void arrangelayers(Monitor *m) { - int i; - struct wlr_box usable_area = m->m; - LayerSurface *l; - uint32_t layers_above_shell[] = { - ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, - ZWLR_LAYER_SHELL_V1_LAYER_TOP, - }; - if (!m->wlr_output->enabled) - return; + int i; + struct wlr_box usable_area = m->m; + LayerSurface *l; + uint32_t layers_above_shell[] = { + ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, + ZWLR_LAYER_SHELL_V1_LAYER_TOP, + }; + if (!m->wlr_output->enabled) + return; - /* Arrange exclusive surfaces from top->bottom */ - for (i = 3; i >= 0; i--) - arrangelayer(m, &m->layers[i], &usable_area, 1); + /* Arrange exclusive surfaces from top->bottom */ + for (i = 3; i >= 0; i--) + arrangelayer(m, &m->layers[i], &usable_area, 1); - if (!wlr_box_equal(&usable_area, &m->w)) { - m->w = usable_area; - arrange(m, false); - } + if (!wlr_box_equal(&usable_area, &m->w)) { + m->w = usable_area; + arrange(m, false); + } - /* Arrange non-exlusive surfaces from top->bottom */ - for (i = 3; i >= 0; i--) - arrangelayer(m, &m->layers[i], &usable_area, 0); + /* Arrange non-exlusive surfaces from top->bottom */ + for (i = 3; i >= 0; i--) + arrangelayer(m, &m->layers[i], &usable_area, 0); - /* Find topmost keyboard interactive layer, if such a layer exists */ - for (i = 0; i < (int)LENGTH(layers_above_shell); i++) { - wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) { - if (locked || !l->layer_surface->current.keyboard_interactive || - !l->mapped) - continue; - /* Deactivate the focused client. */ - focusclient(NULL, 0); - exclusive_focus = l; - client_notify_enter(l->layer_surface->surface, - wlr_seat_get_keyboard(seat)); - return; - } - } + /* Find topmost keyboard interactive layer, if such a layer exists */ + for (i = 0; i < (int)LENGTH(layers_above_shell); i++) { + wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) { + if (locked || !l->layer_surface->current.keyboard_interactive || + !l->mapped) + continue; + /* Deactivate the focused client. */ + focusclient(NULL, 0); + exclusive_focus = l; + client_notify_enter(l->layer_surface->surface, + wlr_seat_get_keyboard(seat)); + return; + } + } } char *get_autostart_path(char *autostart_path, size_t buf_size) { - const char *maomaoconfig = getenv("MAOMAOCONFIG"); + const char *maomaoconfig = getenv("MAOMAOCONFIG"); - if (maomaoconfig && maomaoconfig[0] != '\0') { - snprintf(autostart_path, buf_size, "%s/autostart.sh", maomaoconfig); - } else { - const char *homedir = getenv("HOME"); - if (!homedir) { - fprintf(stderr, "Error: HOME environment variable not set.\n"); - return NULL; - } - snprintf(autostart_path, buf_size, "%s/.config/maomao/autostart.sh", - homedir); - } + if (maomaoconfig && maomaoconfig[0] != '\0') { + snprintf(autostart_path, buf_size, "%s/autostart.sh", maomaoconfig); + } else { + const char *homedir = getenv("HOME"); + if (!homedir) { + fprintf(stderr, "Error: HOME environment variable not set.\n"); + return NULL; + } + snprintf(autostart_path, buf_size, "%s/.config/maomao/autostart.sh", + homedir); + } - return autostart_path; + return autostart_path; } void // 鼠标滚轮事件 axisnotify(struct wl_listener *listener, void *data) { - /* This event is forwarded by the cursor when a pointer emits an axis event, - * for example when you move the scroll wheel. */ - struct wlr_pointer_axis_event *event = data; - struct wlr_keyboard *keyboard; - uint32_t mods; - AxisBinding *a; - int ji; - unsigned int adir; - // IDLE_NOTIFY_ACTIVITY; - handlecursoractivity(); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - keyboard = wlr_seat_get_keyboard(seat); + /* This event is forwarded by the cursor when a pointer emits an axis event, + * for example when you move the scroll wheel. */ + struct wlr_pointer_axis_event *event = data; + struct wlr_keyboard *keyboard; + uint32_t mods; + AxisBinding *a; + int ji; + unsigned int adir; + // IDLE_NOTIFY_ACTIVITY; + handlecursoractivity(); + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + keyboard = wlr_seat_get_keyboard(seat); - // 获取当前按键的mask,比如alt+super或者alt+ctrl - mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; + // 获取当前按键的mask,比如alt+super或者alt+ctrl + mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; - if (event->orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) - adir = event->delta > 0 ? AxisDown : AxisUp; - else - adir = event->delta > 0 ? AxisRight : AxisLeft; + if (event->orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) + adir = event->delta > 0 ? AxisDown : AxisUp; + else + adir = event->delta > 0 ? AxisRight : AxisLeft; - for (ji = 0; ji < config.axis_bindings_count; ji++) { - if (config.axis_bindings_count < 1) - break; - a = &config.axis_bindings[ji]; - if (CLEANMASK(mods) == CLEANMASK(a->mod) && // 按键一致 - adir == a->dir && a->func) { // 滚轮方向判断一致且处理函数存在 - if (event->time_msec - axis_apply_time > axis_bind_apply_timeout || - axis_apply_dir * event->delta < 0) { - a->func(&a->arg); - axis_apply_time = event->time_msec; - axis_apply_dir = event->delta > 0 ? 1 : -1; - return; // 如果成功匹配就不把这个滚轮事件传送给客户端了 - } else { - axis_apply_dir = event->delta > 0 ? 1 : -1; - axis_apply_time = event->time_msec; - return; - } - } - } + for (ji = 0; ji < config.axis_bindings_count; ji++) { + if (config.axis_bindings_count < 1) + break; + a = &config.axis_bindings[ji]; + if (CLEANMASK(mods) == CLEANMASK(a->mod) && // 按键一致 + adir == a->dir && a->func) { // 滚轮方向判断一致且处理函数存在 + if (event->time_msec - axis_apply_time > axis_bind_apply_timeout || + axis_apply_dir * event->delta < 0) { + a->func(&a->arg); + axis_apply_time = event->time_msec; + axis_apply_dir = event->delta > 0 ? 1 : -1; + return; // 如果成功匹配就不把这个滚轮事件传送给客户端了 + } else { + axis_apply_dir = event->delta > 0 ? 1 : -1; + axis_apply_time = event->time_msec; + return; + } + } + } - /* TODO: allow usage of scroll whell for mousebindings, it can be implemented - * checking the event's orientation and the delta of the event */ - /* Notify the client with pointer focus of the axis event. */ - wlr_seat_pointer_notify_axis(seat, // 滚轮事件发送给客户端也就是窗口 - event->time_msec, event->orientation, - event->delta, event->delta_discrete, - event->source, event->relative_direction); + /* TODO: allow usage of scroll whell for mousebindings, it can be + * implemented checking the event's orientation and the delta of the event + */ + /* Notify the client with pointer focus of the axis event. */ + wlr_seat_pointer_notify_axis(seat, // 滚轮事件发送给客户端也就是窗口 + event->time_msec, event->orientation, + event->delta, event->delta_discrete, + event->source, event->relative_direction); } int ongesture(struct wlr_pointer_swipe_end_event *event) { - struct wlr_keyboard *keyboard; - uint32_t mods; - const GestureBinding *g; - unsigned int motion; - unsigned int adx = (int)round(fabs(swipe_dx)); - unsigned int ady = (int)round(fabs(swipe_dy)); - int handled = 0; - int ji; + struct wlr_keyboard *keyboard; + uint32_t mods; + const GestureBinding *g; + unsigned int motion; + unsigned int adx = (int)round(fabs(swipe_dx)); + unsigned int ady = (int)round(fabs(swipe_dy)); + int handled = 0; + int ji; - if (event->cancelled) { - return handled; - } + if (event->cancelled) { + return handled; + } - // Require absolute distance movement beyond a small thresh-hold - if (adx * adx + ady * ady < swipe_min_threshold * swipe_min_threshold) { - return handled; - } + // Require absolute distance movement beyond a small thresh-hold + if (adx * adx + ady * ady < swipe_min_threshold * swipe_min_threshold) { + return handled; + } - if (adx > ady) { - motion = swipe_dx < 0 ? SWIPE_LEFT : SWIPE_RIGHT; - } else { - motion = swipe_dy < 0 ? SWIPE_UP : SWIPE_DOWN; - } + if (adx > ady) { + motion = swipe_dx < 0 ? SWIPE_LEFT : SWIPE_RIGHT; + } else { + motion = swipe_dy < 0 ? SWIPE_UP : SWIPE_DOWN; + } - keyboard = wlr_seat_get_keyboard(seat); - mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; + keyboard = wlr_seat_get_keyboard(seat); + mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; - for (ji = 0; ji < config.gesture_bindings_count; ji++) { - if (config.gesture_bindings_count < 1) - break; - g = &config.gesture_bindings[ji]; - if (CLEANMASK(mods) == CLEANMASK(g->mod) && - swipe_fingers == g->fingers_count && motion == g->motion && g->func) { - g->func(&g->arg); - handled = 1; - } - } - return handled; + for (ji = 0; ji < config.gesture_bindings_count; ji++) { + if (config.gesture_bindings_count < 1) + break; + g = &config.gesture_bindings[ji]; + if (CLEANMASK(mods) == CLEANMASK(g->mod) && + swipe_fingers == g->fingers_count && motion == g->motion && + g->func) { + g->func(&g->arg); + handled = 1; + } + } + return handled; } void swipe_begin(struct wl_listener *listener, void *data) { - struct wlr_pointer_swipe_begin_event *event = data; + struct wlr_pointer_swipe_begin_event *event = data; - // Forward swipe begin event to client - wlr_pointer_gestures_v1_send_swipe_begin(pointer_gestures, seat, - event->time_msec, event->fingers); + // Forward swipe begin event to client + wlr_pointer_gestures_v1_send_swipe_begin(pointer_gestures, seat, + event->time_msec, event->fingers); } void swipe_update(struct wl_listener *listener, void *data) { - struct wlr_pointer_swipe_update_event *event = data; + struct wlr_pointer_swipe_update_event *event = data; - swipe_fingers = event->fingers; - // Accumulate swipe distance - swipe_dx += event->dx; - swipe_dy += event->dy; + swipe_fingers = event->fingers; + // Accumulate swipe distance + swipe_dx += event->dx; + swipe_dy += event->dy; - // Forward swipe update event to client - wlr_pointer_gestures_v1_send_swipe_update( - pointer_gestures, seat, event->time_msec, event->dx, event->dy); + // Forward swipe update event to client + wlr_pointer_gestures_v1_send_swipe_update( + pointer_gestures, seat, event->time_msec, event->dx, event->dy); } void swipe_end(struct wl_listener *listener, void *data) { - struct wlr_pointer_swipe_end_event *event = data; - ongesture(event); - swipe_dx = 0; - swipe_dy = 0; - // Forward swipe end event to client - wlr_pointer_gestures_v1_send_swipe_end(pointer_gestures, seat, - event->time_msec, event->cancelled); + struct wlr_pointer_swipe_end_event *event = data; + ongesture(event); + swipe_dx = 0; + swipe_dy = 0; + // Forward swipe end event to client + wlr_pointer_gestures_v1_send_swipe_end(pointer_gestures, seat, + event->time_msec, event->cancelled); } void pinch_begin(struct wl_listener *listener, void *data) { - struct wlr_pointer_pinch_begin_event *event = data; + struct wlr_pointer_pinch_begin_event *event = data; - // Forward pinch begin event to client - wlr_pointer_gestures_v1_send_pinch_begin(pointer_gestures, seat, - event->time_msec, event->fingers); + // Forward pinch begin event to client + wlr_pointer_gestures_v1_send_pinch_begin(pointer_gestures, seat, + event->time_msec, event->fingers); } void pinch_update(struct wl_listener *listener, void *data) { - struct wlr_pointer_pinch_update_event *event = data; + struct wlr_pointer_pinch_update_event *event = data; - // Forward pinch update event to client - wlr_pointer_gestures_v1_send_pinch_update( - pointer_gestures, seat, event->time_msec, event->dx, event->dy, - event->scale, event->rotation); + // Forward pinch update event to client + wlr_pointer_gestures_v1_send_pinch_update( + pointer_gestures, seat, event->time_msec, event->dx, event->dy, + event->scale, event->rotation); } void pinch_end(struct wl_listener *listener, void *data) { - struct wlr_pointer_pinch_end_event *event = data; + struct wlr_pointer_pinch_end_event *event = data; - // Forward pinch end event to client - wlr_pointer_gestures_v1_send_pinch_end(pointer_gestures, seat, - event->time_msec, event->cancelled); + // Forward pinch end event to client + wlr_pointer_gestures_v1_send_pinch_end(pointer_gestures, seat, + event->time_msec, event->cancelled); } void hold_begin(struct wl_listener *listener, void *data) { - struct wlr_pointer_hold_begin_event *event = data; + struct wlr_pointer_hold_begin_event *event = data; - // Forward hold begin event to client - wlr_pointer_gestures_v1_send_hold_begin(pointer_gestures, seat, - event->time_msec, event->fingers); + // Forward hold begin event to client + wlr_pointer_gestures_v1_send_hold_begin(pointer_gestures, seat, + event->time_msec, event->fingers); } void hold_end(struct wl_listener *listener, void *data) { - struct wlr_pointer_hold_end_event *event = data; + struct wlr_pointer_hold_end_event *event = data; - // Forward hold end event to client - wlr_pointer_gestures_v1_send_hold_end(pointer_gestures, seat, - event->time_msec, event->cancelled); + // Forward hold end event to client + wlr_pointer_gestures_v1_send_hold_end(pointer_gestures, seat, + event->time_msec, event->cancelled); } void place_drag_tile_client(Client *c) { - Client *tc = NULL; - Client *closest_client = NULL; - long min_distant = LONG_MAX; - long temp_distant; - unsigned int x, y; + Client *tc = NULL; + Client *closest_client = NULL; + long min_distant = LONG_MAX; + long temp_distant; + unsigned int x, y; - wl_list_for_each(tc, &clients, link) { - if (tc != c && ISTILED(tc) && VISIBLEON(tc, c->mon)) { - x = tc->geom.x + tc->geom.width / 2 - cursor->x; - y = tc->geom.y + tc->geom.height / 2 - cursor->y; - temp_distant = x * x + y * y; - if (temp_distant < min_distant) { - min_distant = temp_distant; - closest_client = tc; - } - } - } - if (closest_client && closest_client->link.prev != &c->link) { - wl_list_remove(&c->link); - c->link.next = &closest_client->link; - c->link.prev = closest_client->link.prev; - closest_client->link.prev->next = &c->link; - closest_client->link.prev = &c->link; - } else if (closest_client) { - exchange_two_client(c, closest_client); - } - setfloating(c, 0); + wl_list_for_each(tc, &clients, link) { + if (tc != c && ISTILED(tc) && VISIBLEON(tc, c->mon)) { + x = tc->geom.x + tc->geom.width / 2 - cursor->x; + y = tc->geom.y + tc->geom.height / 2 - cursor->y; + temp_distant = x * x + y * y; + if (temp_distant < min_distant) { + min_distant = temp_distant; + closest_client = tc; + } + } + } + if (closest_client && closest_client->link.prev != &c->link) { + wl_list_remove(&c->link); + c->link.next = &closest_client->link; + c->link.prev = closest_client->link.prev; + closest_client->link.prev->next = &c->link; + closest_client->link.prev = &c->link; + } else if (closest_client) { + exchange_two_client(c, closest_client); + } + setfloating(c, 0); } void // 鼠标按键事件 buttonpress(struct wl_listener *listener, void *data) { - struct wlr_pointer_button_event *event = data; - struct wlr_keyboard *keyboard; - uint32_t mods; - Client *c; - Client *tmpc; - int ji; - const MouseBinding *b; - struct wlr_surface *surface; + struct wlr_pointer_button_event *event = data; + struct wlr_keyboard *keyboard; + uint32_t mods; + Client *c; + Client *tmpc; + int ji; + const MouseBinding *b; + struct wlr_surface *surface; - struct wlr_surface *old_pointer_focus_surface = - seat->pointer_state.focused_surface; + struct wlr_surface *old_pointer_focus_surface = + seat->pointer_state.focused_surface; - handlecursoractivity(); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + handlecursoractivity(); + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - switch (event->state) { - case WL_POINTER_BUTTON_STATE_PRESSED: - cursor_mode = CurPressed; - selmon = xytomon(cursor->x, cursor->y); - if (locked) - break; + switch (event->state) { + case WL_POINTER_BUTTON_STATE_PRESSED: + cursor_mode = CurPressed; + selmon = xytomon(cursor->x, cursor->y); + if (locked) + break; - /* Change focus if the button was _pressed_ over a client */ - xytonode(cursor->x, cursor->y, &surface, &c, NULL, NULL, NULL); - if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) - focusclient(c, 1); + /* Change focus if the button was _pressed_ over a client */ + xytonode(cursor->x, cursor->y, &surface, &c, NULL, NULL, NULL); + if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) + focusclient(c, 1); - if (surface != old_pointer_focus_surface) - wlr_seat_pointer_notify_clear_focus(seat); + if (surface != old_pointer_focus_surface) + 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) - break; - b = &config.mouse_bindings[ji]; - if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button && - b->func && (selmon->isoverview == 1 || b->button == BTN_MIDDLE) && - c) { - b->func(&b->arg); - return; - } else if (CLEANMASK(mods) == CLEANMASK(b->mod) && - event->button == b->button && b->func && - CLEANMASK(b->mod) != 0) { - b->func(&b->arg); - return; - } - } - break; - case WL_POINTER_BUTTON_STATE_RELEASED: - /* If you released any buttons, we exit interactive move/resize mode. */ - if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { - cursor_mode = CurNormal; - /* Clear the pointer focus, this way if the cursor is over a surface - * we will send an enter event after which the client will provide us - * a cursor surface */ - wlr_seat_pointer_clear_focus(seat); - motionnotify(0, NULL, 0, 0, 0, 0); - /* Drop the window off on its new monitor */ - if (grabc == selmon->sel) { - selmon->sel = NULL; - } - selmon = xytomon(cursor->x, cursor->y); - setmon(grabc, selmon, 0, true); - reset_foreign_tolevel(grabc); - selmon->prevsel = selmon->sel; - selmon->sel = grabc; - tmpc = grabc; - grabc = NULL; - if (tmpc->drag_to_tile && drag_tile_to_tile) { - place_drag_tile_client(tmpc); - } else { - apply_window_snap(tmpc); - } - tmpc->drag_to_tile = false; - return; - } else { - cursor_mode = CurNormal; - } - break; - } - /* If the event wasn't handled by the compositor, notify the client with - * pointer focus that a button press has occurred */ - wlr_seat_pointer_notify_button(seat, event->time_msec, event->button, - event->state); + 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) + break; + b = &config.mouse_bindings[ji]; + if (CLEANMASK(mods) == CLEANMASK(b->mod) && + event->button == b->button && b->func && + (selmon->isoverview == 1 || b->button == BTN_MIDDLE) && c) { + b->func(&b->arg); + return; + } else if (CLEANMASK(mods) == CLEANMASK(b->mod) && + event->button == b->button && b->func && + CLEANMASK(b->mod) != 0) { + b->func(&b->arg); + return; + } + } + break; + case WL_POINTER_BUTTON_STATE_RELEASED: + /* If you released any buttons, we exit interactive move/resize mode. */ + if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { + cursor_mode = CurNormal; + /* Clear the pointer focus, this way if the cursor is over a surface + * we will send an enter event after which the client will provide + * us a cursor surface */ + wlr_seat_pointer_clear_focus(seat); + motionnotify(0, NULL, 0, 0, 0, 0); + /* Drop the window off on its new monitor */ + if (grabc == selmon->sel) { + selmon->sel = NULL; + } + selmon = xytomon(cursor->x, cursor->y); + setmon(grabc, selmon, 0, true); + reset_foreign_tolevel(grabc); + selmon->prevsel = selmon->sel; + selmon->sel = grabc; + tmpc = grabc; + grabc = NULL; + if (tmpc->drag_to_tile && drag_tile_to_tile) { + place_drag_tile_client(tmpc); + } else { + apply_window_snap(tmpc); + } + tmpc->drag_to_tile = false; + return; + } else { + cursor_mode = CurNormal; + } + break; + } + /* If the event wasn't handled by the compositor, notify the client with + * pointer focus that a button press has occurred */ + wlr_seat_pointer_notify_button(seat, event->time_msec, event->button, + event->state); } void chvt(const Arg *arg) { wlr_session_change_vt(session, arg->ui); } void checkidleinhibitor(struct wlr_surface *exclude) { - int inhibited = 0, unused_lx, unused_ly; - struct wlr_idle_inhibitor_v1 *inhibitor; - wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { - struct wlr_surface *surface = - wlr_surface_get_root_surface(inhibitor->surface); - struct wlr_scene_tree *tree = surface->data; - if (exclude != surface && - (bypass_surface_visibility || - (!tree || - wlr_scene_node_coords(&tree->node, &unused_lx, &unused_ly)))) { - inhibited = 1; - break; - } - } + int inhibited = 0, unused_lx, unused_ly; + struct wlr_idle_inhibitor_v1 *inhibitor; + wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { + struct wlr_surface *surface = + wlr_surface_get_root_surface(inhibitor->surface); + struct wlr_scene_tree *tree = surface->data; + if (exclude != surface && + (bypass_surface_visibility || + (!tree || + wlr_scene_node_coords(&tree->node, &unused_lx, &unused_ly)))) { + inhibited = 1; + break; + } + } - wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited); + wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited); } void setcursorshape(struct wl_listener *listener, void *data) { - struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data; - if (cursor_mode != CurNormal && cursor_mode != CurPressed) - return; - /* This can be sent by any client, so we check to make sure this one is - * actually has pointer focus first. If so, we can tell the cursor to - * use the provided cursor shape. */ - if (event->seat_client == seat->pointer_state.focused_client) { - last_cursor.shape = event->shape; - last_cursor.surface = NULL; - if (!cursor_hidden) - wlr_cursor_set_xcursor(cursor, cursor_mgr, - wlr_cursor_shape_v1_name(event->shape)); - } + struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data; + if (cursor_mode != CurNormal && cursor_mode != CurPressed) + return; + /* This can be sent by any client, so we check to make sure this one is + * actually has pointer focus first. If so, we can tell the cursor to + * use the provided cursor shape. */ + if (event->seat_client == seat->pointer_state.focused_client) { + last_cursor.shape = event->shape; + last_cursor.surface = NULL; + if (!cursor_hidden) + wlr_cursor_set_xcursor(cursor, cursor_mgr, + wlr_cursor_shape_v1_name(event->shape)); + } } void cleanuplisteners(void) { - wl_list_remove(&cursor_axis.link); - wl_list_remove(&cursor_button.link); - wl_list_remove(&cursor_frame.link); - wl_list_remove(&cursor_motion.link); - wl_list_remove(&cursor_motion_absolute.link); - wl_list_remove(&gpu_reset.link); - wl_list_remove(&new_idle_inhibitor.link); - wl_list_remove(&layout_change.link); - wl_list_remove(&new_input_device.link); - wl_list_remove(&new_virtual_keyboard.link); - wl_list_remove(&new_virtual_pointer.link); - wl_list_remove(&new_pointer_constraint.link); - wl_list_remove(&new_output.link); - wl_list_remove(&new_xdg_toplevel.link); - wl_list_remove(&new_xdg_decoration.link); - wl_list_remove(&new_xdg_popup.link); - wl_list_remove(&new_layer_surface.link); - wl_list_remove(&output_mgr_apply.link); - wl_list_remove(&output_mgr_test.link); - wl_list_remove(&output_power_mgr_set_mode.link); - wl_list_remove(&request_activate.link); - wl_list_remove(&request_cursor.link); - wl_list_remove(&request_set_psel.link); - wl_list_remove(&request_set_sel.link); - wl_list_remove(&request_set_cursor_shape.link); - wl_list_remove(&request_start_drag.link); - wl_list_remove(&start_drag.link); - wl_list_remove(&new_session_lock.link); + wl_list_remove(&cursor_axis.link); + wl_list_remove(&cursor_button.link); + wl_list_remove(&cursor_frame.link); + wl_list_remove(&cursor_motion.link); + wl_list_remove(&cursor_motion_absolute.link); + wl_list_remove(&gpu_reset.link); + wl_list_remove(&new_idle_inhibitor.link); + wl_list_remove(&layout_change.link); + wl_list_remove(&new_input_device.link); + wl_list_remove(&new_virtual_keyboard.link); + wl_list_remove(&new_virtual_pointer.link); + wl_list_remove(&new_pointer_constraint.link); + wl_list_remove(&new_output.link); + wl_list_remove(&new_xdg_toplevel.link); + wl_list_remove(&new_xdg_decoration.link); + wl_list_remove(&new_xdg_popup.link); + wl_list_remove(&new_layer_surface.link); + wl_list_remove(&output_mgr_apply.link); + wl_list_remove(&output_mgr_test.link); + wl_list_remove(&output_power_mgr_set_mode.link); + wl_list_remove(&request_activate.link); + wl_list_remove(&request_cursor.link); + wl_list_remove(&request_set_psel.link); + wl_list_remove(&request_set_sel.link); + wl_list_remove(&request_set_cursor_shape.link); + wl_list_remove(&request_start_drag.link); + wl_list_remove(&start_drag.link); + wl_list_remove(&new_session_lock.link); #ifdef XWAYLAND - wl_list_remove(&new_xwayland_surface.link); - wl_list_remove(&xwayland_ready.link); + wl_list_remove(&new_xwayland_surface.link); + wl_list_remove(&xwayland_ready.link); #endif } void cleanup(void) { - cleanuplisteners(); + cleanuplisteners(); #ifdef XWAYLAND - wlr_xwayland_destroy(xwayland); - xwayland = NULL; + wlr_xwayland_destroy(xwayland); + xwayland = NULL; #endif - wl_display_destroy_clients(dpy); - if (child_pid > 0) { - kill(-child_pid, SIGTERM); - waitpid(child_pid, NULL, 0); - } - wlr_xcursor_manager_destroy(cursor_mgr); + wl_display_destroy_clients(dpy); + if (child_pid > 0) { + kill(-child_pid, SIGTERM); + waitpid(child_pid, NULL, 0); + } + wlr_xcursor_manager_destroy(cursor_mgr); - destroykeyboardgroup(&kb_group->destroy, NULL); + destroykeyboardgroup(&kb_group->destroy, NULL); - input_method_relay_finish(input_method_relay); + input_method_relay_finish(input_method_relay); - /* If it's not destroyed manually it will cause a use-after-free of wlr_seat. - * Destroy it until it's fixed in the wlroots side */ - wlr_backend_destroy(backend); + /* If it's not destroyed manually it will cause a use-after-free of + * wlr_seat. Destroy it until it's fixed in the wlroots side */ + wlr_backend_destroy(backend); - wl_display_destroy(dpy); - /* Destroy after the wayland display (when the monitors are already destroyed) - to avoid destroying them with an invalid scene output. */ - wlr_scene_node_destroy(&scene->tree.node); + wl_display_destroy(dpy); + /* Destroy after the wayland display (when the monitors are already + destroyed) to avoid destroying them with an invalid scene output. */ + wlr_scene_node_destroy(&scene->tree.node); } void // 17 cleanupkeyboard(struct wl_listener *listener, void *data) { - Keyboard *kb = wl_container_of(listener, kb, destroy); + Keyboard *kb = wl_container_of(listener, kb, destroy); - wl_event_source_remove(kb->key_repeat_source); - wl_list_remove(&kb->link); - wl_list_remove(&kb->modifiers.link); - wl_list_remove(&kb->key.link); - wl_list_remove(&kb->destroy.link); - free(kb); + wl_event_source_remove(kb->key_repeat_source); + wl_list_remove(&kb->link); + wl_list_remove(&kb->modifiers.link); + wl_list_remove(&kb->key.link); + wl_list_remove(&kb->destroy.link); + free(kb); } void cleanupmon(struct wl_listener *listener, void *data) { - Monitor *m = wl_container_of(listener, m, destroy); - LayerSurface *l, *tmp; - size_t i; + Monitor *m = wl_container_of(listener, m, destroy); + LayerSurface *l, *tmp; + size_t i; - /* 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) - wlr_layer_surface_v1_destroy(l->layer_surface); - } + /* 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) + wlr_layer_surface_v1_destroy(l->layer_surface); + } - wl_list_remove(&m->destroy.link); - wl_list_remove(&m->frame.link); - wl_list_remove(&m->link); - wl_list_remove(&m->request_state.link); - m->wlr_output->data = NULL; - wlr_output_layout_remove(output_layout, m->wlr_output); - wlr_scene_output_destroy(m->scene_output); + wl_list_remove(&m->destroy.link); + wl_list_remove(&m->frame.link); + wl_list_remove(&m->link); + wl_list_remove(&m->request_state.link); + m->wlr_output->data = NULL; + wlr_output_layout_remove(output_layout, m->wlr_output); + wlr_scene_output_destroy(m->scene_output); - closemon(m); - // wlr_scene_node_destroy(&m->fullscreen_bg->node); - free(m); + closemon(m); + // wlr_scene_node_destroy(&m->fullscreen_bg->node); + free(m); } void closemon(Monitor *m) { - /* update selmon if needed and - * move closed monitor's clients to the focused one */ - Client *c; - int i = 0, nmons = wl_list_length(&mons); - if (!nmons) { - selmon = NULL; - } else if (m == selmon) { - do /* don't switch to disabled mons */ - selmon = wl_container_of(mons.next, selmon, link); - while (!selmon->wlr_output->enabled && i++ < nmons); + /* update selmon if needed and + * move closed monitor's clients to the focused one */ + Client *c; + int i = 0, nmons = wl_list_length(&mons); + if (!nmons) { + selmon = NULL; + } else if (m == selmon) { + do /* don't switch to disabled mons */ + selmon = wl_container_of(mons.next, selmon, link); + while (!selmon->wlr_output->enabled && i++ < nmons); - if (!selmon->wlr_output->enabled) - selmon = NULL; - } + if (!selmon->wlr_output->enabled) + selmon = NULL; + } - wl_list_for_each(c, &clients, link) { - if (c->isfloating && c->geom.x > m->m.width) - resize(c, - (struct wlr_box){.x = c->geom.x - m->w.width, - .y = c->geom.y, - .width = c->geom.width, - .height = c->geom.height}, - 0); - if (c->mon == m) { - if (selmon == NULL) { - remove_foreign_topleve(c); - c->mon = NULL; - } else { - setmon(c, selmon, c->tags, true); - reset_foreign_tolevel(c); - } - } - } - if (selmon) { - focusclient(focustop(selmon), 1); - printstatus(); - } + wl_list_for_each(c, &clients, link) { + if (c->isfloating && c->geom.x > m->m.width) + resize(c, + (struct wlr_box){.x = c->geom.x - m->w.width, + .y = c->geom.y, + .width = c->geom.width, + .height = c->geom.height}, + 0); + if (c->mon == m) { + if (selmon == NULL) { + remove_foreign_topleve(c); + c->mon = NULL; + } else { + setmon(c, selmon, c->tags, true); + reset_foreign_tolevel(c); + } + } + } + if (selmon) { + focusclient(focustop(selmon), 1); + printstatus(); + } } void commitlayersurfacenotify(struct wl_listener *listener, void *data) { - LayerSurface *l = wl_container_of(listener, l, surface_commit); - struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; - struct wlr_scene_tree *scene_layer = - layers[layermap[layer_surface->current.layer]]; - struct wlr_layer_surface_v1_state old_state; + LayerSurface *l = wl_container_of(listener, l, surface_commit); + struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; + struct wlr_scene_tree *scene_layer = + layers[layermap[layer_surface->current.layer]]; + struct wlr_layer_surface_v1_state old_state; - if (l->layer_surface->initial_commit) { - client_set_scale(layer_surface->surface, l->mon->wlr_output->scale); + if (l->layer_surface->initial_commit) { + client_set_scale(layer_surface->surface, l->mon->wlr_output->scale); - /* Temporarily set the layer's current state to pending - * so that we can easily arrange it */ - old_state = l->layer_surface->current; - l->layer_surface->current = l->layer_surface->pending; - arrangelayers(l->mon); - l->layer_surface->current = old_state; - return; - } + /* Temporarily set the layer's current state to pending + * so that we can easily arrange it */ + old_state = l->layer_surface->current; + l->layer_surface->current = l->layer_surface->pending; + arrangelayers(l->mon); + l->layer_surface->current = old_state; + return; + } - if (layer_surface->current.committed == 0 && - l->mapped == layer_surface->surface->mapped) - return; - l->mapped = layer_surface->surface->mapped; + if (layer_surface->current.committed == 0 && + l->mapped == layer_surface->surface->mapped) + return; + l->mapped = layer_surface->surface->mapped; - if (scene_layer != l->scene->node.parent) { - wlr_scene_node_reparent(&l->scene->node, scene_layer); - wl_list_remove(&l->link); - wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link); - wlr_scene_node_reparent( - &l->popups->node, - (layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP - ? layers[LyrTop] - : scene_layer)); - } + if (scene_layer != l->scene->node.parent) { + wlr_scene_node_reparent(&l->scene->node, scene_layer); + wl_list_remove(&l->link); + wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link); + wlr_scene_node_reparent( + &l->popups->node, + (layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP + ? layers[LyrTop] + : scene_layer)); + } - arrangelayers(l->mon); + arrangelayers(l->mon); } void client_set_pending_state(Client *c) { - // 判断是否需要动画 - if (!animations) { - c->animation.should_animate = false; - } else if (animations && c->animation.tagining) { - c->animation.should_animate = true; - } else if (!animations || c == grabc || - (!c->is_open_animation && - wlr_box_equal(&c->current, &c->pending))) { - c->animation.should_animate = false; - } else { - c->animation.should_animate = true; - } + // 判断是否需要动画 + if (!animations) { + c->animation.should_animate = false; + } else if (animations && c->animation.tagining) { + c->animation.should_animate = true; + } else if (!animations || c == grabc || + (!c->is_open_animation && + wlr_box_equal(&c->current, &c->pending))) { + c->animation.should_animate = false; + } else { + c->animation.should_animate = true; + } - // 开始动画 - client_commit(c); - c->dirty = true; + // 开始动画 + client_commit(c); + c->dirty = true; } double output_frame_duration_ms(Client *c) { - int32_t refresh_total = 0; - Monitor *m; - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) { - continue; - } - refresh_total += m->wlr_output->refresh; - } - return 1000000.0 / refresh_total; + int32_t refresh_total = 0; + Monitor *m; + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + refresh_total += m->wlr_output->refresh; + } + return 1000000.0 / refresh_total; } void client_commit(Client *c) { - c->current = c->pending; // 设置动画的结束位置 + c->current = c->pending; // 设置动画的结束位置 - if (c->animation.should_animate) { - if (!c->animation.running) { - c->animation.current = c->animainit_geom; - } + if (c->animation.should_animate) { + if (!c->animation.running) { + c->animation.current = c->animainit_geom; + } - c->animation.initial = c->animainit_geom; - // 设置动画速度 - c->animation.passed_frames = 0; - c->animation.total_frames = - c->animation.duration / output_frame_duration_ms(c); + c->animation.initial = c->animainit_geom; + // 设置动画速度 + c->animation.passed_frames = 0; + c->animation.total_frames = + c->animation.duration / output_frame_duration_ms(c); - // 标记动画开始 - c->animation.running = true; - c->animation.should_animate = false; - } - // 请求刷新屏幕 - wlr_output_schedule_frame(c->mon->wlr_output); + // 标记动画开始 + c->animation.running = true; + c->animation.should_animate = false; + } + // 请求刷新屏幕 + wlr_output_schedule_frame(c->mon->wlr_output); } void commitnotify(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, commit); + Client *c = wl_container_of(listener, c, commit); - if (!c->surface.xdg->initialized) - return; + if (!c->surface.xdg->initialized) + return; - if (c->surface.xdg->initial_commit) { - // xdg client will first enter this before mapnotify - applyrules(c); - if (c->mon) { - client_set_scale(client_surface(c), c->mon->wlr_output->scale); - } - setmon(c, NULL, 0, true); /* Make sure to reapply rules in mapnotify() */ - wlr_xdg_toplevel_set_wm_capabilities( - c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); - wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); - client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | - WLR_EDGE_RIGHT); - if (c->decoration) - requestdecorationmode(&c->set_decoration_mode, c->decoration); - return; - } + if (c->surface.xdg->initial_commit) { + // xdg client will first enter this before mapnotify + applyrules(c); + if (c->mon) { + client_set_scale(client_surface(c), c->mon->wlr_output->scale); + } + setmon(c, NULL, 0, + true); /* Make sure to reapply rules in mapnotify() */ + wlr_xdg_toplevel_set_wm_capabilities( + c->surface.xdg->toplevel, + WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); + client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | + WLR_EDGE_RIGHT); + if (c->decoration) + requestdecorationmode(&c->set_decoration_mode, c->decoration); + return; + } - if (!c || c->iskilling || c->animation.tagouting || c->animation.tagouted || - c->animation.tagining) - return; + if (!c || c->iskilling || c->animation.tagouting || c->animation.tagouted || + c->animation.tagining) + return; - if (c == grabc) - return; + if (c == grabc) + return; - if (client_is_unmanaged(c)) - return; + if (client_is_unmanaged(c)) + return; - uint32_t serial = c->surface.xdg->current.configure_serial; - if (!c->dirty || serial < c->configure_serial) - return; + uint32_t serial = c->surface.xdg->current.configure_serial; + if (!c->dirty || serial < c->configure_serial) + return; - struct wlr_box geometry; - client_get_geometry(c, &geometry); + struct wlr_box geometry; + client_get_geometry(c, &geometry); - if (geometry.width == c->geom.width - 2 * c->bw && - geometry.height == c->geom.height - 2 * c->bw) { - c->dirty = false; - return; - } + if (geometry.width == c->geom.width - 2 * c->bw && + geometry.height == c->geom.height - 2 * c->bw) { + c->dirty = false; + return; + } - if (geometry.width == c->animation.current.width - 2 * c->bw && - geometry.height == c->animation.current.height - 2 * c->bw) { - return; - } + if (geometry.width == c->animation.current.width - 2 * c->bw && + geometry.height == c->animation.current.height - 2 * c->bw) { + return; + } - resize(c, c->geom, 0); + resize(c, c->geom, 0); } void destroydecoration(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, destroy_decoration); + Client *c = wl_container_of(listener, c, destroy_decoration); - wl_list_remove(&c->destroy_decoration.link); - wl_list_remove(&c->set_decoration_mode.link); + wl_list_remove(&c->destroy_decoration.link); + wl_list_remove(&c->set_decoration_mode.link); } void commitpopup(struct wl_listener *listener, void *data) { - struct wlr_surface *surface = data; - struct wlr_xdg_popup *popup = wlr_xdg_popup_try_from_wlr_surface(surface); - LayerSurface *l = NULL; - Client *c = NULL; - struct wlr_box box; - int type = -1; + struct wlr_surface *surface = data; + struct wlr_xdg_popup *popup = wlr_xdg_popup_try_from_wlr_surface(surface); + LayerSurface *l = NULL; + Client *c = NULL; + struct wlr_box box; + int type = -1; - if (!popup->base->initial_commit) - return; + if (!popup->base->initial_commit) + return; - type = toplevel_from_wlr_surface(popup->base->surface, &c, &l); - if (!popup->parent || type < 0) - return; - popup->base->surface->data = - wlr_scene_xdg_surface_create(popup->parent->data, popup->base); - if ((l && !l->mon) || (c && !c->mon)) - return; - box = type == LayerShell ? l->mon->m : c->mon->w; - box.x -= (type == LayerShell ? l->geom.x : c->geom.x); - box.y -= (type == LayerShell ? l->geom.y : c->geom.y); - wlr_xdg_popup_unconstrain_from_box(popup, &box); - wl_list_remove(&listener->link); - free(listener); + type = toplevel_from_wlr_surface(popup->base->surface, &c, &l); + if (!popup->parent || type < 0) + return; + popup->base->surface->data = + wlr_scene_xdg_surface_create(popup->parent->data, popup->base); + if ((l && !l->mon) || (c && !c->mon)) + return; + box = type == LayerShell ? l->mon->m : c->mon->w; + box.x -= (type == LayerShell ? l->geom.x : c->geom.x); + box.y -= (type == LayerShell ? l->geom.y : c->geom.y); + wlr_xdg_popup_unconstrain_from_box(popup, &box); + wl_list_remove(&listener->link); + free(listener); } void createdecoration(struct wl_listener *listener, void *data) { - struct wlr_xdg_toplevel_decoration_v1 *deco = data; - Client *c = deco->toplevel->base->data; - c->decoration = deco; + struct wlr_xdg_toplevel_decoration_v1 *deco = data; + Client *c = deco->toplevel->base->data; + c->decoration = deco; - LISTEN(&deco->events.request_mode, &c->set_decoration_mode, - requestdecorationmode); - LISTEN(&deco->events.destroy, &c->destroy_decoration, destroydecoration); + LISTEN(&deco->events.request_mode, &c->set_decoration_mode, + requestdecorationmode); + LISTEN(&deco->events.destroy, &c->destroy_decoration, destroydecoration); - requestdecorationmode(&c->set_decoration_mode, deco); + requestdecorationmode(&c->set_decoration_mode, deco); } void createidleinhibitor(struct wl_listener *listener, void *data) { - struct wlr_idle_inhibitor_v1 *idle_inhibitor = data; - LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor); + struct wlr_idle_inhibitor_v1 *idle_inhibitor = data; + LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor); - checkidleinhibitor(NULL); + checkidleinhibitor(NULL); } void createkeyboard(struct wlr_keyboard *keyboard) { - /* Set the keymap to match the group keymap */ - wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap); + /* Set the keymap to match the group keymap */ + wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap); - wlr_keyboard_notify_modifiers(keyboard, 0, 0, locked_mods, 0); + wlr_keyboard_notify_modifiers(keyboard, 0, 0, locked_mods, 0); - /* Add the new keyboard to the group */ - wlr_keyboard_group_add_keyboard(kb_group->wlr_group, keyboard); + /* Add the new keyboard to the group */ + wlr_keyboard_group_add_keyboard(kb_group->wlr_group, keyboard); } KeyboardGroup *createkeyboardgroup(void) { - KeyboardGroup *group = ecalloc(1, sizeof(*group)); - struct xkb_context *context; - struct xkb_keymap *keymap; + KeyboardGroup *group = ecalloc(1, sizeof(*group)); + struct xkb_context *context; + struct xkb_keymap *keymap; - group->wlr_group = wlr_keyboard_group_create(); - group->wlr_group->data = group; + group->wlr_group = wlr_keyboard_group_create(); + group->wlr_group->data = group; - /* Prepare an XKB keymap and assign it to the keyboard group. */ - context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules, - XKB_KEYMAP_COMPILE_NO_FLAGS))) - die("failed to compile keymap"); + /* Prepare an XKB keymap and assign it to the keyboard group. */ + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules, + XKB_KEYMAP_COMPILE_NO_FLAGS))) + die("failed to compile keymap"); - wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap); + wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap); - if (numlockon) { - xkb_mod_index_t mod_index = - xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM); - if (mod_index != XKB_MOD_INVALID) - locked_mods |= (uint32_t)1 << mod_index; - } + if (numlockon) { + xkb_mod_index_t mod_index = + xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM); + if (mod_index != XKB_MOD_INVALID) + locked_mods |= (uint32_t)1 << mod_index; + } - if (capslock) { - xkb_mod_index_t mod_index = - xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS); - if (mod_index != XKB_MOD_INVALID) - locked_mods |= (uint32_t)1 << mod_index; - } + if (capslock) { + xkb_mod_index_t mod_index = + xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS); + if (mod_index != XKB_MOD_INVALID) + locked_mods |= (uint32_t)1 << mod_index; + } - if (locked_mods) - wlr_keyboard_notify_modifiers(&group->wlr_group->keyboard, 0, 0, - locked_mods, 0); + if (locked_mods) + wlr_keyboard_notify_modifiers(&group->wlr_group->keyboard, 0, 0, + locked_mods, 0); - xkb_keymap_unref(keymap); - xkb_context_unref(context); + xkb_keymap_unref(keymap); + xkb_context_unref(context); - wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard, repeat_rate, - repeat_delay); + wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard, repeat_rate, + repeat_delay); - /* Set up listeners for keyboard events */ - LISTEN(&group->wlr_group->keyboard.events.key, &group->key, keypress); - LISTEN(&group->wlr_group->keyboard.events.modifiers, &group->modifiers, - keypressmod); + /* Set up listeners for keyboard events */ + LISTEN(&group->wlr_group->keyboard.events.key, &group->key, keypress); + LISTEN(&group->wlr_group->keyboard.events.modifiers, &group->modifiers, + keypressmod); - group->key_repeat_source = - wl_event_loop_add_timer(event_loop, keyrepeat, group); + group->key_repeat_source = + wl_event_loop_add_timer(event_loop, keyrepeat, group); - /* A seat can only have one keyboard, but this is a limitation of the - * Wayland protocol - not wlroots. We assign all connected keyboards to the - * same wlr_keyboard_group, which provides a single wlr_keyboard interface for - * all of them. Set this combined wlr_keyboard as the seat keyboard. - */ - wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); - return group; + /* A seat can only have one keyboard, but this is a limitation of the + * Wayland protocol - not wlroots. We assign all connected keyboards to the + * same wlr_keyboard_group, which provides a single wlr_keyboard interface + * for all of them. Set this combined wlr_keyboard as the seat keyboard. + */ + wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); + return group; } void createlayersurface(struct wl_listener *listener, void *data) { - struct wlr_layer_surface_v1 *layer_surface = data; - LayerSurface *l; - struct wlr_surface *surface = layer_surface->surface; - struct wlr_scene_tree *scene_layer = - layers[layermap[layer_surface->pending.layer]]; + struct wlr_layer_surface_v1 *layer_surface = data; + LayerSurface *l; + struct wlr_surface *surface = layer_surface->surface; + struct wlr_scene_tree *scene_layer = + layers[layermap[layer_surface->pending.layer]]; - if (!layer_surface->output && - !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) { - wlr_layer_surface_v1_destroy(layer_surface); - return; - } + if (!layer_surface->output && + !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) { + wlr_layer_surface_v1_destroy(layer_surface); + return; + } - l = layer_surface->data = ecalloc(1, sizeof(*l)); - l->type = LayerShell; - LISTEN(&surface->events.commit, &l->surface_commit, commitlayersurfacenotify); - LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify); - LISTEN(&layer_surface->events.destroy, &l->destroy, - destroylayersurfacenotify); + l = layer_surface->data = ecalloc(1, sizeof(*l)); + l->type = LayerShell; + LISTEN(&surface->events.commit, &l->surface_commit, + commitlayersurfacenotify); + LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify); + LISTEN(&layer_surface->events.destroy, &l->destroy, + destroylayersurfacenotify); - l->layer_surface = layer_surface; - l->mon = layer_surface->output->data; - l->scene_layer = - wlr_scene_layer_surface_v1_create(scene_layer, layer_surface); - l->scene = l->scene_layer->tree; - l->popups = surface->data = wlr_scene_tree_create( - layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP - ? layers[LyrTop] - : scene_layer); - l->scene->node.data = l->popups->node.data = l; + l->layer_surface = layer_surface; + l->mon = layer_surface->output->data; + l->scene_layer = + wlr_scene_layer_surface_v1_create(scene_layer, layer_surface); + l->scene = l->scene_layer->tree; + l->popups = surface->data = wlr_scene_tree_create( + layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP + ? layers[LyrTop] + : scene_layer); + l->scene->node.data = l->popups->node.data = l; - wl_list_insert(&l->mon->layers[layer_surface->pending.layer], &l->link); - wlr_surface_send_enter(surface, layer_surface->output); + wl_list_insert(&l->mon->layers[layer_surface->pending.layer], &l->link); + wlr_surface_send_enter(surface, layer_surface->output); } void createlocksurface(struct wl_listener *listener, void *data) { - SessionLock *lock = wl_container_of(listener, lock, new_surface); - struct wlr_session_lock_surface_v1 *lock_surface = data; - Monitor *m = lock_surface->output->data; - struct wlr_scene_tree *scene_tree = lock_surface->surface->data = - wlr_scene_subsurface_tree_create(lock->scene, lock_surface->surface); - m->lock_surface = lock_surface; + SessionLock *lock = wl_container_of(listener, lock, new_surface); + struct wlr_session_lock_surface_v1 *lock_surface = data; + Monitor *m = lock_surface->output->data; + struct wlr_scene_tree *scene_tree = lock_surface->surface->data = + wlr_scene_subsurface_tree_create(lock->scene, lock_surface->surface); + m->lock_surface = lock_surface; - wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); - wlr_session_lock_surface_v1_configure(lock_surface, m->m.width, m->m.height); + wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); + wlr_session_lock_surface_v1_configure(lock_surface, m->m.width, + m->m.height); - LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface, - destroylocksurface); + LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface, + destroylocksurface); - if (m == selmon) - client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat)); + if (m == selmon) + client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat)); } void createmon(struct wl_listener *listener, void *data) { - /* This event is raised by the backend when a new output (aka a display or - * monitor) becomes available. */ - struct wlr_output *wlr_output = data; - const ConfigMonitorRule *r; - size_t i; - int ji, jk; - struct wlr_output_state state; - Monitor *m; + /* This event is raised by the backend when a new output (aka a display or + * monitor) becomes available. */ + struct wlr_output *wlr_output = data; + const ConfigMonitorRule *r; + size_t i; + int ji, jk; + struct wlr_output_state state; + Monitor *m; - if (!wlr_output_init_render(wlr_output, alloc, drw)) - return; + if (!wlr_output_init_render(wlr_output, alloc, drw)) + return; - m = wlr_output->data = ecalloc(1, sizeof(*m)); - m->wlr_output = wlr_output; + m = wlr_output->data = ecalloc(1, sizeof(*m)); + m->wlr_output = wlr_output; - wl_list_init(&m->dwl_ipc_outputs); + wl_list_init(&m->dwl_ipc_outputs); - for (i = 0; i < LENGTH(m->layers); i++) - wl_list_init(&m->layers[i]); + for (i = 0; i < LENGTH(m->layers); i++) + wl_list_init(&m->layers[i]); - wlr_output_state_init(&state); - /* Initialize monitor state using configured rules */ - m->gappih = gappih; - m->gappiv = gappiv; - m->gappoh = gappoh; - m->gappov = gappov; - m->isoverview = 0; - m->sel = NULL; - m->is_in_hotarea = 0; - m->tagset[0] = m->tagset[1] = 1; - float scale = 1; - m->mfact = default_mfact; - m->nmaster = default_nmaster; - enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL; - wlr_output_state_set_scale(&state, scale); - wlr_output_state_set_transform(&state, rr); + wlr_output_state_init(&state); + /* Initialize monitor state using configured rules */ + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; + m->isoverview = 0; + m->sel = NULL; + m->is_in_hotarea = 0; + m->tagset[0] = m->tagset[1] = 1; + float scale = 1; + m->mfact = default_mfact; + m->nmaster = default_nmaster; + enum wl_output_transform rr = WL_OUTPUT_TRANSFORM_NORMAL; + wlr_output_state_set_scale(&state, scale); + wlr_output_state_set_transform(&state, rr); - m->lt = &layouts[0]; - for (ji = 0; ji < config.monitor_rules_count; ji++) { - if (config.monitor_rules_count < 1) - break; + m->lt = &layouts[0]; + for (ji = 0; ji < config.monitor_rules_count; ji++) { + if (config.monitor_rules_count < 1) + break; - r = &config.monitor_rules[ji]; - if (!r->name || regex_match(r->name, wlr_output->name)) { - m->mfact = r->mfact; - m->nmaster = r->nmaster; - m->m.x = r->x; - m->m.y = r->y; - if (r->layout) { - for (jk = 0; jk < LENGTH(layouts); jk++) { - if (strcmp(layouts[jk].name, r->layout) == 0) { - m->lt = &layouts[jk]; - } - } - } - scale = r->scale; - rr = r->rr; - wlr_output_state_set_scale(&state, r->scale); - wlr_output_state_set_transform(&state, r->rr); - break; - } - } + r = &config.monitor_rules[ji]; + if (!r->name || regex_match(r->name, wlr_output->name)) { + m->mfact = r->mfact; + m->nmaster = r->nmaster; + m->m.x = r->x; + m->m.y = r->y; + if (r->layout) { + for (jk = 0; jk < LENGTH(layouts); jk++) { + if (strcmp(layouts[jk].name, r->layout) == 0) { + m->lt = &layouts[jk]; + } + } + } + scale = r->scale; + rr = r->rr; + wlr_output_state_set_scale(&state, r->scale); + wlr_output_state_set_transform(&state, r->rr); + break; + } + } - /* The mode is a tuple of (width, height, refresh rate), and each - * monitor supports only a specific set of modes. We just pick the - * monitor's preferred mode; a more sophisticated compositor would let - * the user configure it. */ - wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output)); + /* The mode is a tuple of (width, height, refresh rate), and each + * monitor supports only a specific set of modes. We just pick the + * monitor's preferred mode; a more sophisticated compositor would let + * the user configure it. */ + wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output)); - /* Set up event listeners */ - LISTEN(&wlr_output->events.frame, &m->frame, rendermon); - LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); - LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate); + /* Set up event listeners */ + LISTEN(&wlr_output->events.frame, &m->frame, rendermon); + LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon); + LISTEN(&wlr_output->events.request_state, &m->request_state, + requestmonstate); - wlr_output_state_set_enabled(&state, 1); - wlr_output_commit_state(wlr_output, &state); - wlr_output_state_finish(&state); + wlr_output_state_set_enabled(&state, 1); + wlr_output_commit_state(wlr_output, &state); + wlr_output_state_finish(&state); - wl_list_insert(&mons, &m->link); - m->pertag = calloc(1, sizeof(Pertag)); - m->pertag->curtag = m->pertag->prevtag = 1; + wl_list_insert(&mons, &m->link); + m->pertag = calloc(1, sizeof(Pertag)); + m->pertag->curtag = m->pertag->prevtag = 1; - for (i = 0; i <= LENGTH(tags); i++) { - m->pertag->nmasters[i] = m->nmaster; - m->pertag->mfacts[i] = m->mfact; - m->pertag->smfacts[i] = default_smfact; - m->pertag->ltidxs[i] = m->lt; + for (i = 0; i <= LENGTH(tags); i++) { + m->pertag->nmasters[i] = m->nmaster; + m->pertag->mfacts[i] = m->mfact; + m->pertag->smfacts[i] = default_smfact; + m->pertag->ltidxs[i] = m->lt; - if (i > 0 && config.tag_rules && strlen(config.tag_rules[i - 1].layout_name) > 0) { - for (jk = 0; jk < LENGTH(layouts); jk++) { - if (strcmp(layouts[jk].name, config.tag_rules[i - 1].layout_name) == - 0) { - m->pertag->ltidxs[i] = &layouts[jk]; - } - } - } - } + if (i > 0 && config.tag_rules && + strlen(config.tag_rules[i - 1].layout_name) > 0) { + for (jk = 0; jk < LENGTH(layouts); jk++) { + if (strcmp(layouts[jk].name, + config.tag_rules[i - 1].layout_name) == 0) { + m->pertag->ltidxs[i] = &layouts[jk]; + } + } + } + } - printstatus(); + printstatus(); - /* The xdg-protocol specifies: - * - * If the fullscreened surface is not opaque, the compositor must make - * sure that other screen content not part of the same surface tree (made - * up of subsurfaces, popups or similarly coupled surfaces) are not - * visible below the fullscreened surface. - * - */ - /* updatemons() will resize and set correct position */ - // m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, - // fullscreen_bg); wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0); + /* The xdg-protocol specifies: + * + * If the fullscreened surface is not opaque, the compositor must make + * sure that other screen content not part of the same surface tree (made + * up of subsurfaces, popups or similarly coupled surfaces) are not + * visible below the fullscreened surface. + * + */ + /* updatemons() will resize and set correct position */ + // m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, + // fullscreen_bg); wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0); - /* Adds this to the output layout in the order it was configured. - * - * The output layout utility automatically adds a wl_output global to the - * display, which Wayland clients can see to find out information about the - * output (such as DPI, scale factor, manufacturer, etc). - */ - m->scene_output = wlr_scene_output_create(scene, wlr_output); - if (m->m.x == -1 && m->m.y == -1) - wlr_output_layout_add_auto(output_layout, wlr_output); - else - wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y); + /* Adds this to the output layout in the order it was configured. + * + * The output layout utility automatically adds a wl_output global to the + * display, which Wayland clients can see to find out information about the + * output (such as DPI, scale factor, manufacturer, etc). + */ + m->scene_output = wlr_scene_output_create(scene, wlr_output); + if (m->m.x == -1 && m->m.y == -1) + wlr_output_layout_add_auto(output_layout, wlr_output); + else + wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y); } void // fix for 0.5 createnotify(struct wl_listener *listener, void *data) { - /* This event is raised when wlr_xdg_shell receives a new xdg surface from a - * client, either a toplevel (application window) or popup, - * or when wlr_layer_shell receives a new popup from a layer. - * If you want to do something tricky with popups you should check if - * its parent is wlr_xdg_shell or wlr_layer_shell */ - struct wlr_xdg_toplevel *toplevel = data; - Client *c = NULL; + /* This event is raised when wlr_xdg_shell receives a new xdg surface from a + * client, either a toplevel (application window) or popup, + * or when wlr_layer_shell receives a new popup from a layer. + * If you want to do something tricky with popups you should check if + * its parent is wlr_xdg_shell or wlr_layer_shell */ + struct wlr_xdg_toplevel *toplevel = data; + Client *c = NULL; - /* Allocate a Client for this surface */ - c = toplevel->base->data = ecalloc(1, sizeof(*c)); - c->surface.xdg = toplevel->base; - c->bw = borderpx; + /* Allocate a Client for this surface */ + c = toplevel->base->data = ecalloc(1, sizeof(*c)); + c->surface.xdg = toplevel->base; + c->bw = borderpx; - LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify); - LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify); - LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify); - LISTEN(&toplevel->events.destroy, &c->destroy, destroynotify); - LISTEN(&toplevel->events.request_fullscreen, &c->fullscreen, - fullscreennotify); - LISTEN(&toplevel->events.request_maximize, &c->maximize, maximizenotify); - LISTEN(&toplevel->events.request_minimize, &c->minimize, minimizenotify); - LISTEN(&toplevel->events.set_title, &c->set_title, updatetitle); + LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify); + LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify); + LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify); + LISTEN(&toplevel->events.destroy, &c->destroy, destroynotify); + LISTEN(&toplevel->events.request_fullscreen, &c->fullscreen, + fullscreennotify); + LISTEN(&toplevel->events.request_maximize, &c->maximize, maximizenotify); + LISTEN(&toplevel->events.request_minimize, &c->minimize, minimizenotify); + LISTEN(&toplevel->events.set_title, &c->set_title, updatetitle); } void createpointer(struct wlr_pointer *pointer) { - struct libinput_device *device; - if (wlr_input_device_is_libinput(&pointer->base) && - (device = wlr_libinput_get_device_handle(&pointer->base))) { + struct libinput_device *device; + if (wlr_input_device_is_libinput(&pointer->base) && + (device = wlr_libinput_get_device_handle(&pointer->base))) { - if (libinput_device_config_tap_get_finger_count(device)) { - libinput_device_config_tap_set_enabled(device, tap_to_click); - libinput_device_config_tap_set_drag_enabled(device, tap_and_drag); - libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock); - libinput_device_config_tap_set_button_map(device, button_map); - libinput_device_config_scroll_set_natural_scroll_enabled( - device, trackpad_natural_scrolling); - } else { - libinput_device_config_scroll_set_natural_scroll_enabled( - device, mouse_natural_scrolling); - } + if (libinput_device_config_tap_get_finger_count(device)) { + libinput_device_config_tap_set_enabled(device, tap_to_click); + libinput_device_config_tap_set_drag_enabled(device, tap_and_drag); + libinput_device_config_tap_set_drag_lock_enabled(device, drag_lock); + libinput_device_config_tap_set_button_map(device, button_map); + libinput_device_config_scroll_set_natural_scroll_enabled( + device, trackpad_natural_scrolling); + } else { + libinput_device_config_scroll_set_natural_scroll_enabled( + device, mouse_natural_scrolling); + } - if (libinput_device_config_dwt_is_available(device)) - libinput_device_config_dwt_set_enabled(device, disable_while_typing); + if (libinput_device_config_dwt_is_available(device)) + libinput_device_config_dwt_set_enabled(device, + disable_while_typing); - if (libinput_device_config_left_handed_is_available(device)) - libinput_device_config_left_handed_set(device, left_handed); + if (libinput_device_config_left_handed_is_available(device)) + libinput_device_config_left_handed_set(device, left_handed); - if (libinput_device_config_middle_emulation_is_available(device)) - libinput_device_config_middle_emulation_set_enabled( - device, middle_button_emulation); + if (libinput_device_config_middle_emulation_is_available(device)) + libinput_device_config_middle_emulation_set_enabled( + device, middle_button_emulation); - if (libinput_device_config_scroll_get_methods(device) != - LIBINPUT_CONFIG_SCROLL_NO_SCROLL) - libinput_device_config_scroll_set_method(device, scroll_method); + if (libinput_device_config_scroll_get_methods(device) != + LIBINPUT_CONFIG_SCROLL_NO_SCROLL) + libinput_device_config_scroll_set_method(device, scroll_method); - if (libinput_device_config_click_get_methods(device) != - LIBINPUT_CONFIG_CLICK_METHOD_NONE) - libinput_device_config_click_set_method(device, click_method); + if (libinput_device_config_click_get_methods(device) != + LIBINPUT_CONFIG_CLICK_METHOD_NONE) + libinput_device_config_click_set_method(device, click_method); - if (libinput_device_config_send_events_get_modes(device)) - libinput_device_config_send_events_set_mode(device, send_events_mode); + if (libinput_device_config_send_events_get_modes(device)) + libinput_device_config_send_events_set_mode(device, + send_events_mode); - if (libinput_device_config_accel_is_available(device)) { - libinput_device_config_accel_set_profile(device, accel_profile); - libinput_device_config_accel_set_speed(device, accel_speed); - } - } + if (libinput_device_config_accel_is_available(device)) { + libinput_device_config_accel_set_profile(device, accel_profile); + libinput_device_config_accel_set_speed(device, accel_speed); + } + } - wlr_cursor_attach_input_device(cursor, &pointer->base); + wlr_cursor_attach_input_device(cursor, &pointer->base); } void createpointerconstraint(struct wl_listener *listener, void *data) { - PointerConstraint *pointer_constraint = - ecalloc(1, sizeof(*pointer_constraint)); - pointer_constraint->constraint = data; - LISTEN(&pointer_constraint->constraint->events.destroy, - &pointer_constraint->destroy, destroypointerconstraint); + PointerConstraint *pointer_constraint = + ecalloc(1, sizeof(*pointer_constraint)); + pointer_constraint->constraint = data; + LISTEN(&pointer_constraint->constraint->events.destroy, + &pointer_constraint->destroy, destroypointerconstraint); } void createpopup(struct wl_listener *listener, void *data) { - /* This event is raised when a client (either xdg-shell or layer-shell) - * creates a new popup. */ - struct wlr_xdg_popup *popup = data; - LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup); + /* This event is raised when a client (either xdg-shell or layer-shell) + * creates a new popup. */ + struct wlr_xdg_popup *popup = data; + LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup); } void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) { - if (active_constraint == constraint) - return; + if (active_constraint == constraint) + return; - if (active_constraint) - wlr_pointer_constraint_v1_send_deactivated(active_constraint); + if (active_constraint) + wlr_pointer_constraint_v1_send_deactivated(active_constraint); - active_constraint = constraint; - wlr_pointer_constraint_v1_send_activated(constraint); + active_constraint = constraint; + wlr_pointer_constraint_v1_send_activated(constraint); } void cursorframe(struct wl_listener *listener, void *data) { - /* This event is forwarded by the cursor when a pointer emits an frame - * event. Frame events are sent after regular pointer events to group - * multiple events together. For instance, two axis events may happen at the - * same time, in which case a frame event won't be sent in between. */ - /* Notify the client with pointer focus of the frame event. */ - wlr_seat_pointer_notify_frame(seat); + /* This event is forwarded by the cursor when a pointer emits an frame + * event. Frame events are sent after regular pointer events to group + * multiple events together. For instance, two axis events may happen at the + * same time, in which case a frame event won't be sent in between. */ + /* Notify the client with pointer focus of the frame event. */ + wlr_seat_pointer_notify_frame(seat); } void cursorwarptohint(void) { - Client *c = NULL; - double sx = active_constraint->current.cursor_hint.x; - double sy = active_constraint->current.cursor_hint.y; + Client *c = NULL; + double sx = active_constraint->current.cursor_hint.x; + double sy = active_constraint->current.cursor_hint.y; - toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); - if (c && active_constraint->current.cursor_hint.enabled) { - wlr_cursor_warp(cursor, NULL, sx + c->geom.x + c->bw, - sy + c->geom.y + c->bw); - wlr_seat_pointer_warp(active_constraint->seat, sx, sy); - } + toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); + if (c && active_constraint->current.cursor_hint.enabled) { + wlr_cursor_warp(cursor, NULL, sx + c->geom.x + c->bw, + sy + c->geom.y + c->bw); + wlr_seat_pointer_warp(active_constraint->seat, sx, sy); + } } void defaultgaps(const Arg *arg) { setgaps(gappoh, gappov, gappih, gappiv); } void destroydragicon(struct wl_listener *listener, void *data) { - /* Focus enter isn't sent during drag, so refocus the focused node. */ - focusclient(focustop(selmon), 1); - motionnotify(0, NULL, 0, 0, 0, 0); - wl_list_remove(&listener->link); - free(listener); + /* Focus enter isn't sent during drag, so refocus the focused node. */ + focusclient(focustop(selmon), 1); + motionnotify(0, NULL, 0, 0, 0, 0); + wl_list_remove(&listener->link); + free(listener); } void destroyidleinhibitor(struct wl_listener *listener, void *data) { - /* `data` is the wlr_surface of the idle inhibitor being destroyed, - * at this point the idle inhibitor is still in the list of the manager */ - checkidleinhibitor(wlr_surface_get_root_surface(data)); - wl_list_remove(&listener->link); - free(listener); + /* `data` is the wlr_surface of the idle inhibitor being destroyed, + * at this point the idle inhibitor is still in the list of the manager */ + checkidleinhibitor(wlr_surface_get_root_surface(data)); + wl_list_remove(&listener->link); + free(listener); } void destroylayersurfacenotify(struct wl_listener *listener, void *data) { - LayerSurface *l = wl_container_of(listener, l, destroy); + LayerSurface *l = wl_container_of(listener, l, destroy); - wl_list_remove(&l->link); - wl_list_remove(&l->destroy.link); - wl_list_remove(&l->unmap.link); - wl_list_remove(&l->surface_commit.link); - wlr_scene_node_destroy(&l->scene->node); - wlr_scene_node_destroy(&l->popups->node); - free(l); + wl_list_remove(&l->link); + wl_list_remove(&l->destroy.link); + wl_list_remove(&l->unmap.link); + wl_list_remove(&l->surface_commit.link); + wlr_scene_node_destroy(&l->scene->node); + wlr_scene_node_destroy(&l->popups->node); + free(l); } void destroylock(SessionLock *lock, int unlock) { - wlr_seat_keyboard_notify_clear_focus(seat); - if ((locked = !unlock)) - goto destroy; + wlr_seat_keyboard_notify_clear_focus(seat); + if ((locked = !unlock)) + goto destroy; - wlr_scene_node_set_enabled(&locked_bg->node, false); + wlr_scene_node_set_enabled(&locked_bg->node, false); - focusclient(focustop(selmon), 0); - motionnotify(0, NULL, 0, 0, 0, 0); + focusclient(focustop(selmon), 0); + motionnotify(0, NULL, 0, 0, 0, 0); destroy: - wl_list_remove(&lock->new_surface.link); - wl_list_remove(&lock->unlock.link); - wl_list_remove(&lock->destroy.link); + wl_list_remove(&lock->new_surface.link); + wl_list_remove(&lock->unlock.link); + wl_list_remove(&lock->destroy.link); - wlr_scene_node_destroy(&lock->scene->node); - cur_lock = NULL; - free(lock); + wlr_scene_node_destroy(&lock->scene->node); + cur_lock = NULL; + free(lock); } void destroylocksurface(struct wl_listener *listener, void *data) { - Monitor *m = wl_container_of(listener, m, destroy_lock_surface); - struct wlr_session_lock_surface_v1 *surface, *lock_surface = m->lock_surface; + Monitor *m = wl_container_of(listener, m, destroy_lock_surface); + struct wlr_session_lock_surface_v1 *surface, + *lock_surface = m->lock_surface; - m->lock_surface = NULL; - wl_list_remove(&m->destroy_lock_surface.link); + m->lock_surface = NULL; + wl_list_remove(&m->destroy_lock_surface.link); - if (lock_surface->surface != seat->keyboard_state.focused_surface) - return; + if (lock_surface->surface != seat->keyboard_state.focused_surface) + return; - if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) { - surface = wl_container_of(cur_lock->surfaces.next, surface, link); - client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat)); - } else if (!locked) { - focusclient(focustop(selmon), 1); - } else { - wlr_seat_keyboard_clear_focus(seat); - } + if (locked && cur_lock && !wl_list_empty(&cur_lock->surfaces)) { + surface = wl_container_of(cur_lock->surfaces.next, surface, link); + client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat)); + } else if (!locked) { + focusclient(focustop(selmon), 1); + } else { + wlr_seat_keyboard_clear_focus(seat); + } } void // 0.7 custom destroynotify(struct wl_listener *listener, void *data) { - /* Called when the xdg_toplevel is destroyed. */ - Client *c = wl_container_of(listener, c, destroy); - wl_list_remove(&c->destroy.link); - wl_list_remove(&c->set_title.link); - wl_list_remove(&c->fullscreen.link); - wl_list_remove(&c->maximize.link); - wl_list_remove(&c->minimize.link); + /* Called when the xdg_toplevel is destroyed. */ + Client *c = wl_container_of(listener, c, destroy); + wl_list_remove(&c->destroy.link); + wl_list_remove(&c->set_title.link); + wl_list_remove(&c->fullscreen.link); + wl_list_remove(&c->maximize.link); + wl_list_remove(&c->minimize.link); #ifdef XWAYLAND - if (c->type != XDGShell) { - wl_list_remove(&c->activate.link); - wl_list_remove(&c->associate.link); - wl_list_remove(&c->configure.link); - wl_list_remove(&c->dissociate.link); - wl_list_remove(&c->set_hints.link); - } else + if (c->type != XDGShell) { + wl_list_remove(&c->activate.link); + wl_list_remove(&c->associate.link); + wl_list_remove(&c->configure.link); + wl_list_remove(&c->dissociate.link); + wl_list_remove(&c->set_hints.link); + } else #endif - { - wl_list_remove(&c->commit.link); - wl_list_remove(&c->map.link); - wl_list_remove(&c->unmap.link); - } - free(c); + { + wl_list_remove(&c->commit.link); + wl_list_remove(&c->map.link); + wl_list_remove(&c->unmap.link); + } + free(c); } void destroypointerconstraint(struct wl_listener *listener, void *data) { - PointerConstraint *pointer_constraint = - wl_container_of(listener, pointer_constraint, destroy); + PointerConstraint *pointer_constraint = + wl_container_of(listener, pointer_constraint, destroy); - if (active_constraint == pointer_constraint->constraint) { - cursorwarptohint(); - active_constraint = NULL; - } + if (active_constraint == pointer_constraint->constraint) { + cursorwarptohint(); + active_constraint = NULL; + } - wl_list_remove(&pointer_constraint->destroy.link); - free(pointer_constraint); + wl_list_remove(&pointer_constraint->destroy.link); + free(pointer_constraint); } void destroysessionlock(struct wl_listener *listener, void *data) { - SessionLock *lock = wl_container_of(listener, lock, destroy); - destroylock(lock, 0); + SessionLock *lock = wl_container_of(listener, lock, destroy); + destroylock(lock, 0); } void destroykeyboardgroup(struct wl_listener *listener, void *data) { - KeyboardGroup *group = wl_container_of(listener, group, destroy); - wl_event_source_remove(group->key_repeat_source); - wl_list_remove(&group->key.link); - wl_list_remove(&group->modifiers.link); - wl_list_remove(&group->destroy.link); - wlr_keyboard_group_destroy(group->wlr_group); - free(group); + KeyboardGroup *group = wl_container_of(listener, group, destroy); + wl_event_source_remove(group->key_repeat_source); + wl_list_remove(&group->key.link); + wl_list_remove(&group->modifiers.link); + wl_list_remove(&group->destroy.link); + wlr_keyboard_group_destroy(group->wlr_group); + free(group); } Monitor *dirtomon(enum wlr_direction dir) { - struct wlr_output *next; - if (!wlr_output_layout_get(output_layout, selmon->wlr_output)) - return selmon; - if ((next = wlr_output_layout_adjacent_output(output_layout, 1 << dir, - selmon->wlr_output, selmon->m.x, - selmon->m.y))) - return next->data; - if ((next = wlr_output_layout_farthest_output( - output_layout, dir ^ (WLR_DIRECTION_LEFT | WLR_DIRECTION_RIGHT), - selmon->wlr_output, selmon->m.x, selmon->m.y))) - return next->data; - return selmon; + struct wlr_output *next; + if (!wlr_output_layout_get(output_layout, selmon->wlr_output)) + return selmon; + if ((next = wlr_output_layout_adjacent_output(output_layout, 1 << dir, + selmon->wlr_output, + selmon->m.x, selmon->m.y))) + return next->data; + if ((next = wlr_output_layout_farthest_output( + output_layout, dir ^ (WLR_DIRECTION_LEFT | WLR_DIRECTION_RIGHT), + selmon->wlr_output, selmon->m.x, selmon->m.y))) + return next->data; + 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); + 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 (unsigned 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 */ + /* 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; - 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; + struct wl_resource *resource, uint32_t 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); + 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); + 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); + 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); + 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); + 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); - } + 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; + 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); + 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, - uint32_t and_tags, uint32_t xor_tags) { - DwlIpcOutput *ipc_output; - Monitor *monitor; - Client *selected_client; - unsigned int newtags = 0; + 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->mon; - 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; - if (selmon == monitor) - focusclient(focustop(monitor), 1); - arrange(selmon, false); - 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, - struct wl_resource *resource, uint32_t index) { - DwlIpcOutput *ipc_output; - Monitor *monitor; + struct wl_resource *resource, uint32_t index) { + DwlIpcOutput *ipc_output; + Monitor *monitor; - 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->mon; - if (index >= LENGTH(layouts)) - index = 0; + monitor = ipc_output->mon; + if (index >= LENGTH(layouts)) + index = 0; - monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; - arrange(monitor, false); - printstatus(); + 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, uint32_t tagmask, - uint32_t toggle_tagset) { - DwlIpcOutput *ipc_output; - Monitor *monitor; - unsigned int newtags = tagmask & TAGMASK; + 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->mon; + ipc_output = wl_resource_get_user_data(resource); + if (!ipc_output) + return; + monitor = ipc_output->mon; - view_in_mon(&(Arg){.ui = newtags}, true, monitor); + view_in_mon(&(Arg){.ui = newtags}, true, monitor); } void dwl_ipc_output_quit(struct wl_client *client, - struct wl_resource *resource) { - quit(&(Arg){0}); + 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) { + 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 (*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); + 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; + struct wlr_surface *old_keyboard_focus_surface = + seat->keyboard_state.focused_surface; - if (locked) - return; + if (locked) + return; - if (c && c->iskilling) - return; + if (c && c->iskilling) + return; - if (c && !client_surface(c)->mapped) - return; + if (c && !client_surface(c)->mapped) + return; - if (c && c->animation.tagouting && !c->animation.tagouting) - return; + if (c && c->animation.tagouting && !c->animation.tagouting) + return; - if (c && client_should_ignore_focus(c)) { - return; - } + if (c && client_should_ignore_focus(c)) { + return; + } - /* Raise client in stacking order if requested */ - if (c && lift) - wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 + /* 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 && selmon && - selmon->sel) - return; + if (c && client_surface(c) == old_keyboard_focus_surface && selmon && + selmon->sel) + return; - if (selmon && selmon->sel && selmon->sel != c && - selmon->sel->foreign_toplevel) { - wlr_foreign_toplevel_handle_v1_set_activated(selmon->sel->foreign_toplevel, - false); - } + if (selmon && selmon->sel && selmon->sel != c && + selmon->sel->foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_set_activated( + selmon->sel->foreign_toplevel, false); + } - if (c && !c->iskilling && !client_is_unmanaged(c) && c->mon) { + if (c && !c->iskilling && !client_is_unmanaged(c) && c->mon) { - selmon = c->mon; - selmon->prevsel = selmon->sel; - selmon->sel = c; + selmon = c->mon; + selmon->prevsel = selmon->sel; + selmon->sel = c; - // decide whether need to re-arrange - if (c && selmon->prevsel && !selmon->prevsel->isfloating && - (selmon->prevsel->tags & selmon->tagset[selmon->seltags]) && - (c->tags & selmon->tagset[selmon->seltags]) && !c->isfloating && - !c->isfullscreen && - strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, - "scroller") == 0) { - arrange(selmon, false); - } else if (selmon->prevsel) { - selmon->prevsel = NULL; - } + // decide whether need to re-arrange + if (c && selmon->prevsel && !selmon->prevsel->isfloating && + (selmon->prevsel->tags & selmon->tagset[selmon->seltags]) && + (c->tags & selmon->tagset[selmon->seltags]) && !c->isfloating && + !c->isfullscreen && + strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") == 0) { + arrange(selmon, false); + } else if (selmon->prevsel) { + selmon->prevsel = NULL; + } - // change focus link position - wl_list_remove(&c->flink); - wl_list_insert(&fstack, &c->flink); + // change focus link position + wl_list_remove(&c->flink); + wl_list_insert(&fstack, &c->flink); - // change border color - c->isurgent = 0; - setborder_color(c); - } + // change border color + c->isurgent = 0; + setborder_color(c); + } - if (c && !c->iskilling && c->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); + if (c && !c->iskilling && c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); - /* Deactivate old client if focus is changing */ - 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. */ - Client *w = NULL; - LayerSurface *l = NULL; - int type = toplevel_from_wlr_surface(old_keyboard_focus_surface, &w, &l); - if (type == LayerShell && l->scene->node.enabled && - l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { - 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 */ - } else if (w && !client_is_unmanaged(w) && (!c || !client_wants_focus(c))) { - setborder_color(w); + /* Deactivate old client if focus is changing */ + 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. */ + Client *w = NULL; + LayerSurface *l = NULL; + int type = + toplevel_from_wlr_surface(old_keyboard_focus_surface, &w, &l); + if (type == LayerShell && l->scene->node.enabled && + l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { + 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 */ + } else if (w && !client_is_unmanaged(w) && + (!c || !client_wants_focus(c))) { + setborder_color(w); - client_activate_surface(old_keyboard_focus_surface, 0); - } - } - printstatus(); + client_activate_surface(old_keyboard_focus_surface, 0); + } + } + printstatus(); - if (!c) { - /* With no client, all we have left is to clear focus */ - if (selmon && selmon->sel) - selmon->sel = - NULL; // 这个很关键,因为很多地方用到当前窗口做计算,不重置成NULL就会到处有野指针 + if (!c) { + /* With no client, all we have left is to clear focus */ + if (selmon && selmon->sel) + selmon->sel = + NULL; // 这个很关键,因为很多地方用到当前窗口做计算,不重置成NULL就会到处有野指针 - // clear text input focus state - input_method_relay_set_focus(input_method_relay, NULL); - wlr_seat_keyboard_notify_clear_focus(seat); - return; - } + // clear text input focus state + input_method_relay_set_focus(input_method_relay, NULL); + wlr_seat_keyboard_notify_clear_focus(seat); + return; + } - /* Change cursor surface */ - motionnotify(0, NULL, 0, 0, 0, 0); + /* Change cursor surface */ + motionnotify(0, NULL, 0, 0, 0, 0); - /* Have a client, so focus its top-level wlr_surface */ - client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat)); + /* Have a client, so focus its top-level wlr_surface */ + client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat)); - // set text input focus - input_method_relay_set_focus(input_method_relay, client_surface(c)); - /* Activate the new client */ - client_activate_surface(client_surface(c), 1); + // set text input focus + input_method_relay_set_focus(input_method_relay, client_surface(c)); + /* Activate the new client */ + client_activate_surface(client_surface(c), 1); } void focusmon(const Arg *arg) { - Client *c; - int i = 0, nmons = wl_list_length(&mons); - if (nmons) { - do /* don't switch to disabled mons */ - selmon = dirtomon(arg->i); - while (!selmon->wlr_output->enabled && i++ < nmons); - } - warp_cursor_to_selmon(selmon); - c = focustop(selmon); - if (!c) - selmon->sel = NULL; - else - focusclient(c, 1); + Client *c; + int i = 0, nmons = wl_list_length(&mons); + if (nmons) { + do /* don't switch to disabled mons */ + selmon = dirtomon(arg->i); + while (!selmon->wlr_output->enabled && i++ < nmons); + } + warp_cursor_to_selmon(selmon); + c = focustop(selmon); + if (!c) + selmon->sel = NULL; + else + focusclient(c, 1); } void // 17 focusstack(const Arg *arg) { - /* Focus the next or previous client (in tiling order) on selmon */ - Client *c, *sel = focustop(selmon); - if (!sel || sel->isfullscreen) - return; - if (arg->i > 0) { - wl_list_for_each(c, &sel->link, link) { - if (&c->link == &clients || c->isunglobal) - continue; /* wrap past the sentinel node */ - if (VISIBLEON(c, selmon)) - break; /* found it */ - } - } else { - wl_list_for_each_reverse(c, &sel->link, link) { - if (&c->link == &clients) - continue; /* wrap past the sentinel node */ - if (VISIBLEON(c, selmon) || c->isunglobal) - break; /* found it */ - } - } - /* If only one client is visible on selmon, then c == sel */ - focusclient(c, 1); + /* Focus the next or previous client (in tiling order) on selmon */ + Client *c, *sel = focustop(selmon); + if (!sel || sel->isfullscreen) + return; + if (arg->i > 0) { + wl_list_for_each(c, &sel->link, link) { + if (&c->link == &clients || c->isunglobal) + continue; /* wrap past the sentinel node */ + if (VISIBLEON(c, selmon)) + break; /* found it */ + } + } else { + wl_list_for_each_reverse(c, &sel->link, link) { + if (&c->link == &clients) + continue; /* wrap past the sentinel node */ + if (VISIBLEON(c, selmon) || c->isunglobal) + break; /* found it */ + } + } + /* If only one client is visible on selmon, then c == sel */ + focusclient(c, 1); } /* We probably should change the name of this, it sounds like @@ -4019,1875 +4079,1897 @@ focusstack(const Arg *arg) { * only return that client */ Client * // 0.5 focustop(Monitor *m) { - Client *c; - wl_list_for_each(c, &fstack, flink) { - if (c->iskilling || c->isunglobal) - continue; - if (VISIBLEON(c, m)) - return c; - } - return NULL; + Client *c; + wl_list_for_each(c, &fstack, flink) { + if (c->iskilling || c->isunglobal) + continue; + if (VISIBLEON(c, m)) + return c; + } + return NULL; } void // 0.6 fullscreennotify(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, fullscreen); + Client *c = wl_container_of(listener, c, fullscreen); - if (!c || c->iskilling) - return; + if (!c || c->iskilling) + return; - setfullscreen(c, client_wants_fullscreen(c)); + setfullscreen(c, client_wants_fullscreen(c)); } void incnmaster(const Arg *arg) { - if (!arg || !selmon) - return; - selmon->pertag->nmasters[selmon->pertag->curtag] = - MAX(selmon->pertag->nmasters[selmon->pertag->curtag] + arg->i, 0); - arrange(selmon, false); + if (!arg || !selmon) + return; + selmon->pertag->nmasters[selmon->pertag->curtag] = + MAX(selmon->pertag->nmasters[selmon->pertag->curtag] + arg->i, 0); + arrange(selmon, false); } void incgaps(const Arg *arg) { - setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, - selmon->gappih + arg->i, selmon->gappiv + arg->i); + setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, + selmon->gappih + arg->i, selmon->gappiv + arg->i); } void incigaps(const Arg *arg) { - setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, - selmon->gappiv + arg->i); + setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, + selmon->gappiv + arg->i); } void incogaps(const Arg *arg) { - setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, selmon->gappih, - selmon->gappiv); + setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, selmon->gappih, + selmon->gappiv); } void incihgaps(const Arg *arg) { - setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, - selmon->gappiv); + setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, + selmon->gappiv); } void incivgaps(const Arg *arg) { - setgaps(selmon->gappoh, selmon->gappov, selmon->gappih, - selmon->gappiv + arg->i); + setgaps(selmon->gappoh, selmon->gappov, selmon->gappih, + selmon->gappiv + arg->i); } void incohgaps(const Arg *arg) { - setgaps(selmon->gappoh + arg->i, selmon->gappov, selmon->gappih, - selmon->gappiv); + setgaps(selmon->gappoh + arg->i, selmon->gappov, selmon->gappih, + selmon->gappiv); } void incovgaps(const Arg *arg) { - setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih, - selmon->gappiv); + setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih, + selmon->gappiv); } void requestmonstate(struct wl_listener *listener, void *data) { - struct wlr_output_event_request_state *event = data; - wlr_output_commit_state(event->output, event->state); - updatemons(NULL, NULL); + struct wlr_output_event_request_state *event = data; + wlr_output_commit_state(event->output, event->state); + updatemons(NULL, NULL); } void inputdevice(struct wl_listener *listener, void *data) { - /* This event is raised by the backend when a new input device becomes - * available. */ - struct wlr_input_device *device = data; - uint32_t caps; + /* This event is raised by the backend when a new input device becomes + * available. */ + struct wlr_input_device *device = data; + uint32_t caps; - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - createkeyboard(wlr_keyboard_from_input_device(device)); - break; - case WLR_INPUT_DEVICE_POINTER: - createpointer(wlr_pointer_from_input_device(device)); - break; - default: - /* TODO handle other input device types */ - break; - } + switch (device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + createkeyboard(wlr_keyboard_from_input_device(device)); + break; + case WLR_INPUT_DEVICE_POINTER: + createpointer(wlr_pointer_from_input_device(device)); + break; + default: + /* TODO handle other input device types */ + break; + } - /* We need to let the wlr_seat know what our capabilities are, which is - * communiciated to the client. In dwl we always have a cursor, even if - * there are no pointer devices, so we always include that capability. */ - /* TODO do we actually require a cursor? */ - caps = WL_SEAT_CAPABILITY_POINTER; - if (!wl_list_empty(&kb_group->wlr_group->devices)) - caps |= WL_SEAT_CAPABILITY_KEYBOARD; - wlr_seat_set_capabilities(seat, caps); + /* We need to let the wlr_seat know what our capabilities are, which is + * communiciated to the client. In dwl we always have a cursor, even if + * there are no pointer devices, so we always include that capability. */ + /* TODO do we actually require a cursor? */ + caps = WL_SEAT_CAPABILITY_POINTER; + if (!wl_list_empty(&kb_group->wlr_group->devices)) + caps |= WL_SEAT_CAPABILITY_KEYBOARD; + wlr_seat_set_capabilities(seat, caps); } int keyrepeat(void *data) { - KeyboardGroup *group = data; - int i; - if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0) - return 0; + KeyboardGroup *group = data; + int i; + if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0) + return 0; - wl_event_source_timer_update(group->key_repeat_source, - 1000 / - group->wlr_group->keyboard.repeat_info.rate); + wl_event_source_timer_update( + group->key_repeat_source, + 1000 / group->wlr_group->keyboard.repeat_info.rate); - for (i = 0; i < group->nsyms; i++) - keybinding(group->mods, group->keysyms[i]); + for (i = 0; i < group->nsyms; i++) + keybinding(group->mods, group->keysyms[i]); - return 0; + return 0; } int // 17 keybinding(uint32_t mods, xkb_keysym_t sym) { - /* - * Here we handle compositor keybindings. This is when the compositor is - * processing keys, rather than passing them on to the client for its own - * processing. - */ - int handled = 0; - const KeyBinding *k; - int ji; - 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) && - normalize_keysym(sym) == normalize_keysym(k->keysym) && k->func) { - k->func(&k->arg); - handled = 1; - } - } - return handled; + /* + * Here we handle compositor keybindings. This is when the compositor is + * processing keys, rather than passing them on to the client for its own + * processing. + */ + int handled = 0; + const KeyBinding *k; + int ji; + 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) && + normalize_keysym(sym) == normalize_keysym(k->keysym) && k->func) { + k->func(&k->arg); + handled = 1; + } + } + return handled; } bool keypressglobal(struct wlr_surface *last_surface, - struct wlr_keyboard *keyboard, - struct wlr_keyboard_key_event *event, uint32_t mods, - xkb_keysym_t keysym) { - Client *c = NULL, *lastc = focustop(selmon); - uint32_t keycodes[32] = {0}; - int reset = false; - const char *appid = NULL; - const char *title = NULL; - int ji; - const ConfigWinRule *r; + struct wlr_keyboard *keyboard, + struct wlr_keyboard_key_event *event, uint32_t mods, + xkb_keysym_t keysym) { + Client *c = NULL, *lastc = focustop(selmon); + uint32_t keycodes[32] = {0}; + int reset = false; + const char *appid = NULL; + const char *title = NULL; + int ji; + const ConfigWinRule *r; - for (ji = 0; ji < config.window_rules_count; ji++) { - if (config.window_rules_count < 1) - break; - r = &config.window_rules[ji]; + for (ji = 0; ji < config.window_rules_count; ji++) { + if (config.window_rules_count < 1) + break; + r = &config.window_rules[ji]; - if (!r->globalkeybinding.mod || !r->globalkeybinding.keysym) - continue; + if (!r->globalkeybinding.mod || !r->globalkeybinding.keysym) + continue; - /* match key only (case insensitive) ignoring mods */ - if (r->globalkeybinding.keysym == keysym && - r->globalkeybinding.mod == mods) { - wl_list_for_each(c, &clients, link) { - if (c && c != lastc) { - appid = client_get_appid(c); - title = client_get_title(c); + /* match key only (case insensitive) ignoring mods */ + if (r->globalkeybinding.keysym == keysym && + r->globalkeybinding.mod == mods) { + wl_list_for_each(c, &clients, link) { + if (c && c != lastc) { + appid = client_get_appid(c); + title = client_get_title(c); - if ((r->title && regex_match(r->title, title) && !r->id) || - (r->id && regex_match(r->id, appid) && !r->title) || - (r->id && regex_match(r->id, appid) && r->title && - regex_match(r->title, title))) { - reset = true; - wlr_seat_keyboard_enter(seat, client_surface(c), keycodes, 0, - &keyboard->modifiers); - wlr_seat_keyboard_send_key(seat, event->time_msec, event->keycode, - event->state); - goto done; - } - } - } - } - } + if ((r->title && regex_match(r->title, title) && !r->id) || + (r->id && regex_match(r->id, appid) && !r->title) || + (r->id && regex_match(r->id, appid) && r->title && + regex_match(r->title, title))) { + reset = true; + wlr_seat_keyboard_enter(seat, client_surface(c), + keycodes, 0, + &keyboard->modifiers); + wlr_seat_keyboard_send_key(seat, event->time_msec, + event->keycode, + event->state); + goto done; + } + } + } + } + } done: - if (reset) - wlr_seat_keyboard_enter(seat, last_surface, keycodes, 0, - &keyboard->modifiers); - return reset; + if (reset) + wlr_seat_keyboard_enter(seat, last_surface, keycodes, 0, + &keyboard->modifiers); + return reset; } void keypress(struct wl_listener *listener, void *data) { - int i; - /* This event is raised when a key is pressed or released. */ - KeyboardGroup *group = wl_container_of(listener, group, key); - struct wlr_keyboard_key_event *event = data; + int i; + /* This event is raised when a key is pressed or released. */ + KeyboardGroup *group = wl_container_of(listener, group, key); + struct wlr_keyboard_key_event *event = data; - struct wlr_surface *last_surface = seat->keyboard_state.focused_surface; - struct wlr_xdg_surface *xdg_surface = - last_surface ? wlr_xdg_surface_try_from_wlr_surface(last_surface) : NULL; - int pass = 0; - bool hit_global = false; + struct wlr_surface *last_surface = seat->keyboard_state.focused_surface; + struct wlr_xdg_surface *xdg_surface = + last_surface ? wlr_xdg_surface_try_from_wlr_surface(last_surface) + : NULL; + int pass = 0; + bool hit_global = false; #ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface = - last_surface ? wlr_xwayland_surface_try_from_wlr_surface(last_surface) - : NULL; + struct wlr_xwayland_surface *xsurface = + last_surface ? wlr_xwayland_surface_try_from_wlr_surface(last_surface) + : NULL; #endif - /* Translate libinput keycode -> xkbcommon */ - uint32_t keycode = event->keycode + 8; - /* Get a list of keysyms based on the keymap for this keyboard */ - const xkb_keysym_t *syms; - int nsyms = xkb_state_key_get_syms(group->wlr_group->keyboard.xkb_state, - keycode, &syms); + /* Translate libinput keycode -> xkbcommon */ + uint32_t keycode = event->keycode + 8; + /* Get a list of keysyms based on the keymap for this keyboard */ + const xkb_keysym_t *syms; + int nsyms = xkb_state_key_get_syms(group->wlr_group->keyboard.xkb_state, + keycode, &syms); - int handled = 0; - uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard); + int handled = 0; + uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + 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 && - (keycode == 133 || keycode == 37 || keycode == 64 || keycode == 50 || - keycode == 134 || keycode == 105 || keycode == 108 || keycode == 62) && - selmon && selmon->sel) { - if (selmon->isoverview && selmon->sel) { - toggleoverview(&(Arg){.i = -1}); - } - } + // ov tab mode detect moe key release + 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 && selmon->sel) { + if (selmon->isoverview && selmon->sel) { + toggleoverview(&(Arg){.i = -1}); + } + } - /* On _press_ if there is no active screen locker, - * attempt to process a compositor keybinding. */ - if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - for (i = 0; i < nsyms; i++) - handled = keybinding(mods, syms[i]) || handled; - } + /* On _press_ if there is no active screen locker, + * attempt to process a compositor keybinding. */ + if (!locked && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + for (i = 0; i < nsyms; i++) + handled = keybinding(mods, syms[i]) || handled; + } - if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) { - group->mods = mods; - group->keysyms = syms; - group->nsyms = nsyms; - wl_event_source_timer_update(group->key_repeat_source, - group->wlr_group->keyboard.repeat_info.delay); - } else { - group->nsyms = 0; - wl_event_source_timer_update(group->key_repeat_source, 0); - } + if (handled && group->wlr_group->keyboard.repeat_info.delay > 0) { + group->mods = mods; + group->keysyms = syms; + group->nsyms = nsyms; + wl_event_source_timer_update( + group->key_repeat_source, + group->wlr_group->keyboard.repeat_info.delay); + } else { + group->nsyms = 0; + wl_event_source_timer_update(group->key_repeat_source, 0); + } - if (handled) - return; + if (handled) + return; - /* don't pass when popup is focused - * this is better than having popups (like fuzzel or wmenu) closing while - * typing in a passed keybind */ - pass = (xdg_surface && xdg_surface->role != WLR_XDG_SURFACE_ROLE_POPUP) || - !last_surface + /* don't pass when popup is focused + * this is better than having popups (like fuzzel or wmenu) closing while + * typing in a passed keybind */ + pass = (xdg_surface && xdg_surface->role != WLR_XDG_SURFACE_ROLE_POPUP) || + !last_surface #ifdef XWAYLAND - || xsurface + || xsurface #endif - ; - /* passed keys don't get repeated */ - if (pass && syms) - hit_global = keypressglobal(last_surface, &group->wlr_group->keyboard, - event, mods, syms[0]); + ; + /* passed keys don't get repeated */ + if (pass && syms) + hit_global = keypressglobal(last_surface, &group->wlr_group->keyboard, + event, mods, syms[0]); - if (hit_global) { - return; - } - if (!input_method_keyboard_grab_forward_key(group, event)) { - wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); - /* Pass unhandled keycodes along to the client. */ - wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, - event->state); - } + if (hit_global) { + return; + } + if (!input_method_keyboard_grab_forward_key(group, event)) { + wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); + /* Pass unhandled keycodes along to the client. */ + wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, + event->state); + } } void keypressmod(struct wl_listener *listener, void *data) { - /* This event is raised when a modifier key, such as shift or alt, is - * pressed. We simply communicate this to the client. */ - KeyboardGroup *group = wl_container_of(listener, group, modifiers); + /* This event is raised when a modifier key, such as shift or alt, is + * pressed. We simply communicate this to the client. */ + KeyboardGroup *group = wl_container_of(listener, group, modifiers); - if (!input_method_keyboard_grab_forward_modifiers(group)) { - wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); - /* Send modifiers to the client. */ - wlr_seat_keyboard_notify_modifiers(seat, - &group->wlr_group->keyboard.modifiers); - } + if (!input_method_keyboard_grab_forward_modifiers(group)) { + wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard); + /* Send modifiers to the client. */ + wlr_seat_keyboard_notify_modifiers( + seat, &group->wlr_group->keyboard.modifiers); + } } static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly, - struct wlr_scene_tree *snapshot_tree) { - if (!node->enabled && node->type != WLR_SCENE_NODE_TREE) { - return true; - } + struct wlr_scene_tree *snapshot_tree) { + if (!node->enabled && node->type != WLR_SCENE_NODE_TREE) { + return true; + } - lx += node->x; - ly += node->y; + lx += node->x; + ly += node->y; - struct wlr_scene_node *snapshot_node = NULL; - switch (node->type) { - case WLR_SCENE_NODE_TREE:; - struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node); - struct wlr_scene_node *child; - wl_list_for_each(child, &scene_tree->children, link) { - scene_node_snapshot(child, lx, ly, snapshot_tree); - } - break; - case WLR_SCENE_NODE_RECT:; + struct wlr_scene_node *snapshot_node = NULL; + switch (node->type) { + case WLR_SCENE_NODE_TREE:; + struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node); + struct wlr_scene_node *child; + wl_list_for_each(child, &scene_tree->children, link) { + scene_node_snapshot(child, lx, ly, snapshot_tree); + } + break; + case WLR_SCENE_NODE_RECT:; - struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node); + struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node); - struct wlr_scene_rect *snapshot_rect = - wlr_scene_rect_create(snapshot_tree, scene_rect->width, - scene_rect->height, scene_rect->color); - snapshot_rect->node.data = scene_rect->node.data; - if (snapshot_rect == NULL) { - return false; - } - snapshot_node = &snapshot_rect->node; - break; - case WLR_SCENE_NODE_BUFFER:; + struct wlr_scene_rect *snapshot_rect = + wlr_scene_rect_create(snapshot_tree, scene_rect->width, + scene_rect->height, scene_rect->color); + snapshot_rect->node.data = scene_rect->node.data; + if (snapshot_rect == NULL) { + return false; + } + snapshot_node = &snapshot_rect->node; + break; + case WLR_SCENE_NODE_BUFFER:; - struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node); + struct wlr_scene_buffer *scene_buffer = + wlr_scene_buffer_from_node(node); - struct wlr_scene_buffer *snapshot_buffer = - wlr_scene_buffer_create(snapshot_tree, NULL); - if (snapshot_buffer == NULL) { - return false; - } - snapshot_node = &snapshot_buffer->node; - snapshot_buffer->node.data = scene_buffer->node.data; + struct wlr_scene_buffer *snapshot_buffer = + wlr_scene_buffer_create(snapshot_tree, NULL); + if (snapshot_buffer == NULL) { + return false; + } + snapshot_node = &snapshot_buffer->node; + snapshot_buffer->node.data = scene_buffer->node.data; - wlr_scene_buffer_set_dest_size(snapshot_buffer, scene_buffer->dst_width, - scene_buffer->dst_height); - wlr_scene_buffer_set_opaque_region(snapshot_buffer, - &scene_buffer->opaque_region); - wlr_scene_buffer_set_source_box(snapshot_buffer, &scene_buffer->src_box); - wlr_scene_buffer_set_transform(snapshot_buffer, scene_buffer->transform); - wlr_scene_buffer_set_filter_mode(snapshot_buffer, - scene_buffer->filter_mode); + wlr_scene_buffer_set_dest_size(snapshot_buffer, scene_buffer->dst_width, + scene_buffer->dst_height); + wlr_scene_buffer_set_opaque_region(snapshot_buffer, + &scene_buffer->opaque_region); + wlr_scene_buffer_set_source_box(snapshot_buffer, + &scene_buffer->src_box); + wlr_scene_buffer_set_transform(snapshot_buffer, + scene_buffer->transform); + wlr_scene_buffer_set_filter_mode(snapshot_buffer, + scene_buffer->filter_mode); - // Effects - wlr_scene_buffer_set_opacity(snapshot_buffer, scene_buffer->opacity); + // Effects + wlr_scene_buffer_set_opacity(snapshot_buffer, scene_buffer->opacity); - snapshot_buffer->node.data = scene_buffer->node.data; + snapshot_buffer->node.data = scene_buffer->node.data; - struct wlr_scene_surface *scene_surface = - wlr_scene_surface_try_from_buffer(scene_buffer); - if (scene_surface != NULL && scene_surface->surface->buffer != NULL) { - wlr_scene_buffer_set_buffer(snapshot_buffer, - &scene_surface->surface->buffer->base); - } else { - wlr_scene_buffer_set_buffer(snapshot_buffer, scene_buffer->buffer); - } - break; - } + struct wlr_scene_surface *scene_surface = + wlr_scene_surface_try_from_buffer(scene_buffer); + if (scene_surface != NULL && scene_surface->surface->buffer != NULL) { + wlr_scene_buffer_set_buffer(snapshot_buffer, + &scene_surface->surface->buffer->base); + } else { + wlr_scene_buffer_set_buffer(snapshot_buffer, scene_buffer->buffer); + } + break; + } - if (snapshot_node != NULL) { - wlr_scene_node_set_position(snapshot_node, lx, ly); - } + if (snapshot_node != NULL) { + wlr_scene_node_set_position(snapshot_node, lx, ly); + } - return true; + return true; } struct wlr_scene_tree *wlr_scene_tree_snapshot(struct wlr_scene_node *node, - struct wlr_scene_tree *parent) { - struct wlr_scene_tree *snapshot = wlr_scene_tree_create(parent); - if (snapshot == NULL) { - return NULL; - } + struct wlr_scene_tree *parent) { + struct wlr_scene_tree *snapshot = wlr_scene_tree_create(parent); + if (snapshot == NULL) { + return NULL; + } - // Disable and enable the snapshot tree like so to atomically update - // the scene-graph. This will prevent over-damaging or other weirdness. - wlr_scene_node_set_enabled(&snapshot->node, false); + // Disable and enable the snapshot tree like so to atomically update + // the scene-graph. This will prevent over-damaging or other weirdness. + wlr_scene_node_set_enabled(&snapshot->node, false); - if (!scene_node_snapshot(node, 0, 0, snapshot)) { - wlr_scene_node_destroy(&snapshot->node); - return NULL; - } + if (!scene_node_snapshot(node, 0, 0, snapshot)) { + wlr_scene_node_destroy(&snapshot->node); + return NULL; + } - wlr_scene_node_set_enabled(&snapshot->node, true); + wlr_scene_node_set_enabled(&snapshot->node, true); - return snapshot; + return snapshot; } void pending_kill_client(Client *c) { - // c->iskilling = 1; //不可以提前标记已经杀掉,因为有些客户端可能拒绝 - client_send_close(c); + // c->iskilling = 1; //不可以提前标记已经杀掉,因为有些客户端可能拒绝 + client_send_close(c); } void killclient(const Arg *arg) { - Client *c; - c = selmon->sel; - if (c) { - pending_kill_client(c); - } + Client *c; + c = selmon->sel; + if (c) { + pending_kill_client(c); + } } void locksession(struct wl_listener *listener, void *data) { - struct wlr_session_lock_v1 *session_lock = data; - SessionLock *lock; - wlr_scene_node_set_enabled(&locked_bg->node, true); - if (cur_lock) { - wlr_session_lock_v1_destroy(session_lock); - return; - } - lock = session_lock->data = ecalloc(1, sizeof(*lock)); - focusclient(NULL, 0); + struct wlr_session_lock_v1 *session_lock = data; + SessionLock *lock; + wlr_scene_node_set_enabled(&locked_bg->node, true); + if (cur_lock) { + wlr_session_lock_v1_destroy(session_lock); + return; + } + lock = session_lock->data = ecalloc(1, sizeof(*lock)); + focusclient(NULL, 0); - lock->scene = wlr_scene_tree_create(layers[LyrBlock]); - cur_lock = lock->lock = session_lock; - locked = 1; + lock->scene = wlr_scene_tree_create(layers[LyrBlock]); + cur_lock = lock->lock = session_lock; + locked = 1; - LISTEN(&session_lock->events.new_surface, &lock->new_surface, - createlocksurface); - LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock); - LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession); + LISTEN(&session_lock->events.new_surface, &lock->new_surface, + createlocksurface); + LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock); + LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession); - wlr_session_lock_v1_send_locked(session_lock); + wlr_session_lock_v1_send_locked(session_lock); } void // old fix to 0.5 mapnotify(struct wl_listener *listener, void *data) { - /* Called when the surface is mapped, or ready to display on-screen. */ - Client *p = NULL; - Client *c = wl_container_of(listener, c, map); - int i; - /* Create scene tree for this client and its border */ - c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); - wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); - c->scene_surface = - c->type == XDGShell - ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) - : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); - c->scene->node.data = c->scene_surface->node.data = c; + /* Called when the surface is mapped, or ready to display on-screen. */ + Client *p = NULL; + Client *c = wl_container_of(listener, c, map); + int i; + /* Create scene tree for this client and its border */ + c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); + wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); + c->scene_surface = + c->type == XDGShell + ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) + : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); + c->scene->node.data = c->scene_surface->node.data = c; - client_get_geometry(c, &c->geom); + client_get_geometry(c, &c->geom); - if (client_is_unmanaged(c) || client_should_ignore_focus(c)) { - c->bw = 0; - c->isnoborder = 1; - } else { - c->bw = borderpx; - } + if (client_is_unmanaged(c) || client_should_ignore_focus(c)) { + c->bw = 0; + c->isnoborder = 1; + } else { + c->bw = borderpx; + } - /* Handle unmanaged clients first so we can return prior create borders */ - if (client_is_unmanaged(c)) { - /* Unmanaged clients always are floating */ - wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); - wlr_scene_node_set_position(&c->scene->node, c->geom.x + borderpx, - c->geom.y + borderpx); - if (client_wants_focus(c)) { - focusclient(c, 1); - exclusive_focus = c; - } + /* Handle unmanaged clients first so we can return prior create borders */ + if (client_is_unmanaged(c)) { + /* Unmanaged clients always are floating */ + wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]); + wlr_scene_node_set_position(&c->scene->node, c->geom.x + borderpx, + c->geom.y + borderpx); + if (client_wants_focus(c)) { + focusclient(c, 1); + exclusive_focus = c; + } #ifdef XWAYLAND - if (client_is_x11(c)) { - LISTEN(&c->surface.xwayland->events.set_geometry, &c->set_geometry, - setgeometrynotify); - } + if (client_is_x11(c)) { + LISTEN(&c->surface.xwayland->events.set_geometry, &c->set_geometry, + setgeometrynotify); + } #endif - return; - } + return; + } - for (i = 0; i < 4; i++) { - c->border[i] = wlr_scene_rect_create( - c->scene, 0, 0, c->isurgent ? urgentcolor : bordercolor); - c->border[i]->node.data = c; - } + for (i = 0; i < 4; i++) { + c->border[i] = wlr_scene_rect_create( + c->scene, 0, 0, c->isurgent ? urgentcolor : bordercolor); + c->border[i]->node.data = c; + } - /* Initialize client geometry with room for border */ - client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | - WLR_EDGE_RIGHT); - c->geom.width += 2 * c->bw; - c->geom.height += 2 * c->bw; - c->ismaxmizescreen = 0; - c->isfullscreen = 0; - c->need_float_size_reduce = 0; - c->iskilling = 0; - c->isglobal = 0; - c->isminied = 0; - c->isoverlay = 0; - c->isunglobal = 0; - c->is_in_scratchpad = 0; - c->isnamedscratchpand = 0; - c->is_scratchpad_show = 0; - c->need_float_size_reduce = 0; - c->is_clip_to_hide = 0; - c->is_restoring_from_ov = 0; - c->isurgent = 0; - c->need_output_flush = 0; - c->scroller_proportion = scroller_default_proportion; - c->is_open_animation = true; - c->drag_to_tile = false; - c->fake_no_border = false; - c->nofadein = 0; - c->nofadeout = 0; - c->no_force_center = 0; + /* Initialize client geometry with room for border */ + client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | + WLR_EDGE_RIGHT); + c->geom.width += 2 * c->bw; + c->geom.height += 2 * c->bw; + c->ismaxmizescreen = 0; + c->isfullscreen = 0; + c->need_float_size_reduce = 0; + c->iskilling = 0; + c->isglobal = 0; + c->isminied = 0; + c->isoverlay = 0; + c->isunglobal = 0; + c->is_in_scratchpad = 0; + c->isnamedscratchpand = 0; + c->is_scratchpad_show = 0; + c->need_float_size_reduce = 0; + c->is_clip_to_hide = 0; + c->is_restoring_from_ov = 0; + c->isurgent = 0; + c->need_output_flush = 0; + c->scroller_proportion = scroller_default_proportion; + c->is_open_animation = true; + c->drag_to_tile = false; + c->fake_no_border = false; + c->nofadein = 0; + c->nofadeout = 0; + c->no_force_center = 0; - if (new_is_master && selmon && - strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, - "scroller") != 0) - // tile at the top - wl_list_insert(&clients, &c->link); // 新窗口是master,头部入栈 - else if (selmon && - strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, - "scroller") == 0 && - center_select(selmon)) { - Client *at_client = center_select(selmon); - at_client->link.next->prev = &c->link; - c->link.prev = &at_client->link; - c->link.next = at_client->link.next; - at_client->link.next = &c->link; - } else - wl_list_insert(clients.prev, &c->link); // 尾部入栈 - wl_list_insert(&fstack, &c->flink); + if (new_is_master && selmon && + strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") != 0) + // tile at the top + wl_list_insert(&clients, &c->link); // 新窗口是master,头部入栈 + else if (selmon && + strcmp(selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") == 0 && + center_select(selmon)) { + Client *at_client = center_select(selmon); + at_client->link.next->prev = &c->link; + c->link.prev = &at_client->link; + c->link.next = at_client->link.next; + at_client->link.next = &c->link; + } else + wl_list_insert(clients.prev, &c->link); // 尾部入栈 + wl_list_insert(&fstack, &c->flink); - /* Set initial monitor, tags, floating status, and focus: - * we always consider floating, clients that have parent and thus - * we set the same tags and monitor than its parent, if not - * try to apply rules for them */ - if ((p = client_get_parent(c))) { - c->isfloating = 1; - setmon(c, p->mon, p->tags, true); - } else { - applyrules(c); - } + /* Set initial monitor, tags, floating status, and focus: + * we always consider floating, clients that have parent and thus + * we set the same tags and monitor than its parent, if not + * try to apply rules for them */ + if ((p = client_get_parent(c))) { + c->isfloating = 1; + setmon(c, p->mon, p->tags, true); + } else { + applyrules(c); + } - // make sure the animation is open type - c->is_open_animation = true; - resize(c, c->geom, 0); - printstatus(); + // make sure the animation is open type + c->is_open_animation = true; + resize(c, c->geom, 0); + printstatus(); } void // 0.5 custom maximizenotify(struct wl_listener *listener, void *data) { - /* This event is raised when a client would like to maximize itself, - * typically because the user clicked on the maximize button on - * client-side decorations. dwl doesn't support maximization, but - * to conform to xdg-shell protocol we still must send a configure. - * Since xdg-shell protocol v5 we should ignore request of unsupported - * capabilities, just schedule a empty configure when the client uses <5 - * protocol version - * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ - // Client *c = wl_container_of(listener, c, maximize); - // if (wl_resource_get_version(c->surface.xdg->toplevel->resource) - // < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) - // wlr_xdg_surface_schedule_configure(c->surface.xdg); - // togglemaxmizescreen(&(Arg){0}); - Client *c = wl_container_of(listener, c, maximize); + /* This event is raised when a client would like to maximize itself, + * typically because the user clicked on the maximize button on + * client-side decorations. dwl doesn't support maximization, but + * to conform to xdg-shell protocol we still must send a configure. + * Since xdg-shell protocol v5 we should ignore request of unsupported + * capabilities, just schedule a empty configure when the client uses <5 + * protocol version + * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ + // Client *c = wl_container_of(listener, c, maximize); + // if (wl_resource_get_version(c->surface.xdg->toplevel->resource) + // < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) + // wlr_xdg_surface_schedule_configure(c->surface.xdg); + // togglemaxmizescreen(&(Arg){0}); + Client *c = wl_container_of(listener, c, maximize); - if (!c || !c->mon || c->iskilling) - return; + if (!c || !c->mon || c->iskilling) + return; - if (c->ismaxmizescreen || c->isfullscreen) - setmaxmizescreen(c, 0); - else - setmaxmizescreen(c, 1); + if (c->ismaxmizescreen || c->isfullscreen) + setmaxmizescreen(c, 0); + else + setmaxmizescreen(c, 1); } void set_minized(Client *c) { - if (!c || !c->mon) - return; + if (!c || !c->mon) + return; - c->isglobal = 0; - c->oldtags = c->mon->tagset[c->mon->seltags]; - c->mini_restore_tag = c->tags; - c->tags = 0; - c->isminied = 1; - c->is_in_scratchpad = 1; - c->is_scratchpad_show = 0; - focusclient(focustop(selmon), 1); - arrange(c->mon, false); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false); - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); - wl_list_remove(&c->link); // 从原来位置移除 - wl_list_insert(clients.prev, &c->link); // 插入尾部 + c->isglobal = 0; + c->oldtags = c->mon->tagset[c->mon->seltags]; + c->mini_restore_tag = c->tags; + c->tags = 0; + c->isminied = 1; + c->is_in_scratchpad = 1; + c->is_scratchpad_show = 0; + focusclient(focustop(selmon), 1); + arrange(c->mon, false); + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false); + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); + wl_list_remove(&c->link); // 从原来位置移除 + wl_list_insert(clients.prev, &c->link); // 插入尾部 } void // 0.5 custom minimizenotify(struct wl_listener *listener, void *data) { - /* This event is raised when a client would like to maximize itself, - * typically because the user clicked on the maximize button on - * client-side decorations. dwl doesn't support maximization, but - * to conform to xdg-shell protocol we still must send a configure. - * Since xdg-shell protocol v5 we should ignore request of unsupported - * capabilities, just schedule a empty configure when the client uses <5 - * protocol version - * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ - // Client *c = wl_container_of(listener, c, maximize); - // if (wl_resource_get_version(c->surface.xdg->toplevel->resource) - // < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) - // wlr_xdg_surface_schedule_configure(c->surface.xdg); - // togglemaxmizescreen(&(Arg){0}); - Client *c = wl_container_of(listener, c, minimize); + /* This event is raised when a client would like to maximize itself, + * typically because the user clicked on the maximize button on + * client-side decorations. dwl doesn't support maximization, but + * to conform to xdg-shell protocol we still must send a configure. + * Since xdg-shell protocol v5 we should ignore request of unsupported + * capabilities, just schedule a empty configure when the client uses <5 + * protocol version + * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */ + // Client *c = wl_container_of(listener, c, maximize); + // if (wl_resource_get_version(c->surface.xdg->toplevel->resource) + // < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) + // wlr_xdg_surface_schedule_configure(c->surface.xdg); + // togglemaxmizescreen(&(Arg){0}); + Client *c = wl_container_of(listener, c, minimize); - if (!c || !c->mon || c->iskilling || c->isminied) - return; + if (!c || !c->mon || c->iskilling || c->isminied) + return; - set_minized(c); + set_minized(c); } void motionabsolute(struct wl_listener *listener, void *data) { - /* This event is forwarded by the cursor when a pointer emits an _absolute_ - * motion event, from 0..1 on each axis. This happens, for example, when - * wlroots is running under a Wayland window rather than KMS+DRM, and you - * move the mouse over the window. You could enter the window from any edge, - * so we have to warp the mouse there. There is also some hardware which - * emits these events. */ - struct wlr_pointer_motion_absolute_event *event = data; - double lx, ly, dx, dy; + /* This event is forwarded by the cursor when a pointer emits an _absolute_ + * motion event, from 0..1 on each axis. This happens, for example, when + * wlroots is running under a Wayland window rather than KMS+DRM, and you + * move the mouse over the window. You could enter the window from any edge, + * so we have to warp the mouse there. There is also some hardware which + * emits these events. */ + struct wlr_pointer_motion_absolute_event *event = data; + double lx, ly, dx, dy; - if (!event->time_msec) /* this is 0 with virtual pointers */ - wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y); + if (!event->time_msec) /* this is 0 with virtual pointers */ + wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, + event->y); - wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x, - event->y, &lx, &ly); - dx = lx - cursor->x; - dy = ly - cursor->y; - motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy); + wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, + event->x, event->y, &lx, &ly); + dx = lx - cursor->x; + dy = ly - cursor->y; + motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy); } void motionnotify(uint32_t time, struct wlr_input_device *device, double dx, - double dy, double dx_unaccel, double dy_unaccel) { - double sx = 0, sy = 0, sx_confined, sy_confined; - Client *c = NULL, *w = NULL; - LayerSurface *l = NULL; - struct wlr_surface *surface = NULL; - struct wlr_pointer_constraint_v1 *constraint; - bool should_lock = false; + double dy, double dx_unaccel, double dy_unaccel) { + double sx = 0, sy = 0, sx_confined, sy_confined; + Client *c = NULL, *w = NULL; + LayerSurface *l = NULL; + struct wlr_surface *surface = NULL; + struct wlr_pointer_constraint_v1 *constraint; + bool should_lock = false; - /* Find the client under the pointer and send the event along. */ - xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); + /* Find the client under the pointer and send the event along. */ + xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy); - if (cursor_mode == CurPressed && !seat->drag && - surface != seat->pointer_state.focused_surface && - toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= - 0) { - c = w; - surface = seat->pointer_state.focused_surface; - sx = cursor->x - (l ? l->scene->node.x : w->geom.x); - sy = cursor->y - (l ? l->scene->node.y : w->geom.y); - } + if (cursor_mode == CurPressed && !seat->drag && + surface != seat->pointer_state.focused_surface && + toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, + &l) >= 0) { + c = w; + surface = seat->pointer_state.focused_surface; + sx = cursor->x - (l ? l->scene->node.x : w->geom.x); + sy = cursor->y - (l ? l->scene->node.y : w->geom.y); + } - /* time is 0 in internal calls meant to restore pointer focus. */ - if (time) { - wlr_relative_pointer_manager_v1_send_relative_motion( - relative_pointer_mgr, seat, (uint64_t)time * 1000, dx, dy, dx_unaccel, - dy_unaccel); + /* time is 0 in internal calls meant to restore pointer focus. */ + if (time) { + wlr_relative_pointer_manager_v1_send_relative_motion( + relative_pointer_mgr, seat, (uint64_t)time * 1000, dx, dy, + dx_unaccel, dy_unaccel); - wl_list_for_each(constraint, &pointer_constraints->constraints, link) - cursorconstrain(constraint); + wl_list_for_each(constraint, &pointer_constraints->constraints, link) + cursorconstrain(constraint); - if (active_constraint && cursor_mode != CurResize && - cursor_mode != CurMove) { - toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); - if (c && - active_constraint->surface == seat->pointer_state.focused_surface) { - sx = cursor->x - c->geom.x - c->bw; - sy = cursor->y - c->geom.y - c->bw; - if (wlr_region_confine(&active_constraint->region, sx, sy, sx + dx, - sy + dy, &sx_confined, &sy_confined)) { - dx = sx_confined - sx; - dy = sy_confined - sy; - } + if (active_constraint && cursor_mode != CurResize && + cursor_mode != CurMove) { + toplevel_from_wlr_surface(active_constraint->surface, &c, NULL); + if (c && active_constraint->surface == + seat->pointer_state.focused_surface) { + sx = cursor->x - c->geom.x - c->bw; + sy = cursor->y - c->geom.y - c->bw; + if (wlr_region_confine(&active_constraint->region, sx, sy, + sx + dx, sy + dy, &sx_confined, + &sy_confined)) { + dx = sx_confined - sx; + dy = sy_confined - sy; + } - if (active_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) - return; - } - } + if (active_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED) + return; + } + } - wlr_cursor_move(cursor, device, dx, dy); - handlecursoractivity(); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + wlr_cursor_move(cursor, device, dx, dy); + handlecursoractivity(); + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - /* Update selmon (even while dragging a window) */ - if (sloppyfocus) - selmon = xytomon(cursor->x, cursor->y); - } + /* Update selmon (even while dragging a window) */ + if (sloppyfocus) + selmon = xytomon(cursor->x, cursor->y); + } - /* Update drag icon's position */ - wlr_scene_node_set_position(&drag_icon->node, (int)round(cursor->x), - (int)round(cursor->y)); + /* Update drag icon's position */ + wlr_scene_node_set_position(&drag_icon->node, (int)round(cursor->x), + (int)round(cursor->y)); - /* If we are currently grabbing the mouse, handle and return */ - if (cursor_mode == CurMove) { - /* Move the grabbed client to the new position. */ - grabc->oldgeom = (struct wlr_box){.x = (int)round(cursor->x) - grabcx, - .y = (int)round(cursor->y) - grabcy, - .width = grabc->geom.width, - .height = grabc->geom.height}; - resize(grabc, grabc->oldgeom, 1); - return; - } else if (cursor_mode == CurResize) { - grabc->oldgeom = - (struct wlr_box){.x = grabc->geom.x, - .y = grabc->geom.y, - .width = (int)round(cursor->x) - grabc->geom.x, - .height = (int)round(cursor->y) - grabc->geom.y}; - resize(grabc, grabc->oldgeom, 1); - return; - } + /* If we are currently grabbing the mouse, handle and return */ + if (cursor_mode == CurMove) { + /* Move the grabbed client to the new position. */ + grabc->oldgeom = (struct wlr_box){.x = (int)round(cursor->x) - grabcx, + .y = (int)round(cursor->y) - grabcy, + .width = grabc->geom.width, + .height = grabc->geom.height}; + resize(grabc, grabc->oldgeom, 1); + return; + } else if (cursor_mode == CurResize) { + grabc->oldgeom = + (struct wlr_box){.x = grabc->geom.x, + .y = grabc->geom.y, + .width = (int)round(cursor->x) - grabc->geom.x, + .height = (int)round(cursor->y) - grabc->geom.y}; + resize(grabc, grabc->oldgeom, 1); + return; + } - /* If there's no client surface under the cursor, set the cursor image to a - * default. This is what makes the cursor image appear when you move it - * off of a client or over its border. */ - if (!surface && !seat->drag && !cursor_hidden) - wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); + /* If there's no client surface under the cursor, set the cursor image to a + * default. This is what makes the cursor image appear when you move it + * off of a client or over its border. */ + if (!surface && !seat->drag && !cursor_hidden) + wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); - if (c && c->mon && !c->animation.running && - (!(c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x) || - !ISTILED(c))) { - scroller_focus_lock = 0; - } + if (c && c->mon && !c->animation.running && + (!(c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || + c->geom.x < c->mon->m.x) || + !ISTILED(c))) { + scroller_focus_lock = 0; + } - should_lock = false; - if (!scroller_focus_lock || - !(c && c->mon && - (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x))) { - if (c && c->mon && - strcmp(c->mon->pertag->ltidxs[selmon->pertag->curtag]->name, - "scroller") == 0 && - (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x)) { - should_lock = true; - } - pointerfocus(c, surface, sx, sy, time); + should_lock = false; + if (!scroller_focus_lock || + !(c && c->mon && + (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || + c->geom.x < c->mon->m.x))) { + if (c && c->mon && + strcmp(c->mon->pertag->ltidxs[selmon->pertag->curtag]->name, + "scroller") == 0 && + (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || + c->geom.x < c->mon->m.x)) { + should_lock = true; + } + pointerfocus(c, surface, sx, sy, time); - if (should_lock && c && c->mon && ISTILED(c) && c == c->mon->sel) { - scroller_focus_lock = 1; - } - } + if (should_lock && c && c->mon && ISTILED(c) && c == c->mon->sel) { + scroller_focus_lock = 1; + } + } } void motionrelative(struct wl_listener *listener, void *data) { - /* This event is forwarded by the cursor when a pointer emits a _relative_ - * pointer motion event (i.e. a delta) */ - struct wlr_pointer_motion_event *event = data; - /* The cursor doesn't move unless we tell it to. The cursor automatically - * handles constraining the motion to the output layout, as well as any - * special configuration applied for the specific input device which - * generated the event. You can pass NULL for the device if you want to move - * the cursor around without any input. */ - motionnotify(event->time_msec, &event->pointer->base, event->delta_x, - event->delta_y, event->unaccel_dx, event->unaccel_dy); - toggle_hotarea(cursor->x, cursor->y); + /* This event is forwarded by the cursor when a pointer emits a _relative_ + * pointer motion event (i.e. a delta) */ + struct wlr_pointer_motion_event *event = data; + /* The cursor doesn't move unless we tell it to. The cursor automatically + * handles constraining the motion to the output layout, as well as any + * special configuration applied for the specific input device which + * generated the event. You can pass NULL for the device if you want to move + * the cursor around without any input. */ + motionnotify(event->time_msec, &event->pointer->base, event->delta_x, + event->delta_y, event->unaccel_dx, event->unaccel_dy); + toggle_hotarea(cursor->x, cursor->y); } void // 17 moveresize(const Arg *arg) { - if (cursor_mode != CurNormal && cursor_mode != CurPressed) - return; - xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL); - if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen) - return; + if (cursor_mode != CurNormal && cursor_mode != CurPressed) + return; + xytonode(cursor->x, cursor->y, NULL, &grabc, NULL, NULL, NULL); + if (!grabc || client_is_unmanaged(grabc) || grabc->isfullscreen) + return; - /* Float the window and tell motionnotify to grab it */ - if (grabc->isfloating == 0) { - grabc->drag_to_tile = true; - setfloating(grabc, 1); - } + /* Float the window and tell motionnotify to grab it */ + if (grabc->isfloating == 0) { + grabc->drag_to_tile = true; + setfloating(grabc, 1); + } - switch (cursor_mode = arg->ui) { - case CurMove: - grabcx = cursor->x - grabc->geom.x; - grabcy = cursor->y - grabc->geom.y; - wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); - break; - case CurResize: - /* Doesn't work for X11 output - the next absolute motion event - * returns the cursor to where it started */ - wlr_cursor_warp_closest(cursor, NULL, grabc->geom.x + grabc->geom.width, - grabc->geom.y + grabc->geom.height); - wlr_cursor_set_xcursor(cursor, cursor_mgr, "bottom_right_corner"); - break; - } + switch (cursor_mode = arg->ui) { + case CurMove: + grabcx = cursor->x - grabc->geom.x; + grabcy = cursor->y - grabc->geom.y; + wlr_cursor_set_xcursor(cursor, cursor_mgr, "fleur"); + break; + case CurResize: + /* Doesn't work for X11 output - the next absolute motion event + * returns the cursor to where it started */ + wlr_cursor_warp_closest(cursor, NULL, grabc->geom.x + grabc->geom.width, + grabc->geom.y + grabc->geom.height); + wlr_cursor_set_xcursor(cursor, cursor_mgr, "bottom_right_corner"); + break; + } } void outputmgrapply(struct wl_listener *listener, void *data) { - struct wlr_output_configuration_v1 *config = data; - outputmgrapplyortest(config, 0); + struct wlr_output_configuration_v1 *config = data; + outputmgrapplyortest(config, 0); } void // 0.7 custom outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test) { - /* - * Called when a client such as wlr-randr requests a change in output - * configuration. This is only one way that the layout can be changed, - * so any Monitor information should be updated by updatemons() after an - * output_layout.change event, not here. - */ - struct wlr_output_configuration_head_v1 *config_head; - int ok = 1; + /* + * Called when a client such as wlr-randr requests a change in output + * configuration. This is only one way that the layout can be changed, + * so any Monitor information should be updated by updatemons() after an + * output_layout.change event, not here. + */ + struct wlr_output_configuration_head_v1 *config_head; + int ok = 1; - wl_list_for_each(config_head, &config->heads, link) { - struct wlr_output *wlr_output = config_head->state.output; - Monitor *m = wlr_output->data; - struct wlr_output_state state; + wl_list_for_each(config_head, &config->heads, link) { + struct wlr_output *wlr_output = config_head->state.output; + Monitor *m = wlr_output->data; + struct wlr_output_state state; - /* Ensure displays previously disabled by wlr-output-power-management-v1 - * are properly handled*/ - m->asleep = 0; + /* Ensure displays previously disabled by wlr-output-power-management-v1 + * are properly handled*/ + m->asleep = 0; - wlr_output_state_init(&state); - wlr_output_state_set_enabled(&state, config_head->state.enabled); - if (!config_head->state.enabled) - goto apply_or_test; + wlr_output_state_init(&state); + wlr_output_state_set_enabled(&state, config_head->state.enabled); + if (!config_head->state.enabled) + goto apply_or_test; - if (config_head->state.mode) - wlr_output_state_set_mode(&state, config_head->state.mode); - else - wlr_output_state_set_custom_mode(&state, - config_head->state.custom_mode.width, - config_head->state.custom_mode.height, - config_head->state.custom_mode.refresh); + if (config_head->state.mode) + wlr_output_state_set_mode(&state, config_head->state.mode); + else + wlr_output_state_set_custom_mode( + &state, config_head->state.custom_mode.width, + config_head->state.custom_mode.height, + config_head->state.custom_mode.refresh); - wlr_output_state_set_transform(&state, config_head->state.transform); - wlr_output_state_set_scale(&state, config_head->state.scale); - wlr_output_state_set_adaptive_sync_enabled( - &state, config_head->state.adaptive_sync_enabled); + wlr_output_state_set_transform(&state, config_head->state.transform); + wlr_output_state_set_scale(&state, config_head->state.scale); + wlr_output_state_set_adaptive_sync_enabled( + &state, config_head->state.adaptive_sync_enabled); - apply_or_test: - ok &= test ? wlr_output_test_state(wlr_output, &state) - : wlr_output_commit_state(wlr_output, &state); + apply_or_test: + ok &= test ? wlr_output_test_state(wlr_output, &state) + : wlr_output_commit_state(wlr_output, &state); - /* Don't move monitors if position wouldn't change, this to avoid - * wlroots marking the output as manually configured. - * wlr_output_layout_add does not like disabled outputs */ - if (!test && wlr_output->enabled && - (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) - wlr_output_layout_add(output_layout, wlr_output, config_head->state.x, - config_head->state.y); + /* Don't move monitors if position wouldn't change, this to avoid + * wlroots marking the output as manually configured. + * wlr_output_layout_add does not like disabled outputs */ + if (!test && wlr_output->enabled && + (m->m.x != config_head->state.x || m->m.y != config_head->state.y)) + wlr_output_layout_add(output_layout, wlr_output, + config_head->state.x, config_head->state.y); - wlr_output_state_finish(&state); - } + wlr_output_state_finish(&state); + } - if (ok) - wlr_output_configuration_v1_send_succeeded(config); - else - wlr_output_configuration_v1_send_failed(config); - wlr_output_configuration_v1_destroy(config); + if (ok) + wlr_output_configuration_v1_send_succeeded(config); + else + wlr_output_configuration_v1_send_failed(config); + wlr_output_configuration_v1_destroy(config); - /* https://codeberg.org/dwl/dwl/issues/577 */ - updatemons(NULL, NULL); + /* https://codeberg.org/dwl/dwl/issues/577 */ + updatemons(NULL, NULL); } void outputmgrtest(struct wl_listener *listener, void *data) { - struct wlr_output_configuration_v1 *config = data; - outputmgrapplyortest(config, 1); + struct wlr_output_configuration_v1 *config = data; + outputmgrapplyortest(config, 1); } void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, - uint32_t time) { - struct timespec now; + uint32_t time) { + struct timespec now; - if (surface != seat->pointer_state.focused_surface && sloppyfocus && time && - c && !client_is_unmanaged(c)) - focusclient(c, 0); + if (surface != seat->pointer_state.focused_surface && sloppyfocus && time && + c && !client_is_unmanaged(c)) + focusclient(c, 0); - /* If surface is NULL, clear pointer focus */ - if (!surface) { - wlr_seat_pointer_notify_clear_focus(seat); - return; - } + /* If surface is NULL, clear pointer focus */ + if (!surface) { + wlr_seat_pointer_notify_clear_focus(seat); + return; + } - if (!time) { - clock_gettime(CLOCK_MONOTONIC, &now); - time = now.tv_sec * 1000 + now.tv_nsec / 1000000; - } + if (!time) { + clock_gettime(CLOCK_MONOTONIC, &now); + time = now.tv_sec * 1000 + now.tv_nsec / 1000000; + } - /* Let the client know that the mouse cursor has entered one - * of its surfaces, and make keyboard focus follow if desired. - * wlroots makes this a no-op if surface is already focused */ - wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(seat, time, sx, sy); + /* Let the client know that the mouse cursor has entered one + * of its surfaces, and make keyboard focus follow if desired. + * wlroots makes this a no-op if surface is already focused */ + wlr_seat_pointer_notify_enter(seat, surface, sx, sy); + wlr_seat_pointer_notify_motion(seat, time, sx, sy); } void // 17 printstatus(void) { - Monitor *m = NULL; - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) { - continue; - } - dwl_ipc_output_printstatus(m); // 更新waybar上tag的状态 这里很关键 - } + Monitor *m = NULL; + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + dwl_ipc_output_printstatus(m); // 更新waybar上tag的状态 这里很关键 + } } void powermgrsetmode(struct wl_listener *listener, void *data) { - struct wlr_output_power_v1_set_mode_event *event = data; - struct wlr_output_state state = {0}; - Monitor *m = event->output->data; + struct wlr_output_power_v1_set_mode_event *event = data; + struct wlr_output_state state = {0}; + Monitor *m = event->output->data; - if (!m) - return; + if (!m) + return; - m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */ - wlr_output_state_set_enabled(&state, event->mode); - wlr_output_commit_state(m->wlr_output, &state); + m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */ + wlr_output_state_set_enabled(&state, event->mode); + wlr_output_commit_state(m->wlr_output, &state); - m->asleep = !event->mode; - updatemons(NULL, NULL); + m->asleep = !event->mode; + updatemons(NULL, NULL); } void // 0.5 custom quit(const Arg *arg) { - wl_display_terminate(dpy); + wl_display_terminate(dpy); } void quitsignal(int signo) { quit(NULL); } void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx, int sy, - void *data) { - wlr_scene_buffer_set_opacity(buffer, *(double *)data); + void *data) { + wlr_scene_buffer_set_opacity(buffer, *(double *)data); } void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, int sy, - void *data) { - animationScale *scale_data = (animationScale *)data; + void *data) { + animationScale *scale_data = (animationScale *)data; - if (scale_data->should_scale && scale_data->height_scale < 1 && - scale_data->width_scale < 1) { - scale_data->should_scale = false; - } + if (scale_data->should_scale && scale_data->height_scale < 1 && + scale_data->width_scale < 1) { + scale_data->should_scale = false; + } - if (scale_data->should_scale && scale_data->height_scale == 1 && - scale_data->width_scale < 1) { - scale_data->should_scale = false; - } + if (scale_data->should_scale && scale_data->height_scale == 1 && + scale_data->width_scale < 1) { + scale_data->should_scale = false; + } - if (scale_data->should_scale && scale_data->height_scale < 1 && - scale_data->width_scale == 1) { - scale_data->should_scale = false; - } + if (scale_data->should_scale && scale_data->height_scale < 1 && + scale_data->width_scale == 1) { + scale_data->should_scale = false; + } - struct wlr_scene_surface *scene_surface = - wlr_scene_surface_try_from_buffer(buffer); + struct wlr_scene_surface *scene_surface = + wlr_scene_surface_try_from_buffer(buffer); - if (scene_surface == NULL) - return; + if (scene_surface == NULL) + return; - struct wlr_surface *surface = scene_surface->surface; + struct wlr_surface *surface = scene_surface->surface; - if (scale_data->should_scale) { + if (scale_data->should_scale) { - uint32_t surface_width = surface->current.width; - uint32_t surface_height = surface->current.height; + uint32_t surface_width = surface->current.width; + uint32_t surface_height = surface->current.height; - surface_width = scale_data->width_scale < 1 - ? surface_width - : scale_data->width_scale * surface_width; - surface_height = scale_data->height_scale < 1 - ? surface_height - : scale_data->height_scale * surface_height; + surface_width = scale_data->width_scale < 1 + ? surface_width + : scale_data->width_scale * surface_width; + surface_height = scale_data->height_scale < 1 + ? surface_height + : scale_data->height_scale * surface_height; - if (surface_width > scale_data->width && - wlr_subsurface_try_from_wlr_surface(surface) == NULL) { - surface_width = scale_data->width; - } + if (surface_width > scale_data->width && + wlr_subsurface_try_from_wlr_surface(surface) == NULL) { + surface_width = scale_data->width; + } - if (surface_height > scale_data->height && - wlr_subsurface_try_from_wlr_surface(surface) == NULL) { - surface_height = scale_data->height; - } + if (surface_height > scale_data->height && + wlr_subsurface_try_from_wlr_surface(surface) == NULL) { + surface_height = scale_data->height; + } - if (surface_width > scale_data->width && - wlr_subsurface_try_from_wlr_surface(surface) != NULL) { - return; - } + if (surface_width > scale_data->width && + wlr_subsurface_try_from_wlr_surface(surface) != NULL) { + return; + } - if (surface_height > scale_data->height && - wlr_subsurface_try_from_wlr_surface(surface) != NULL) { - return; - } + if (surface_height > scale_data->height && + wlr_subsurface_try_from_wlr_surface(surface) != NULL) { + return; + } - if (surface_height > 0 && surface_width > 0) { - wlr_scene_buffer_set_dest_size(buffer, surface_width, surface_height); - } - } - // TODO: blur set, opacity set + if (surface_height > 0 && surface_width > 0) { + wlr_scene_buffer_set_dest_size(buffer, surface_width, + surface_height); + } + } + // TODO: blur set, opacity set } void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, - int sy, void *data) { - animationScale *scale_data = (animationScale *)data; - wlr_scene_buffer_set_dest_size(buffer, scale_data->width, scale_data->height); + int sy, void *data) { + animationScale *scale_data = (animationScale *)data; + wlr_scene_buffer_set_dest_size(buffer, scale_data->width, + scale_data->height); } void buffer_set_effect(Client *c, animationScale data) { - if (c->iskilling || c->animation.tagouting || c->animation.tagouted || - c->animation.tagining) { - data.should_scale = false; - } + if (c->iskilling || c->animation.tagouting || c->animation.tagouted || + c->animation.tagining) { + data.should_scale = false; + } - if (client_is_x11(c) && c->current.height >= c->animation.current.height && - c->current.width >= c->animation.current.width) { - data.should_scale = false; - } + if (client_is_x11(c) && c->current.height >= c->animation.current.height && + c->current.width >= c->animation.current.width) { + data.should_scale = false; + } - if (c == grabc) - data.should_scale = false; + if (c == grabc) + data.should_scale = false; - wlr_scene_node_for_each_buffer(&c->scene_surface->node, - scene_buffer_apply_effect, &data); + wlr_scene_node_for_each_buffer(&c->scene_surface->node, + scene_buffer_apply_effect, &data); } void client_set_opacity(Client *c, double opacity) { - wlr_scene_node_for_each_buffer(&c->scene_surface->node, - scene_buffer_apply_opacity, &opacity); + wlr_scene_node_for_each_buffer(&c->scene_surface->node, + scene_buffer_apply_opacity, &opacity); } void client_handle_opacity(Client *c) { - if (!c || !c->mon || !client_surface(c)->mapped) - return; + if (!c || !c->mon || !client_surface(c)->mapped) + return; - double opacity = c->isfullscreen || c->ismaxmizescreen ? 1.0 - : c == selmon->sel ? 0.8 - : 0.5; + double opacity = c->isfullscreen || c->ismaxmizescreen ? 1.0 + : c == selmon->sel ? 0.8 + : 0.5; - wlr_scene_node_for_each_buffer(&c->scene_surface->node, - scene_buffer_apply_opacity, &opacity); + wlr_scene_node_for_each_buffer(&c->scene_surface->node, + scene_buffer_apply_opacity, &opacity); } void rendermon(struct wl_listener *listener, void *data) { - Monitor *m = wl_container_of(listener, m, frame); - Client *c, *tmp; - struct wlr_output_state pending = {0}; + Monitor *m = wl_container_of(listener, m, frame); + Client *c, *tmp; + struct wlr_output_state pending = {0}; - struct timespec now; - bool need_more_frames = false; + struct timespec now; + bool need_more_frames = false; - // Draw frames for all clients - wl_list_for_each(c, &clients, link) { - need_more_frames = client_draw_frame(c) || need_more_frames; - } + // Draw frames for all clients + wl_list_for_each(c, &clients, link) { + need_more_frames = client_draw_frame(c) || need_more_frames; + } - wl_list_for_each_safe(c, tmp, &fadeout_clients, fadeout_link) { - need_more_frames = client_draw_fadeout_frame(c) || need_more_frames; - } + wl_list_for_each_safe(c, tmp, &fadeout_clients, fadeout_link) { + need_more_frames = client_draw_fadeout_frame(c) || need_more_frames; + } - wlr_scene_output_commit(m->scene_output, NULL); + wlr_scene_output_commit(m->scene_output, NULL); - // Send frame done notification - clock_gettime(CLOCK_MONOTONIC, &now); - wlr_scene_output_send_frame_done(m->scene_output, &now); + // Send frame done notification + clock_gettime(CLOCK_MONOTONIC, &now); + wlr_scene_output_send_frame_done(m->scene_output, &now); - // // Clean up pending state - wlr_output_state_finish(&pending); + // // Clean up pending state + wlr_output_state_finish(&pending); - if (need_more_frames) { - wlr_output_schedule_frame(m->wlr_output); - } + if (need_more_frames) { + wlr_output_schedule_frame(m->wlr_output); + } } void requestdecorationmode(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, set_decoration_mode); - if (c->surface.xdg->initialized) - wlr_xdg_toplevel_decoration_v1_set_mode( - c->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + Client *c = wl_container_of(listener, c, set_decoration_mode); + if (c->surface.xdg->initialized) + wlr_xdg_toplevel_decoration_v1_set_mode( + c->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); } void requeststartdrag(struct wl_listener *listener, void *data) { - struct wlr_seat_request_start_drag_event *event = data; + struct wlr_seat_request_start_drag_event *event = data; - if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, event->serial)) - wlr_seat_start_pointer_drag(seat, event->drag, event->serial); - else - wlr_data_source_destroy(event->drag->source); + if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, + event->serial)) + wlr_seat_start_pointer_drag(seat, event->drag, event->serial); + else + wlr_data_source_destroy(event->drag->source); } void setborder_color(Client *c) { - if (!c || !c->mon) - return; - if (c->isurgent) { - client_set_border_color(c, urgentcolor); - return; - } - if (c->is_in_scratchpad && selmon && c == selmon->sel) { - client_set_border_color(c, scratchpadcolor); - } else if (c->isglobal && selmon && c == selmon->sel) { - client_set_border_color(c, globalcolor); - } else if (c->isoverlay && selmon && c == selmon->sel) { - client_set_border_color(c, overlaycolor); - } else if (c->ismaxmizescreen && selmon && c == selmon->sel) { - client_set_border_color(c, maxmizescreencolor); - } else if (selmon && c == selmon->sel) { - client_set_border_color(c, focuscolor); - } else { - client_set_border_color(c, bordercolor); - } + if (!c || !c->mon) + return; + if (c->isurgent) { + client_set_border_color(c, urgentcolor); + return; + } + if (c->is_in_scratchpad && selmon && c == selmon->sel) { + client_set_border_color(c, scratchpadcolor); + } else if (c->isglobal && selmon && c == selmon->sel) { + client_set_border_color(c, globalcolor); + } else if (c->isoverlay && selmon && c == selmon->sel) { + client_set_border_color(c, overlaycolor); + } else if (c->ismaxmizescreen && selmon && c == selmon->sel) { + client_set_border_color(c, maxmizescreencolor); + } else if (selmon && c == selmon->sel) { + client_set_border_color(c, focuscolor); + } else { + client_set_border_color(c, bordercolor); + } } void exchange_two_client(Client *c1, Client *c2) { - if (c1 == NULL || c2 == NULL || c1->mon != c2->mon) { - return; - } + if (c1 == NULL || c2 == NULL || c1->mon != c2->mon) { + return; + } - struct wl_list *tmp1_prev = c1->link.prev; - struct wl_list *tmp2_prev = c2->link.prev; - struct wl_list *tmp1_next = c1->link.next; - struct wl_list *tmp2_next = c2->link.next; + struct wl_list *tmp1_prev = c1->link.prev; + struct wl_list *tmp2_prev = c2->link.prev; + struct wl_list *tmp1_next = c1->link.next; + struct wl_list *tmp2_next = c2->link.next; - // wl_list - // 是双向链表,其中clients是头部节点,它的下一个节点是第一个客户端的链表节点 - // 最后一个客户端的链表节点的下一个节点也指向clients,但clients本身不是客户端的链表节点 - // 客户端遍历从clients的下一个节点开始,到检测到客户端节点的下一个是clients结束 + // wl_list + // 是双向链表,其中clients是头部节点,它的下一个节点是第一个客户端的链表节点 + // 最后一个客户端的链表节点的下一个节点也指向clients,但clients本身不是客户端的链表节点 + // 客户端遍历从clients的下一个节点开始,到检测到客户端节点的下一个是clients结束 - // 当c1和c2为相邻节点时 - if (c1->link.next == &c2->link) { - c1->link.next = c2->link.next; - c1->link.prev = &c2->link; - c2->link.next = &c1->link; - c2->link.prev = tmp1_prev; - tmp1_prev->next = &c2->link; - tmp2_next->prev = &c1->link; - } else if (c2->link.next == &c1->link) { - c2->link.next = c1->link.next; - c2->link.prev = &c1->link; - c1->link.next = &c2->link; - c1->link.prev = tmp2_prev; - tmp2_prev->next = &c1->link; - tmp1_next->prev = &c2->link; - } else { // 不为相邻节点 - c2->link.next = tmp1_next; - c2->link.prev = tmp1_prev; - c1->link.next = tmp2_next; - c1->link.prev = tmp2_prev; + // 当c1和c2为相邻节点时 + if (c1->link.next == &c2->link) { + c1->link.next = c2->link.next; + c1->link.prev = &c2->link; + c2->link.next = &c1->link; + c2->link.prev = tmp1_prev; + tmp1_prev->next = &c2->link; + tmp2_next->prev = &c1->link; + } else if (c2->link.next == &c1->link) { + c2->link.next = c1->link.next; + c2->link.prev = &c1->link; + c1->link.next = &c2->link; + c1->link.prev = tmp2_prev; + tmp2_prev->next = &c1->link; + tmp1_next->prev = &c2->link; + } else { // 不为相邻节点 + c2->link.next = tmp1_next; + c2->link.prev = tmp1_prev; + c1->link.next = tmp2_next; + c1->link.prev = tmp2_prev; - tmp1_prev->next = &c2->link; - tmp1_next->prev = &c2->link; - tmp2_prev->next = &c1->link; - tmp2_next->prev = &c1->link; - } + tmp1_prev->next = &c2->link; + tmp1_next->prev = &c2->link; + tmp2_prev->next = &c1->link; + tmp2_next->prev = &c1->link; + } - arrange(c1->mon, false); - focusclient(c1, 0); + arrange(c1->mon, false); + focusclient(c1, 0); } void exchange_client(const Arg *arg) { - Client *c = selmon->sel; - if (!c || c->isfloating || c->isfullscreen || c->ismaxmizescreen) - return; - exchange_two_client(c, direction_select(arg)); + Client *c = selmon->sel; + if (!c || c->isfloating || c->isfullscreen || c->ismaxmizescreen) + return; + exchange_two_client(c, direction_select(arg)); } int is_special_animaiton_rule(Client *c) { - int visible_client_number = 0; - Client *count_c; - wl_list_for_each(count_c, &clients, link) { - if (count_c && VISIBLEON(count_c, selmon) && !count_c->isminied && - !count_c->iskilling && !count_c->isfloating) { - visible_client_number++; - } - } + int visible_client_number = 0; + Client *count_c; + wl_list_for_each(count_c, &clients, link) { + if (count_c && VISIBLEON(count_c, selmon) && !count_c->isminied && + !count_c->iskilling && !count_c->isfloating) { + visible_client_number++; + } + } - 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) { - return RIGHT; - } else if (!c->isfloating && new_is_master) { - return LEFT; - } else { - return UNDIR; - } + 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) { + return RIGHT; + } else if (!c->isfloating && new_is_master) { + return LEFT; + } else { + return UNDIR; + } } void set_open_animaiton(Client *c, struct wlr_box geo) { - int slide_direction; - int horizontal, horizontal_value; - int vertical, vertical_value; - int special_direction; - int center_x, center_y; - if ((!c->animation_type_open && strcmp(animation_type_open, "zoom") == 0) || - (c->animation_type_open && strcmp(c->animation_type_open, "zoom") == 0)) { - c->animainit_geom.width = geo.width * zoom_initial_ratio; - c->animainit_geom.height = geo.height * zoom_initial_ratio; - c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width) / 2; - c->animainit_geom.y = geo.y + (geo.height - c->animainit_geom.height) / 2; - return; - } else { - special_direction = is_special_animaiton_rule(c); - center_x = c->geom.x + c->geom.width / 2; - center_y = c->geom.y + c->geom.height / 2; - if (special_direction == UNDIR) { - horizontal = - c->mon->w.x + c->mon->w.width - center_x < center_x - c->mon->w.x - ? RIGHT - : LEFT; - horizontal_value = horizontal == LEFT - ? center_x - c->mon->w.x - : c->mon->w.x + c->mon->w.width - center_x; - vertical = - c->mon->w.y + c->mon->w.height - center_y < center_y - c->mon->w.y - ? DOWN - : UP; - vertical_value = vertical == UP - ? center_y - c->mon->w.y - : c->mon->w.y + c->mon->w.height - center_y; - slide_direction = - horizontal_value < vertical_value ? horizontal : vertical; - } else { - slide_direction = special_direction; - } - c->animainit_geom.width = c->geom.width; - c->animainit_geom.height = c->geom.height; - switch (slide_direction) { - case UP: - c->animainit_geom.x = c->geom.x; - c->animainit_geom.y = c->mon->m.y - c->geom.height; - break; - case DOWN: - c->animainit_geom.x = c->geom.x; - c->animainit_geom.y = - c->geom.y + c->mon->m.height - (c->geom.y - c->mon->m.y); - break; - case LEFT: - c->animainit_geom.x = c->mon->m.x - c->geom.width; - c->animainit_geom.y = c->geom.y; - break; - case RIGHT: - c->animainit_geom.x = - c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); - c->animainit_geom.y = c->geom.y; - break; - default: - c->animainit_geom.x = c->geom.x; - c->animainit_geom.y = 0 - c->geom.height; - } - } + int slide_direction; + int horizontal, horizontal_value; + int vertical, vertical_value; + int special_direction; + int center_x, center_y; + if ((!c->animation_type_open && strcmp(animation_type_open, "zoom") == 0) || + (c->animation_type_open && + strcmp(c->animation_type_open, "zoom") == 0)) { + c->animainit_geom.width = geo.width * zoom_initial_ratio; + c->animainit_geom.height = geo.height * zoom_initial_ratio; + c->animainit_geom.x = geo.x + (geo.width - c->animainit_geom.width) / 2; + c->animainit_geom.y = + geo.y + (geo.height - c->animainit_geom.height) / 2; + return; + } else { + special_direction = is_special_animaiton_rule(c); + center_x = c->geom.x + c->geom.width / 2; + center_y = c->geom.y + c->geom.height / 2; + if (special_direction == UNDIR) { + horizontal = c->mon->w.x + c->mon->w.width - center_x < + center_x - c->mon->w.x + ? RIGHT + : LEFT; + horizontal_value = horizontal == LEFT + ? center_x - c->mon->w.x + : c->mon->w.x + c->mon->w.width - center_x; + vertical = c->mon->w.y + c->mon->w.height - center_y < + center_y - c->mon->w.y + ? DOWN + : UP; + vertical_value = vertical == UP + ? center_y - c->mon->w.y + : c->mon->w.y + c->mon->w.height - center_y; + slide_direction = + horizontal_value < vertical_value ? horizontal : vertical; + } else { + slide_direction = special_direction; + } + c->animainit_geom.width = c->geom.width; + c->animainit_geom.height = c->geom.height; + switch (slide_direction) { + case UP: + c->animainit_geom.x = c->geom.x; + c->animainit_geom.y = c->mon->m.y - c->geom.height; + break; + case DOWN: + c->animainit_geom.x = c->geom.x; + c->animainit_geom.y = + c->geom.y + c->mon->m.height - (c->geom.y - c->mon->m.y); + break; + case LEFT: + c->animainit_geom.x = c->mon->m.x - c->geom.width; + c->animainit_geom.y = c->geom.y; + break; + case RIGHT: + c->animainit_geom.x = + c->geom.x + c->mon->m.width - (c->geom.x - c->mon->m.x); + c->animainit_geom.y = c->geom.y; + break; + default: + c->animainit_geom.x = c->geom.x; + c->animainit_geom.y = 0 - c->geom.height; + } + } } void resize(Client *c, struct wlr_box geo, int interact) { - // 动画设置的起始函数,这里用来计算一些动画的起始值 - // 动画起始位置大小是由于c->animainit_geom确定的 + // 动画设置的起始函数,这里用来计算一些动画的起始值 + // 动画起始位置大小是由于c->animainit_geom确定的 - if (!c || !c->mon || !client_surface(c)->mapped) - return; + if (!c || !c->mon || !client_surface(c)->mapped) + return; - struct wlr_box *bbox; - struct wlr_box clip; + struct wlr_box *bbox; + struct wlr_box clip; - if (!c->mon) - return; + if (!c->mon) + return; - c->need_output_flush = true; + c->need_output_flush = true; - // oldgeom = c->geom; - bbox = (interact || c->isfloating || c->isfullscreen) ? &sgeom : &c->mon->w; + // oldgeom = c->geom; + bbox = (interact || c->isfloating || c->isfullscreen) ? &sgeom : &c->mon->w; - if (strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name, - "scroller") == 0 && - (!c->isfloating || c == grabc)) { - c->geom = geo; - c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); - c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); - } else { // 这里会限制不允许窗口划出屏幕 - client_set_bounds( - c, geo.width, - geo.height); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 - c->geom = geo; - applybounds( - c, bbox); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 - } + if (strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name, + "scroller") == 0 && + (!c->isfloating || c == grabc)) { + c->geom = geo; + c->geom.width = MAX(1 + 2 * (int)c->bw, c->geom.width); + c->geom.height = MAX(1 + 2 * (int)c->bw, c->geom.height); + } else { // 这里会限制不允许窗口划出屏幕 + client_set_bounds( + c, geo.width, + geo.height); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 + c->geom = geo; + applybounds( + c, + bbox); // 去掉这个推荐的窗口大小,因为有时推荐的窗口特别大导致平铺异常 + } - if (!c->is_open_animation) { - c->animation.begin_fade_in = false; - client_set_opacity(c, 1); - } + if (!c->is_open_animation) { + c->animation.begin_fade_in = false; + client_set_opacity(c, 1); + } - if (c->animation.action == OPEN && !c->animation.tagining && - !c->animation.tagouting && wlr_box_equal(&c->geom, &c->current)) { - c->animation.action = c->animation.action; - } else if (c->animation.tagouting) { - c->animation.duration = animation_duration_tag; - c->animation.action = TAG; - } else if (c->animation.tagining) { - c->animation.duration = animation_duration_tag; - c->animation.action = TAG; - } else if (c->is_open_animation) { - c->animation.duration = animation_duration_open; - c->animation.action = OPEN; - } else { - c->animation.duration = animation_duration_move; - c->animation.action = MOVE; - } + if (c->animation.action == OPEN && !c->animation.tagining && + !c->animation.tagouting && wlr_box_equal(&c->geom, &c->current)) { + c->animation.action = c->animation.action; + } else if (c->animation.tagouting) { + c->animation.duration = animation_duration_tag; + c->animation.action = TAG; + } else if (c->animation.tagining) { + c->animation.duration = animation_duration_tag; + c->animation.action = TAG; + } else if (c->is_open_animation) { + c->animation.duration = animation_duration_open; + c->animation.action = OPEN; + } else { + c->animation.duration = animation_duration_move; + c->animation.action = MOVE; + } - // 动画起始位置大小设置 - if (c->animation.tagouting) { - c->animainit_geom = c->animation.current; - } else if (c->animation.tagining) { - c->animainit_geom.height = c->animation.current.height; - c->animainit_geom.width = c->animation.current.width; - } else if (c->is_open_animation) { - set_open_animaiton(c, c->geom); - } else { - c->animainit_geom = c->animation.current; - } + // 动画起始位置大小设置 + if (c->animation.tagouting) { + c->animainit_geom = c->animation.current; + } else if (c->animation.tagining) { + c->animainit_geom.height = c->animation.current.height; + c->animainit_geom.width = c->animation.current.width; + } else if (c->is_open_animation) { + set_open_animaiton(c, c->geom); + } else { + c->animainit_geom = c->animation.current; + } - if (c->isnoborder || c->iskilling) { - c->bw = 0; - } + if (c->isnoborder || c->iskilling) { + c->bw = 0; + } - // c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局 - c->configure_serial = - client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); + // c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局 + c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw, + c->geom.height - 2 * c->bw); - if (c == grabc) { - c->animation.running = false; - c->need_output_flush = false; - c->animainit_geom = c->current = c->pending = c->animation.current = - c->geom; - wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); - apply_border(c, c->geom, 0, 0); - client_get_clip(c, &clip); - wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); - return; - } + if (c == grabc) { + c->animation.running = false; + c->need_output_flush = false; + c->animainit_geom = c->current = c->pending = c->animation.current = + c->geom; + wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); + apply_border(c, c->geom, 0, 0); + client_get_clip(c, &clip); + wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); + return; + } - // 如果不是工作区切换时划出去的窗口,就让动画的结束位置,就是上面的真实位置和大小 - // c->pending 决定动画的终点,一般在其他调用resize的函数的附近设置了 - if (!c->animation.tagouting && !c->iskilling) { - c->pending = c->geom; - } + // 如果不是工作区切换时划出去的窗口,就让动画的结束位置,就是上面的真实位置和大小 + // c->pending 决定动画的终点,一般在其他调用resize的函数的附近设置了 + if (!c->animation.tagouting && !c->iskilling) { + c->pending = c->geom; + } - if (c->swallowedby && c->animation.action == OPEN) { - c->animainit_geom = c->swallowedby->animation.current; - } + if (c->swallowedby && c->animation.action == OPEN) { + c->animainit_geom = c->swallowedby->animation.current; + } - if (c->swallowing) { - c->animainit_geom = c->geom; - } + if (c->swallowing) { + c->animainit_geom = c->geom; + } - if ((c->isglobal|| c->isunglobal) && c->isfloating && c->animation.action == TAG) { - c->animainit_geom = c->geom; - } + if ((c->isglobal || c->isunglobal) && c->isfloating && + c->animation.action == TAG) { + c->animainit_geom = c->geom; + } - if (c->animation_type_open && strcmp(c->animation_type_open, "none") == 0 && - c->animation.action == OPEN) { - c->animainit_geom = c->geom; - } + if (c->animation_type_open && strcmp(c->animation_type_open, "none") == 0 && + c->animation.action == OPEN) { + c->animainit_geom = c->geom; + } - // 开始应用动画设置 - client_set_pending_state(c); + // 开始应用动画设置 + client_set_pending_state(c); - setborder_color(c); + setborder_color(c); } void // 17 run(char *startup_cmd) { - char autostart_temp_path[1024]; - /* Add a Unix socket to the Wayland display. */ - const char *socket = wl_display_add_socket_auto(dpy); - if (!socket) - die("startup: display_add_socket_auto"); - setenv("WAYLAND_DISPLAY", socket, 1); + char autostart_temp_path[1024]; + /* Add a Unix socket to the Wayland display. */ + const char *socket = wl_display_add_socket_auto(dpy); + if (!socket) + die("startup: display_add_socket_auto"); + setenv("WAYLAND_DISPLAY", socket, 1); - /* Start the backend. This will enumerate outputs and inputs, become the DRM - * master, etc */ - if (!wlr_backend_start(backend)) - die("startup: backend_start"); + /* Start the backend. This will enumerate outputs and inputs, become the DRM + * master, etc */ + if (!wlr_backend_start(backend)) + die("startup: backend_start"); - /* Now that the socket exists and the backend is started, run the startup - * command */ - if (!startup_cmd) - startup_cmd = - get_autostart_path(autostart_temp_path, sizeof(autostart_temp_path)); - if (startup_cmd) { - int piperw[2]; - if (pipe(piperw) < 0) - die("startup: pipe:"); - if ((child_pid = fork()) < 0) - die("startup: fork:"); - if (child_pid == 0) { - setsid(); - dup2(piperw[0], STDIN_FILENO); - close(piperw[0]); - close(piperw[1]); - execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL); - die("startup: execl:"); - } - dup2(piperw[1], STDOUT_FILENO); - close(piperw[1]); - close(piperw[0]); - } + /* Now that the socket exists and the backend is started, run the startup + * command */ + if (!startup_cmd) + startup_cmd = get_autostart_path(autostart_temp_path, + sizeof(autostart_temp_path)); + if (startup_cmd) { + int piperw[2]; + if (pipe(piperw) < 0) + die("startup: pipe:"); + if ((child_pid = fork()) < 0) + die("startup: fork:"); + if (child_pid == 0) { + setsid(); + dup2(piperw[0], STDIN_FILENO); + close(piperw[0]); + close(piperw[1]); + execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL); + die("startup: execl:"); + } + dup2(piperw[1], STDOUT_FILENO); + close(piperw[1]); + close(piperw[0]); + } - /* Mark stdout as non-blocking to avoid people who does not close stdin - * nor consumes it in their startup script getting dwl frozen */ - if (fd_set_nonblock(STDOUT_FILENO) < 0) - close(STDOUT_FILENO); + /* Mark stdout as non-blocking to avoid people who does not close stdin + * nor consumes it in their startup script getting dwl frozen */ + if (fd_set_nonblock(STDOUT_FILENO) < 0) + close(STDOUT_FILENO); - printstatus(); + printstatus(); - /* At this point the outputs are initialized, choose initial selmon based on - * cursor position, and set default cursor image */ - selmon = xytomon(cursor->x, cursor->y); + /* At this point the outputs are initialized, choose initial selmon based on + * cursor position, and set default cursor image */ + selmon = xytomon(cursor->x, cursor->y); - /* TODO hack to get cursor to display in its initial location (100, 100) - * instead of (0, 0) and then jumping. still may not be fully - * initialized, as the image/coordinates are not transformed for the - * monitor when displayed here */ - wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y); - wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr"); - handlecursoractivity(); + /* TODO hack to get cursor to display in its initial location (100, 100) + * instead of (0, 0) and then jumping. still may not be fully + * initialized, as the image/coordinates are not transformed for the + * monitor when displayed here */ + wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y); + wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr"); + handlecursoractivity(); - run_exec(); - run_exec_once(); + run_exec(); + run_exec_once(); - /* Run the Wayland event loop. This does not return until you exit the - * compositor. Starting the backend rigged up all of the necessary event - * loop configuration to listen to libinput events, DRM events, generate - * frame events at the refresh rate, and so on. */ + /* Run the Wayland event loop. This does not return until you exit the + * compositor. Starting the backend rigged up all of the necessary event + * loop configuration to listen to libinput events, DRM events, generate + * frame events at the refresh rate, and so on. */ - wl_display_run(dpy); + wl_display_run(dpy); } void setcursor(struct wl_listener *listener, void *data) { - /* This event is raised by the seat when a client provides a cursor image */ - struct wlr_seat_pointer_request_set_cursor_event *event = data; - /* If we're "grabbing" the cursor, don't use the client's image, we will - * restore it after "grabbing" sending a leave event, followed by a enter - * event, which will result in the client requesting set the cursor surface */ - if (cursor_mode != CurNormal && cursor_mode != CurPressed) - return; - /* This can be sent by any client, so we check to make sure this one is - * actually has pointer focus first. If so, we can tell the cursor to - * use the provided surface as the cursor image. It will set the - * hardware cursor on the output that it's currently on and continue to - * do so as the cursor moves between outputs. */ - if (event->seat_client == seat->pointer_state.focused_client) { - last_cursor.shape = 0; - last_cursor.surface = event->surface; - last_cursor.hotspot_x = event->hotspot_x; - last_cursor.hotspot_y = event->hotspot_y; - if (!cursor_hidden) - wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x, - event->hotspot_y); - } + /* This event is raised by the seat when a client provides a cursor image */ + struct wlr_seat_pointer_request_set_cursor_event *event = data; + /* If we're "grabbing" the cursor, don't use the client's image, we will + * restore it after "grabbing" sending a leave event, followed by a enter + * event, which will result in the client requesting set the cursor surface + */ + if (cursor_mode != CurNormal && cursor_mode != CurPressed) + return; + /* This can be sent by any client, so we check to make sure this one is + * actually has pointer focus first. If so, we can tell the cursor to + * use the provided surface as the cursor image. It will set the + * hardware cursor on the output that it's currently on and continue to + * do so as the cursor moves between outputs. */ + if (event->seat_client == seat->pointer_state.focused_client) { + last_cursor.shape = 0; + last_cursor.surface = event->surface; + last_cursor.hotspot_x = event->hotspot_x; + last_cursor.hotspot_y = event->hotspot_y; + if (!cursor_hidden) + wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x, + event->hotspot_y); + } } void // 0.5 setfloating(Client *c, int floating) { - Client *fc; - int hit; - struct wlr_box target_box, backup_box; - c->isfloating = floating; + Client *fc; + int hit; + struct wlr_box target_box, backup_box; + c->isfloating = floating; - if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) - return; + if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) + return; - if (c->isoverlay) { - wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]); - } else { - wlr_scene_node_reparent(&c->scene->node, - layers[c->isfloating ? LyrFloat : LyrTile]); - } + if (c->isoverlay) { + wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]); + } else { + wlr_scene_node_reparent(&c->scene->node, + layers[c->isfloating ? LyrFloat : LyrTile]); + } - target_box = c->geom; + target_box = c->geom; - if (floating == 1 && c != grabc) { + if (floating == 1 && c != grabc) { - if (c->isfullscreen || c->ismaxmizescreen) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->ismaxmizescreen = 0; - c->bw = c->isnoborder ? 0 : borderpx; - } + if (c->isfullscreen || c->ismaxmizescreen) { + c->isfullscreen = 0; // 清除窗口全屏标志 + c->ismaxmizescreen = 0; + c->bw = c->isnoborder ? 0 : borderpx; + } - // 重新计算居中的坐标 - if (!client_is_x11(c) || !client_should_ignore_focus(c)) - target_box = setclient_coordinate_center(c, target_box, 0, 0); - backup_box = c->geom; - hit = applyrulesgeom(c); - target_box = hit == 1 ? c->geom : target_box; - c->geom = backup_box; + // 重新计算居中的坐标 + if (!client_is_x11(c) || !client_should_ignore_focus(c)) + target_box = setclient_coordinate_center(c, target_box, 0, 0); + backup_box = c->geom; + hit = applyrulesgeom(c); + target_box = hit == 1 ? c->geom : target_box; + c->geom = backup_box; - // restore to the memeroy geom - if (c->oldgeom.width > 0 && c->oldgeom.height > 0) { - resize(c, c->oldgeom, 0); - } else { - resize(c, target_box, 0); - } + // restore to the memeroy geom + if (c->oldgeom.width > 0 && c->oldgeom.height > 0) { + resize(c, c->oldgeom, 0); + } else { + resize(c, target_box, 0); + } - c->need_float_size_reduce = 0; - } else if (c->isfloating && c == grabc) { - c->need_float_size_reduce = 0; - } else { - c->need_float_size_reduce = 1; - c->is_scratchpad_show = 0; - c->is_in_scratchpad = 0; - c->isnamedscratchpand = 0; - // 让当前tag中的全屏窗口退出全屏参与平铺 - wl_list_for_each(fc, &clients, link) if (fc && fc != c && - c->tags & fc->tags && - ISFULLSCREEN(fc)) { - clear_fullscreen_flag(fc); - } - } + c->need_float_size_reduce = 0; + } else if (c->isfloating && c == grabc) { + c->need_float_size_reduce = 0; + } else { + c->need_float_size_reduce = 1; + c->is_scratchpad_show = 0; + c->is_in_scratchpad = 0; + c->isnamedscratchpand = 0; + // 让当前tag中的全屏窗口退出全屏参与平铺 + wl_list_for_each(fc, &clients, link) if (fc && fc != c && + c->tags & fc->tags && + ISFULLSCREEN(fc)) { + clear_fullscreen_flag(fc); + } + } - arrange(c->mon, false); - setborder_color(c); - printstatus(); + arrange(c->mon, false); + setborder_color(c); + printstatus(); } void reset_maxmizescreen_size(Client *c) { - c->geom.x = c->mon->w.x + gappov; - c->geom.y = c->mon->w.y + gappoh; - c->geom.width = c->mon->w.width - 2 * gappov; - c->geom.height = c->mon->w.height - 2 * gappov; - resize(c, c->geom, 0); + c->geom.x = c->mon->w.x + gappov; + c->geom.y = c->mon->w.y + gappoh; + c->geom.width = c->mon->w.width - 2 * gappov; + c->geom.height = c->mon->w.height - 2 * gappov; + resize(c, c->geom, 0); } void setmaxmizescreen(Client *c, int maxmizescreen) { - struct wlr_box maxmizescreen_box; - if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) - return; + struct wlr_box maxmizescreen_box; + if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) + return; - c->ismaxmizescreen = maxmizescreen; + c->ismaxmizescreen = maxmizescreen; - // c->bw = fullscreen ? 0 : borderpx; - // client_set_fullscreen(c, maxmizescreen); - wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile - : c->isfloating ? LyrFloat - : LyrTile]); + // c->bw = fullscreen ? 0 : borderpx; + // client_set_fullscreen(c, maxmizescreen); + wlr_scene_node_reparent(&c->scene->node, layers[maxmizescreen ? LyrTile + : c->isfloating ? LyrFloat + : LyrTile]); - if (maxmizescreen) { - if (c->isfloating) - c->oldgeom = c->geom; - if (selmon->isoverview) { - Arg arg = {0}; - toggleoverview(&arg); - } + if (maxmizescreen) { + if (c->isfloating) + c->oldgeom = c->geom; + if (selmon->isoverview) { + Arg arg = {0}; + toggleoverview(&arg); + } - maxmizescreen_box.x = c->mon->w.x + gappov; - maxmizescreen_box.y = c->mon->w.y + gappoh; - maxmizescreen_box.width = c->mon->w.width - 2 * gappov; - maxmizescreen_box.height = c->mon->w.height - 2 * gappov; - wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 - resize(c, maxmizescreen_box, 0); - c->ismaxmizescreen = 1; - } else { - c->bw = c->isnoborder ? 0 : borderpx; - c->ismaxmizescreen = 0; - c->isfullscreen = 0; - client_set_fullscreen(c, false); - if (c->isfloating) - setfloating(c, 1); - arrange(c->mon, false); - } + maxmizescreen_box.x = c->mon->w.x + gappov; + maxmizescreen_box.y = c->mon->w.y + gappoh; + maxmizescreen_box.width = c->mon->w.width - 2 * gappov; + maxmizescreen_box.height = c->mon->w.height - 2 * gappov; + wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 + resize(c, maxmizescreen_box, 0); + c->ismaxmizescreen = 1; + } else { + c->bw = c->isnoborder ? 0 : borderpx; + c->ismaxmizescreen = 0; + c->isfullscreen = 0; + client_set_fullscreen(c, false); + if (c->isfloating) + setfloating(c, 1); + arrange(c->mon, false); + } } void setfakefullscreen(Client *c, int fakefullscreen) { - c->isfakefullscreen = fakefullscreen; - if (!c->mon) - return; - if (c->isfullscreen) - setfullscreen(c, 0); - client_set_fullscreen(c, fakefullscreen); + c->isfakefullscreen = fakefullscreen; + if (!c->mon) + return; + if (c->isfullscreen) + setfullscreen(c, 0); + client_set_fullscreen(c, fakefullscreen); } void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带全屏 { - c->isfullscreen = fullscreen; + c->isfullscreen = fullscreen; - if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) - return; + if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) + return; - client_set_fullscreen(c, fullscreen); + client_set_fullscreen(c, fullscreen); - if (c->isoverlay) { - wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]); - } else { - wlr_scene_node_reparent(&c->scene->node, layers[fullscreen ? LyrFloat - : c->isfloating ? LyrFloat - : LyrTile]); - } + if (c->isoverlay) { + wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]); + } else { + wlr_scene_node_reparent(&c->scene->node, + layers[fullscreen ? LyrFloat + : c->isfloating ? LyrFloat + : LyrTile]); + } - if (fullscreen) { - if (c->isfloating) - c->oldgeom = c->geom; - if (selmon->isoverview) { - Arg arg = {0}; - toggleoverview(&arg); - } + if (fullscreen) { + if (c->isfloating) + c->oldgeom = c->geom; + if (selmon->isoverview) { + Arg arg = {0}; + toggleoverview(&arg); + } - c->bw = 0; - wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 - resize(c, c->mon->m, 1); - c->isfullscreen = 1; - // c->isfloating = 0; - } else { - c->bw = c->isnoborder ? 0 : borderpx; - c->isfullscreen = 0; - c->isfullscreen = 0; - c->ismaxmizescreen = 0; - if (c->isfloating) - setfloating(c, 1); - arrange(c->mon, false); - } + c->bw = 0; + wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 + resize(c, c->mon->m, 1); + c->isfullscreen = 1; + // c->isfloating = 0; + } else { + c->bw = c->isnoborder ? 0 : borderpx; + c->isfullscreen = 0; + c->isfullscreen = 0; + c->ismaxmizescreen = 0; + if (c->isfloating) + setfloating(c, 1); + arrange(c->mon, false); + } } void setgaps(int oh, int ov, int ih, int iv) { - selmon->gappoh = MAX(oh, 0); - selmon->gappov = MAX(ov, 0); - selmon->gappih = MAX(ih, 0); - selmon->gappiv = MAX(iv, 0); - arrange(selmon, false); + selmon->gappoh = MAX(oh, 0); + selmon->gappov = MAX(ov, 0); + selmon->gappih = MAX(ih, 0); + selmon->gappiv = MAX(iv, 0); + arrange(selmon, false); } 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]; + 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]; - arrange(selmon, false); - printstatus(); - return; - } - } + arrange(selmon, false); + printstatus(); + return; + } + } } void switch_layout(const Arg *arg) { - int jk, ji; - char *target_layout_name = NULL; - size_t len; + int jk, ji; + char *target_layout_name = NULL; + size_t len; - if (config.circle_layout_count != 0) { - for (jk = 0; jk < config.circle_layout_count; jk++) { + if (config.circle_layout_count != 0) { + for (jk = 0; jk < config.circle_layout_count; jk++) { - len = MAX(strlen(config.circle_layout[jk]), - strlen(selmon->pertag->ltidxs[selmon->pertag->curtag]->name)); + len = MAX( + strlen(config.circle_layout[jk]), + strlen(selmon->pertag->ltidxs[selmon->pertag->curtag]->name)); - if (strncmp(config.circle_layout[jk], - selmon->pertag->ltidxs[selmon->pertag->curtag]->name, - len) == 0) { - target_layout_name = jk == config.circle_layout_count - 1 - ? config.circle_layout[0] - : config.circle_layout[jk + 1]; - break; - } - } + if (strncmp(config.circle_layout[jk], + selmon->pertag->ltidxs[selmon->pertag->curtag]->name, + len) == 0) { + target_layout_name = jk == config.circle_layout_count - 1 + ? config.circle_layout[0] + : config.circle_layout[jk + 1]; + break; + } + } - if (!target_layout_name) { - target_layout_name = config.circle_layout[0]; - } + if (!target_layout_name) { + target_layout_name = config.circle_layout[0]; + } - for (ji = 0; ji < LENGTH(layouts); ji++) { - len = MAX(strlen(layouts[ji].name), strlen(target_layout_name)); - if (strncmp(layouts[ji].name, target_layout_name, len) == 0) { - selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[ji]; - break; - } - } + for (ji = 0; ji < LENGTH(layouts); ji++) { + len = MAX(strlen(layouts[ji].name), strlen(target_layout_name)); + if (strncmp(layouts[ji].name, target_layout_name, len) == 0) { + selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[ji]; + break; + } + } - arrange(selmon, false); - printstatus(); - return; - } + 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; - } - } + 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 */ void // 17 setmfact(const Arg *arg) { - float f; + float f; - 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; - if (f < 0.1 || f > 0.9) - return; - // selmon->mfact = f; - selmon->pertag->mfacts[selmon->pertag->curtag] = f; - arrange(selmon, false); + 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; + if (f < 0.1 || f > 0.9) + return; + // selmon->mfact = f; + selmon->pertag->mfacts[selmon->pertag->curtag] = f; + arrange(selmon, false); } void setsmfact(const Arg *arg) { - float f; + float f; - if (!arg || !selmon || - !selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange) - return; - f = arg->f < 1.0 ? arg->f + selmon->pertag->smfacts[selmon->pertag->curtag] - : arg->f - 1.0; - if (f < 0.1 || f > 0.9) - return; - // selmon->mfact = f; - selmon->pertag->smfacts[selmon->pertag->curtag] = f; - arrange(selmon, false); + if (!arg || !selmon || + !selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange) + return; + f = arg->f < 1.0 ? arg->f + selmon->pertag->smfacts[selmon->pertag->curtag] + : arg->f - 1.0; + if (f < 0.1 || f > 0.9) + return; + // selmon->mfact = f; + selmon->pertag->smfacts[selmon->pertag->curtag] = f; + arrange(selmon, false); } void setmon(Client *c, Monitor *m, uint32_t newtags, bool focus) { - Monitor *oldmon = c->mon; + Monitor *oldmon = c->mon; - if (oldmon == m) - return; + if (oldmon == m) + return; - if (oldmon && oldmon->sel == c) { - oldmon->sel = NULL; - } + if (oldmon && oldmon->sel == c) { + oldmon->sel = NULL; + } - if (oldmon && oldmon->prevsel == c) { - oldmon->prevsel = NULL; - } + if (oldmon && oldmon->prevsel == c) { + oldmon->prevsel = NULL; + } - c->mon = m; + c->mon = m; - /* Scene graph sends surface leave/enter events on move and resize */ - if (oldmon) - arrange(oldmon, false); - if (m) { - /* Make sure window actually overlaps with the monitor */ - resize(c, c->geom, 0); - c->tags = newtags - ? newtags - : m->tagset[m->seltags]; /* assign tags of target monitor */ - setfloating(c, c->isfloating); - setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ - } - if (focus) - focusclient(focustop(selmon), 1); + /* Scene graph sends surface leave/enter events on move and resize */ + if (oldmon) + arrange(oldmon, false); + if (m) { + /* Make sure window actually overlaps with the monitor */ + resize(c, c->geom, 0); + c->tags = + newtags ? newtags + : m->tagset[m->seltags]; /* assign tags of target monitor */ + setfloating(c, c->isfloating); + setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ + } + if (focus) + focusclient(focustop(selmon), 1); - if (!c->foreign_toplevel && c->mon) { - add_foreign_toplevel(c); - if (selmon->sel && selmon->sel->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_activated( - selmon->sel->foreign_toplevel, false); - if (c->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); - } + if (!c->foreign_toplevel && c->mon) { + add_foreign_toplevel(c); + if (selmon->sel && selmon->sel->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_activated( + selmon->sel->foreign_toplevel, false); + if (c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, + true); + } } void setpsel(struct wl_listener *listener, void *data) { - /* This event is raised by the seat when a client wants to set the selection, - * usually when the user copies something. wlroots allows compositors to - * ignore such requests if they so choose, but in dwl we always honor - */ - struct wlr_seat_request_set_primary_selection_event *event = data; - wlr_seat_set_primary_selection(seat, event->source, event->serial); + /* This event is raised by the seat when a client wants to set the + * selection, usually when the user copies something. wlroots allows + * compositors to ignore such requests if they so choose, but in dwl we + * always honor + */ + struct wlr_seat_request_set_primary_selection_event *event = data; + wlr_seat_set_primary_selection(seat, event->source, event->serial); } void setsel(struct wl_listener *listener, void *data) { - /* This event is raised by the seat when a client wants to set the selection, - * usually when the user copies something. wlroots allows compositors to - * ignore such requests if they so choose, but in dwl we always honor - */ - struct wlr_seat_request_set_selection_event *event = data; - wlr_seat_set_selection(seat, event->source, event->serial); + /* This event is raised by the seat when a client wants to set the + * selection, usually when the user copies something. wlroots allows + * compositors to ignore such requests if they so choose, but in dwl we + * always honor + */ + struct wlr_seat_request_set_selection_event *event = data; + wlr_seat_set_selection(seat, event->source, event->serial); } // 获取tags中最前面的tag的tagmask unsigned int get_tags_first_tag(unsigned int source_tags) { - unsigned int i, tag; - tag = 0; + unsigned int i, tag; + tag = 0; - if (!source_tags) { - return selmon->pertag->curtag; - } + if (!source_tags) { + return selmon->pertag->curtag; + } - for (i = 0; !(tag & 1) && source_tags != 0 && i < LENGTH(tags); i++) { - tag = source_tags >> i; - } + for (i = 0; !(tag & 1) && source_tags != 0 && i < LENGTH(tags); i++) { + tag = source_tags >> i; + } - if (i == 1) { - return 1; - } else if (i > 9) { - return 1 << 8; - } else { - return 1 << (i - 1); - } + if (i == 1) { + return 1; + } else if (i > 9) { + return 1 << 8; + } else { + return 1 << (i - 1); + } } void show_hide_client(Client *c) { - unsigned int target = get_tags_first_tag(c->oldtags); - tag_client(&(Arg){.ui = target}, c); - // c->tags = c->oldtags; - c->isminied = 0; - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); - focusclient(c, 1); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); + unsigned int target = get_tags_first_tag(c->oldtags); + tag_client(&(Arg){.ui = target}, c); + // c->tags = c->oldtags; + c->isminied = 0; + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); + focusclient(c, 1); + 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; + Client *c = wl_container_of(listener, c, foreign_activate_request); + unsigned int target; - if (c && c->swallowing) - return; + if (c && c->swallowing) + return; - if (c && !c->isminied && c == selmon->sel) { - set_minized(c); - 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; - } + 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); + 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 *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); - } + 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); - } + 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) { - return; - } + bool *done = data; + if (*done) { + return; + } - if (wlr_backend_is_wl(backend)) { - wlr_wl_output_create(backend); - *done = true; - } else if (wlr_backend_is_headless(backend)) { - wlr_headless_add_output(backend, 1920, 1080); - *done = true; - } + if (wlr_backend_is_wl(backend)) { + wlr_wl_output_create(backend); + *done = true; + } else if (wlr_backend_is_headless(backend)) { + wlr_headless_add_output(backend, 1920, 1080); + *done = true; + } #if WLR_HAS_X11_BACKEND - else if (wlr_backend_is_x11(backend)) { - wlr_x11_output_create(backend); - *done = true; - } + else if (wlr_backend_is_x11(backend)) { + wlr_x11_output_create(backend); + *done = true; + } #endif } @@ -5896,1823 +5978,1837 @@ void create_output(struct wlr_backend *backend, void *data) { */ void create_virtual_output(const Arg *arg) { - if (!wlr_backend_is_multi(backend)) { - wlr_log(WLR_ERROR, "Expected a multi backend"); - return; - } + if (!wlr_backend_is_multi(backend)) { + wlr_log(WLR_ERROR, "Expected a multi backend"); + return; + } - bool done = false; - wlr_multi_for_each_backend(backend, create_output, &done); + bool done = false; + wlr_multi_for_each_backend(backend, create_output, &done); - if (!done) { - wlr_log(WLR_ERROR, "Failed to create virtual output"); - return; - } + if (!done) { + wlr_log(WLR_ERROR, "Failed to create virtual output"); + return; + } - wlr_log(WLR_INFO, "Virtual output created"); - return; + wlr_log(WLR_INFO, "Virtual output created"); + return; } void destroy_all_virtual_output(const Arg *arg) { - if (!wlr_backend_is_multi(backend)) { - wlr_log(WLR_ERROR, "Expected a multi backend"); - return; - } + if (!wlr_backend_is_multi(backend)) { + wlr_log(WLR_ERROR, "Expected a multi backend"); + return; + } - Monitor *m, *tmp; - wl_list_for_each_safe(m, tmp, &mons, link) { - if (wlr_output_is_headless(m->wlr_output)) { - // if(selmon == m) - // selmon = NULL; - wlr_output_destroy(m->wlr_output); - wlr_log(WLR_INFO, "Virtual output destroyed"); - } - } + Monitor *m, *tmp; + wl_list_for_each_safe(m, tmp, &mons, link) { + if (wlr_output_is_headless(m->wlr_output)) { + // if(selmon == m) + // selmon = NULL; + wlr_output_destroy(m->wlr_output); + wlr_log(WLR_INFO, "Virtual output destroyed"); + } + } } void setup(void) { - setenv("XCURSOR_SIZE", "24", 1); - setenv("XDG_CURRENT_DESKTOP", "maomao", 1); + setenv("XCURSOR_SIZE", "24", 1); + setenv("XDG_CURRENT_DESKTOP", "maomao", 1); - parse_config(); - init_baked_points(); + parse_config(); + init_baked_points(); - int drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; - struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; - sigemptyset(&sa.sa_mask); + int drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; + struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; + sigemptyset(&sa.sa_mask); - for (i = 0; i < LENGTH(sig); i++) - sigaction(sig[i], &sa, NULL); + for (i = 0; i < LENGTH(sig); i++) + sigaction(sig[i], &sa, NULL); - wlr_log_init(log_level, NULL); + wlr_log_init(log_level, NULL); - /* The Wayland display is managed by libwayland. It handles accepting - * clients from the Unix socket, manging Wayland globals, and so on. */ - dpy = wl_display_create(); - event_loop = wl_display_get_event_loop(dpy); - pointer_manager = wlr_relative_pointer_manager_v1_create(dpy); - /* The backend is a wlroots feature which abstracts the underlying input and - * output hardware. The autocreate option will choose the most suitable - * backend based on the current environment, such as opening an X11 window - * if an X11 server is running. The NULL argument here optionally allows you - * to pass in a custom renderer if wlr_renderer doesn't meet your needs. The - * backend uses the renderer, for example, to fall back to software cursors - * if the backend does not support hardware cursors (some older GPUs - * don't). */ - if (!(backend = wlr_backend_autocreate(event_loop, &session))) - die("couldn't create backend"); + /* The Wayland display is managed by libwayland. It handles accepting + * clients from the Unix socket, manging Wayland globals, and so on. */ + dpy = wl_display_create(); + event_loop = wl_display_get_event_loop(dpy); + pointer_manager = wlr_relative_pointer_manager_v1_create(dpy); + /* The backend is a wlroots feature which abstracts the underlying input and + * output hardware. The autocreate option will choose the most suitable + * backend based on the current environment, such as opening an X11 window + * if an X11 server is running. The NULL argument here optionally allows you + * to pass in a custom renderer if wlr_renderer doesn't meet your needs. The + * backend uses the renderer, for example, to fall back to software cursors + * if the backend does not support hardware cursors (some older GPUs + * don't). */ + if (!(backend = wlr_backend_autocreate(event_loop, &session))) + die("couldn't create backend"); - headless_backend = wlr_headless_backend_create(event_loop); - if (!headless_backend) { - wlr_log(WLR_ERROR, "Failed to create secondary headless backend"); - } else { - wlr_multi_backend_add(backend, headless_backend); - } + headless_backend = wlr_headless_backend_create(event_loop); + if (!headless_backend) { + wlr_log(WLR_ERROR, "Failed to create secondary headless backend"); + } else { + wlr_multi_backend_add(backend, headless_backend); + } - /* Initialize the scene graph used to lay out windows */ - scene = wlr_scene_create(); - root_bg = wlr_scene_rect_create(&scene->tree, 0, 0, rootcolor); - for (i = 0; i < NUM_LAYERS; i++) - layers[i] = wlr_scene_tree_create(&scene->tree); - drag_icon = wlr_scene_tree_create(&scene->tree); - wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node); + /* Initialize the scene graph used to lay out windows */ + scene = wlr_scene_create(); + root_bg = wlr_scene_rect_create(&scene->tree, 0, 0, rootcolor); + for (i = 0; i < NUM_LAYERS; i++) + layers[i] = wlr_scene_tree_create(&scene->tree); + drag_icon = wlr_scene_tree_create(&scene->tree); + wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node); - /* Create a renderer with the default implementation */ - if (!(drw = wlr_renderer_autocreate(backend))) - die("couldn't create renderer"); + /* Create a renderer with the default implementation */ + if (!(drw = wlr_renderer_autocreate(backend))) + die("couldn't create renderer"); - wl_signal_add(&drw->events.lost, &gpu_reset); + wl_signal_add(&drw->events.lost, &gpu_reset); - /* Create shm, drm and linux_dmabuf interfaces by ourselves. - * The simplest way is call: - * wlr_renderer_init_wl_display(drw); - * but we need to create manually the linux_dmabuf interface to integrate it - * with wlr_scene. */ - wlr_renderer_init_wl_shm(drw, dpy); + /* Create shm, drm and linux_dmabuf interfaces by ourselves. + * The simplest way is call: + * wlr_renderer_init_wl_display(drw); + * but we need to create manually the linux_dmabuf interface to integrate it + * with wlr_scene. */ + wlr_renderer_init_wl_shm(drw, dpy); - if (wlr_renderer_get_texture_formats(drw, WLR_BUFFER_CAP_DMABUF)) { - wlr_drm_create(dpy, drw); - wlr_scene_set_linux_dmabuf_v1( - scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); - } + if (wlr_renderer_get_texture_formats(drw, WLR_BUFFER_CAP_DMABUF)) { + wlr_drm_create(dpy, drw); + wlr_scene_set_linux_dmabuf_v1( + scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); + } - if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && drw->features.timeline && - backend->features.timeline) - wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd); + if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && + drw->features.timeline && backend->features.timeline) + wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd); - /* Create a default allocator */ - if (!(alloc = wlr_allocator_autocreate(backend, drw))) - die("couldn't create allocator"); + /* Create a default allocator */ + if (!(alloc = wlr_allocator_autocreate(backend, drw))) + die("couldn't create allocator"); - /* This creates some hands-off wlroots interfaces. The compositor is - * necessary for clients to allocate surfaces and the data device manager - * handles the clipboard. Each of these wlroots interfaces has room for you - * to dig your fingers in and play with their behavior if you want. Note that - * the clients cannot set the selection directly without compositor approval, - * see the setsel() function. */ - compositor = wlr_compositor_create(dpy, 6, drw); - wlr_export_dmabuf_manager_v1_create(dpy); - wlr_screencopy_manager_v1_create(dpy); + /* This creates some hands-off wlroots interfaces. The compositor is + * necessary for clients to allocate surfaces and the data device manager + * handles the clipboard. Each of these wlroots interfaces has room for you + * to dig your fingers in and play with their behavior if you want. Note + * that the clients cannot set the selection directly without compositor + * approval, see the setsel() function. */ + compositor = wlr_compositor_create(dpy, 6, drw); + wlr_export_dmabuf_manager_v1_create(dpy); + wlr_screencopy_manager_v1_create(dpy); wlr_ext_image_copy_capture_manager_v1_create(dpy, 1); wlr_ext_output_image_capture_source_manager_v1_create(dpy, 1); - wlr_data_control_manager_v1_create(dpy); - wlr_data_device_manager_create(dpy); - wlr_primary_selection_v1_device_manager_create(dpy); - wlr_viewporter_create(dpy); - wlr_single_pixel_buffer_manager_v1_create(dpy); - wlr_fractional_scale_manager_v1_create(dpy, 1); - wlr_presentation_create(dpy, backend, 2); - wlr_subcompositor_create(dpy); - wlr_alpha_modifier_v1_create(dpy); + wlr_data_control_manager_v1_create(dpy); + wlr_data_device_manager_create(dpy); + wlr_primary_selection_v1_device_manager_create(dpy); + wlr_viewporter_create(dpy); + wlr_single_pixel_buffer_manager_v1_create(dpy); + wlr_fractional_scale_manager_v1_create(dpy, 1); + wlr_presentation_create(dpy, backend, 2); + wlr_subcompositor_create(dpy); + wlr_alpha_modifier_v1_create(dpy); - /* Initializes the interface used to implement urgency hints */ - activation = wlr_xdg_activation_v1_create(dpy); - wl_signal_add(&activation->events.request_activate, &request_activate); + /* Initializes the interface used to implement urgency hints */ + activation = wlr_xdg_activation_v1_create(dpy); + wl_signal_add(&activation->events.request_activate, &request_activate); - wlr_scene_set_gamma_control_manager_v1( - scene, wlr_gamma_control_manager_v1_create(dpy)); + wlr_scene_set_gamma_control_manager_v1( + scene, wlr_gamma_control_manager_v1_create(dpy)); - power_mgr = wlr_output_power_manager_v1_create(dpy); - wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode); + power_mgr = wlr_output_power_manager_v1_create(dpy); + wl_signal_add(&power_mgr->events.set_mode, &output_power_mgr_set_mode); - /* Creates an output layout, which a wlroots utility for working with an - * arrangement of screens in a physical layout. */ - output_layout = wlr_output_layout_create(dpy); - wl_signal_add(&output_layout->events.change, &layout_change); - wlr_xdg_output_manager_v1_create(dpy, output_layout); + /* Creates an output layout, which a wlroots utility for working with an + * arrangement of screens in a physical layout. */ + output_layout = wlr_output_layout_create(dpy); + wl_signal_add(&output_layout->events.change, &layout_change); + wlr_xdg_output_manager_v1_create(dpy, output_layout); - /* Configure a listener to be notified when new outputs are available on the - * backend. */ - wl_list_init(&mons); - wl_signal_add(&backend->events.new_output, &new_output); + /* Configure a listener to be notified when new outputs are available on the + * backend. */ + wl_list_init(&mons); + wl_signal_add(&backend->events.new_output, &new_output); - /* Set up our client lists and the xdg-shell. The xdg-shell is a - * Wayland protocol which is used for application windows. For more - * detail on shells, refer to the article: - * - * https://drewdevault.com/2018/07/29/Wayland-shells.html - */ - wl_list_init(&clients); - wl_list_init(&fstack); - wl_list_init(&fadeout_clients); + /* Set up our client lists and the xdg-shell. The xdg-shell is a + * Wayland protocol which is used for application windows. For more + * detail on shells, refer to the article: + * + * https://drewdevault.com/2018/07/29/Wayland-shells.html + */ + wl_list_init(&clients); + wl_list_init(&fstack); + wl_list_init(&fadeout_clients); - idle_notifier = wlr_idle_notifier_v1_create(dpy); + idle_notifier = wlr_idle_notifier_v1_create(dpy); - idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy); - wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &new_idle_inhibitor); + idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy); + wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &new_idle_inhibitor); - layer_shell = wlr_layer_shell_v1_create(dpy, 4); - wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface); + layer_shell = wlr_layer_shell_v1_create(dpy, 4); + wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface); - xdg_shell = wlr_xdg_shell_create(dpy, 6); - wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel); - wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup); + xdg_shell = wlr_xdg_shell_create(dpy, 6); + wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel); + wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup); - session_lock_mgr = wlr_session_lock_manager_v1_create(dpy); - wl_signal_add(&session_lock_mgr->events.new_lock, &new_session_lock); + session_lock_mgr = wlr_session_lock_manager_v1_create(dpy); + wl_signal_add(&session_lock_mgr->events.new_lock, &new_session_lock); - locked_bg = wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, - (float[4]){0.1, 0.1, 0.1, 1.0}); - wlr_scene_node_set_enabled(&locked_bg->node, false); + locked_bg = + wlr_scene_rect_create(layers[LyrBlock], sgeom.width, sgeom.height, + (float[4]){0.1, 0.1, 0.1, 1.0}); + wlr_scene_node_set_enabled(&locked_bg->node, false); - /* Use decoration protocols to negotiate server-side decorations */ - wlr_server_decoration_manager_set_default_mode( - wlr_server_decoration_manager_create(dpy), - WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); - xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy); - wl_signal_add(&xdg_decoration_mgr->events.new_toplevel_decoration, - &new_xdg_decoration); + /* Use decoration protocols to negotiate server-side decorations */ + wlr_server_decoration_manager_set_default_mode( + wlr_server_decoration_manager_create(dpy), + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(dpy); + wl_signal_add(&xdg_decoration_mgr->events.new_toplevel_decoration, + &new_xdg_decoration); - pointer_constraints = wlr_pointer_constraints_v1_create(dpy); - wl_signal_add(&pointer_constraints->events.new_constraint, - &new_pointer_constraint); + pointer_constraints = wlr_pointer_constraints_v1_create(dpy); + wl_signal_add(&pointer_constraints->events.new_constraint, + &new_pointer_constraint); - relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy); + relative_pointer_mgr = wlr_relative_pointer_manager_v1_create(dpy); - /* - * Creates a cursor, which is a wlroots utility for tracking the cursor - * image shown on screen. - */ - cursor = wlr_cursor_create(); - wlr_cursor_attach_output_layout(cursor, output_layout); + /* + * Creates a cursor, which is a wlroots utility for tracking the cursor + * image shown on screen. + */ + cursor = wlr_cursor_create(); + wlr_cursor_attach_output_layout(cursor, output_layout); - /* Creates an xcursor manager, another wlroots utility which loads up - * Xcursor themes to source cursor images from and makes sure that cursor - * images are available at all scale factors on the screen (necessary for - * HiDPI support). Scaled cursors will be loaded with each output. */ - // cursor_mgr = wlr_xcursor_manager_create(cursor_theme, 24); - cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size); + /* Creates an xcursor manager, another wlroots utility which loads up + * Xcursor themes to source cursor images from and makes sure that cursor + * images are available at all scale factors on the screen (necessary for + * HiDPI support). Scaled cursors will be loaded with each output. */ + // cursor_mgr = wlr_xcursor_manager_create(cursor_theme, 24); + cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size); - /* - * wlr_cursor *only* displays an image on screen. It does not move around - * when the pointer moves. However, we can attach input devices to it, and - * it will generate aggregate events for all of them. In these events, we - * can choose how we want to process them, forwarding them to clients and - * moving the cursor around. More detail on this process is described in my - * input handling blog post: - * - * https://drewdevault.com/2018/07/17/Input-handling-in-wlroots.html - * - * And more comments are sprinkled throughout the notify functions above. - */ - wl_signal_add(&cursor->events.motion, &cursor_motion); - wl_signal_add(&cursor->events.motion_absolute, &cursor_motion_absolute); - wl_signal_add(&cursor->events.button, &cursor_button); - wl_signal_add(&cursor->events.axis, &cursor_axis); - wl_signal_add(&cursor->events.frame, &cursor_frame); + /* + * wlr_cursor *only* displays an image on screen. It does not move around + * when the pointer moves. However, we can attach input devices to it, and + * it will generate aggregate events for all of them. In these events, we + * can choose how we want to process them, forwarding them to clients and + * moving the cursor around. More detail on this process is described in my + * input handling blog post: + * + * https://drewdevault.com/2018/07/17/Input-handling-in-wlroots.html + * + * And more comments are sprinkled throughout the notify functions above. + */ + wl_signal_add(&cursor->events.motion, &cursor_motion); + wl_signal_add(&cursor->events.motion_absolute, &cursor_motion_absolute); + wl_signal_add(&cursor->events.button, &cursor_button); + wl_signal_add(&cursor->events.axis, &cursor_axis); + wl_signal_add(&cursor->events.frame, &cursor_frame); - // 这两句代码会造成obs窗口里的鼠标光标消失,不知道注释有什么影响 - cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1); - wl_signal_add(&cursor_shape_mgr->events.request_set_shape, - &request_set_cursor_shape); - hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy), - hidecursor, cursor); + // 这两句代码会造成obs窗口里的鼠标光标消失,不知道注释有什么影响 + cursor_shape_mgr = wlr_cursor_shape_manager_v1_create(dpy, 1); + wl_signal_add(&cursor_shape_mgr->events.request_set_shape, + &request_set_cursor_shape); + hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy), + hidecursor, cursor); - /* - * Configures a seat, which is a single "seat" at which a user sits and - * operates the computer. This conceptually includes up to one keyboard, - * pointer, touch, and drawing tablet device. We also rig up a listener to - * let us know when new input devices are available on the backend. - */ - wl_list_init(&keyboards); - wl_signal_add(&backend->events.new_input, &new_input_device); - virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); - wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard, - &new_virtual_keyboard); - virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy); - wl_signal_add(&virtual_pointer_mgr->events.new_virtual_pointer, - &new_virtual_pointer); + /* + * Configures a seat, which is a single "seat" at which a user sits and + * operates the computer. This conceptually includes up to one keyboard, + * pointer, touch, and drawing tablet device. We also rig up a listener to + * let us know when new input devices are available on the backend. + */ + wl_list_init(&keyboards); + wl_signal_add(&backend->events.new_input, &new_input_device); + virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); + wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard, + &new_virtual_keyboard); + virtual_pointer_mgr = wlr_virtual_pointer_manager_v1_create(dpy); + wl_signal_add(&virtual_pointer_mgr->events.new_virtual_pointer, + &new_virtual_pointer); - pointer_gestures = wlr_pointer_gestures_v1_create(dpy); - LISTEN_STATIC(&cursor->events.swipe_begin, swipe_begin); - LISTEN_STATIC(&cursor->events.swipe_update, swipe_update); - LISTEN_STATIC(&cursor->events.swipe_end, swipe_end); - LISTEN_STATIC(&cursor->events.pinch_begin, pinch_begin); - LISTEN_STATIC(&cursor->events.pinch_update, pinch_update); - LISTEN_STATIC(&cursor->events.pinch_end, pinch_end); - LISTEN_STATIC(&cursor->events.hold_begin, hold_begin); - LISTEN_STATIC(&cursor->events.hold_end, hold_end); + pointer_gestures = wlr_pointer_gestures_v1_create(dpy); + LISTEN_STATIC(&cursor->events.swipe_begin, swipe_begin); + LISTEN_STATIC(&cursor->events.swipe_update, swipe_update); + LISTEN_STATIC(&cursor->events.swipe_end, swipe_end); + LISTEN_STATIC(&cursor->events.pinch_begin, pinch_begin); + LISTEN_STATIC(&cursor->events.pinch_update, pinch_update); + LISTEN_STATIC(&cursor->events.pinch_end, pinch_end); + LISTEN_STATIC(&cursor->events.hold_begin, hold_begin); + LISTEN_STATIC(&cursor->events.hold_end, hold_end); - seat = wlr_seat_create(dpy, "seat0"); - wl_signal_add(&seat->events.request_set_cursor, &request_cursor); - wl_signal_add(&seat->events.request_set_selection, &request_set_sel); - wl_signal_add(&seat->events.request_set_primary_selection, &request_set_psel); - wl_signal_add(&seat->events.request_start_drag, &request_start_drag); - wl_signal_add(&seat->events.start_drag, &start_drag); + seat = wlr_seat_create(dpy, "seat0"); + wl_signal_add(&seat->events.request_set_cursor, &request_cursor); + wl_signal_add(&seat->events.request_set_selection, &request_set_sel); + wl_signal_add(&seat->events.request_set_primary_selection, + &request_set_psel); + wl_signal_add(&seat->events.request_start_drag, &request_start_drag); + wl_signal_add(&seat->events.start_drag, &start_drag); - kb_group = createkeyboardgroup(); - wl_list_init(&kb_group->destroy.link); + kb_group = createkeyboardgroup(); + wl_list_init(&kb_group->destroy.link); - output_mgr = wlr_output_manager_v1_create(dpy); - wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); - wl_signal_add(&output_mgr->events.test, &output_mgr_test); + output_mgr = wlr_output_manager_v1_create(dpy); + wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); + wl_signal_add(&output_mgr->events.test, &output_mgr_test); - /* create text_input-, and input_method-protocol relevant globals */ - input_method_manager = wlr_input_method_manager_v2_create(dpy); - text_input_manager = wlr_text_input_manager_v3_create(dpy); + /* create text_input-, and input_method-protocol relevant globals */ + input_method_manager = wlr_input_method_manager_v2_create(dpy); + text_input_manager = wlr_text_input_manager_v3_create(dpy); - input_method_relay = calloc(1, sizeof(*input_method_relay)); - input_method_relay = input_method_relay_create(); + input_method_relay = calloc(1, sizeof(*input_method_relay)); + input_method_relay = input_method_relay_create(); - wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL, - dwl_ipc_manager_bind); + wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL, + dwl_ipc_manager_bind); - // 创建顶层管理句柄 - foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(dpy); - struct wlr_xdg_foreign_registry *foreign_registry = - wlr_xdg_foreign_registry_create(dpy); - wlr_xdg_foreign_v1_create(dpy, foreign_registry); - wlr_xdg_foreign_v2_create(dpy, foreign_registry); + // 创建顶层管理句柄 + foreign_toplevel_manager = wlr_foreign_toplevel_manager_v1_create(dpy); + struct wlr_xdg_foreign_registry *foreign_registry = + wlr_xdg_foreign_registry_create(dpy); + wlr_xdg_foreign_v1_create(dpy, foreign_registry); + wlr_xdg_foreign_v2_create(dpy, foreign_registry); #ifdef XWAYLAND - /* - * Initialise the XWayland X server. - * It will be started when the first X client is started. - */ - xwayland = wlr_xwayland_create(dpy, compositor, !xwayland_persistence); - if (xwayland) { - wl_signal_add(&xwayland->events.ready, &xwayland_ready); - wl_signal_add(&xwayland->events.new_surface, &new_xwayland_surface); + /* + * Initialise the XWayland X server. + * It will be started when the first X client is started. + */ + xwayland = wlr_xwayland_create(dpy, compositor, !xwayland_persistence); + if (xwayland) { + wl_signal_add(&xwayland->events.ready, &xwayland_ready); + wl_signal_add(&xwayland->events.new_surface, &new_xwayland_surface); - setenv("DISPLAY", xwayland->display_name, 1); - } else { - fprintf(stderr, - "failed to setup XWayland X server, continuing without it\n"); - } + setenv("DISPLAY", xwayland->display_name, 1); + } else { + fprintf(stderr, + "failed to setup XWayland X server, continuing without it\n"); + } #endif } void spawn(const Arg *arg) { - if (!arg->v) - return; + if (!arg->v) + return; - if (fork() == 0) { - // 1. 忽略可能导致 coredump 的信号 - signal(SIGSEGV, SIG_IGN); - signal(SIGABRT, SIG_IGN); - signal(SIGILL, SIG_IGN); + if (fork() == 0) { + // 1. 忽略可能导致 coredump 的信号 + signal(SIGSEGV, SIG_IGN); + signal(SIGABRT, SIG_IGN); + signal(SIGILL, SIG_IGN); - dup2(STDERR_FILENO, STDOUT_FILENO); - setsid(); + dup2(STDERR_FILENO, STDOUT_FILENO); + setsid(); - // 2. 解析参数 - char *argv[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 = strtok(NULL, " "); - } - argv[argc] = NULL; + // 2. 解析参数 + char *argv[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 = strtok(NULL, " "); + } + argv[argc] = NULL; - // 3. 执行命令 - execvp(argv[0], argv); + // 3. 执行命令 + execvp(argv[0], argv); - // 4. execvp 失败时:打印错误并直接退出(避免 coredump) - wlr_log(WLR_ERROR, "dwl: execvp '%s' failed: %s\n", argv[0], - strerror(errno)); - _exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作 - } + // 4. execvp 失败时:打印错误并直接退出(避免 coredump) + wlr_log(WLR_ERROR, "dwl: execvp '%s' failed: %s\n", argv[0], + strerror(errno)); + _exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作 + } } void spawn_on_empty(const Arg *arg) { - bool is_empty = true; - Client *c; + bool is_empty = true; + Client *c; - wl_list_for_each(c, &clients, link) { - if (arg->ui & c->tags && c->mon == selmon) { - is_empty = false; - break; - } - } - if (!is_empty) { - view(arg, true); - return; - } else { - view(arg, true); - spawn(arg); - } + wl_list_for_each(c, &clients, link) { + if (arg->ui & c->tags && c->mon == selmon) { + is_empty = false; + break; + } + } + if (!is_empty) { + view(arg, true); + return; + } else { + view(arg, true); + spawn(arg); + } } void startdrag(struct wl_listener *listener, void *data) { - struct wlr_drag *drag = data; - if (!drag->icon) - return; + struct wlr_drag *drag = data; + if (!drag->icon) + return; - drag->icon->data = &wlr_scene_drag_icon_create(drag_icon, drag->icon)->node; - LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon); + drag->icon->data = &wlr_scene_drag_icon_create(drag_icon, drag->icon)->node; + LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon); } void tag_client(const Arg *arg, Client *target_client) { - Client *fc; - if (target_client && arg->ui & TAGMASK) { - target_client->tags = arg->ui & TAGMASK; - wl_list_for_each(fc, &clients, link) { - if (fc && fc != target_client && target_client->tags & fc->tags && - ISFULLSCREEN(fc) && !target_client->isfloating) { - clear_fullscreen_flag(fc); - } - } - view(&(Arg){.ui = arg->ui}, false); + Client *fc; + if (target_client && arg->ui & TAGMASK) { + target_client->tags = arg->ui & TAGMASK; + wl_list_for_each(fc, &clients, link) { + if (fc && fc != target_client && target_client->tags & fc->tags && + ISFULLSCREEN(fc) && !target_client->isfloating) { + clear_fullscreen_flag(fc); + } + } + view(&(Arg){.ui = arg->ui}, false); - } else { - view(arg, false); - } + } else { + view(arg, false); + } - focusclient(target_client, 1); - printstatus(); + focusclient(target_client, 1); + printstatus(); } void tag(const Arg *arg) { - Client *target_client = selmon->sel; - tag_client(arg, target_client); + Client *target_client = selmon->sel; + tag_client(arg, target_client); } void tagsilent(const Arg *arg) { - Client *fc; - Client *target_client = selmon->sel; - target_client->tags = arg->ui & TAGMASK; - wl_list_for_each(fc, &clients, link) { - if (fc && fc != target_client && target_client->tags & fc->tags && - ISFULLSCREEN(fc) && !target_client->isfloating) { - clear_fullscreen_flag(fc); - } - } - focusclient(focustop(selmon), 1); - arrange(target_client->mon, false); + Client *fc; + Client *target_client = selmon->sel; + target_client->tags = arg->ui & TAGMASK; + wl_list_for_each(fc, &clients, link) { + if (fc && fc != target_client && target_client->tags & fc->tags && + ISFULLSCREEN(fc) && !target_client->isfloating) { + clear_fullscreen_flag(fc); + } + } + focusclient(focustop(selmon), 1); + arrange(target_client->mon, false); } void tagmon(const Arg *arg) { - Client *c = focustop(selmon); - Monitor *m; - if (c) { - if (c == selmon->sel) { - selmon->sel = NULL; - } - m = dirtomon(arg->i); - setmon(c, m, 0, true); - reset_foreign_tolevel(c); - // 重新计算居中的坐标 - if (c->isfloating) { - c->geom.width = (int)(c->geom.width * c->mon->w.width / selmon->w.width); - c->geom.height = - (int)(c->geom.height * c->mon->w.height / selmon->w.height); - selmon = c->mon; - c->geom = setclient_coordinate_center(c, c->geom, 0, 0); - focusclient(c, 1); - c->oldgeom = c->geom; - resize(c, c->geom, 1); - } else { - selmon = c->mon; - focusclient(c, 1); - arrange(selmon, false); - } - warp_cursor_to_selmon(c->mon); - } + Client *c = focustop(selmon); + Monitor *m; + if (c) { + if (c == selmon->sel) { + selmon->sel = NULL; + } + m = dirtomon(arg->i); + setmon(c, m, 0, true); + reset_foreign_tolevel(c); + // 重新计算居中的坐标 + if (c->isfloating) { + c->geom.width = + (int)(c->geom.width * c->mon->w.width / selmon->w.width); + c->geom.height = + (int)(c->geom.height * c->mon->w.height / selmon->w.height); + selmon = c->mon; + c->geom = setclient_coordinate_center(c, c->geom, 0, 0); + focusclient(c, 1); + c->oldgeom = c->geom; + resize(c, c->geom, 1); + } else { + selmon = c->mon; + focusclient(c, 1); + arrange(selmon, false); + } + warp_cursor_to_selmon(c->mon); + } } void overview(Monitor *m) { grid(m); } // 目标窗口有其他窗口和它同个tag就返回0 unsigned int want_restore_fullscreen(Client *target_client) { - Client *c = NULL; - wl_list_for_each(c, &clients, link) { - if (c && c != target_client && c->tags == target_client->tags && - c == selmon->sel) { - return 0; - } - } + Client *c = NULL; + wl_list_for_each(c, &clients, link) { + if (c && c != target_client && c->tags == target_client->tags && + c == selmon->sel) { + return 0; + } + } - return 1; + return 1; } // 普通视图切换到overview时保存窗口的旧状态 void overview_backup(Client *c) { - c->overview_isfloatingbak = c->isfloating; - c->overview_isfullscreenbak = c->isfullscreen; - c->overview_ismaxmizescreenbak = c->ismaxmizescreen; - c->overview_isfullscreenbak = c->isfullscreen; - c->animation.tagining = false; - c->animation.tagouted = false; - c->animation.tagouting = false; - c->overview_backup_geom = c->geom; - c->overview_backup_bw = c->bw; - if (c->isfloating) { - c->isfloating = 0; - } - if (c->isfullscreen || c->ismaxmizescreen) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->ismaxmizescreen = 0; - } - c->bw = c->isnoborder ? 0 : borderpx; + c->overview_isfloatingbak = c->isfloating; + c->overview_isfullscreenbak = c->isfullscreen; + c->overview_ismaxmizescreenbak = c->ismaxmizescreen; + c->overview_isfullscreenbak = c->isfullscreen; + c->animation.tagining = false; + c->animation.tagouted = false; + c->animation.tagouting = false; + c->overview_backup_geom = c->geom; + c->overview_backup_bw = c->bw; + if (c->isfloating) { + c->isfloating = 0; + } + if (c->isfullscreen || c->ismaxmizescreen) { + c->isfullscreen = 0; // 清除窗口全屏标志 + c->ismaxmizescreen = 0; + } + c->bw = c->isnoborder ? 0 : borderpx; } // overview切回到普通视图还原窗口的状态 void overview_restore(Client *c, const Arg *arg) { - c->isfloating = c->overview_isfloatingbak; - c->isfullscreen = c->overview_isfullscreenbak; - c->ismaxmizescreen = c->overview_ismaxmizescreenbak; - c->overview_isfloatingbak = 0; - c->overview_isfullscreenbak = 0; - c->overview_ismaxmizescreenbak = 0; - c->geom = c->overview_backup_geom; - c->bw = c->overview_backup_bw; - c->animation.tagining = false; - c->is_restoring_from_ov = (arg->ui & c->tags & TAGMASK) == 0 ? true : false; + c->isfloating = c->overview_isfloatingbak; + c->isfullscreen = c->overview_isfullscreenbak; + c->ismaxmizescreen = c->overview_ismaxmizescreenbak; + c->overview_isfloatingbak = 0; + c->overview_isfullscreenbak = 0; + c->overview_ismaxmizescreenbak = 0; + c->geom = c->overview_backup_geom; + c->bw = c->overview_backup_bw; + c->animation.tagining = false; + c->is_restoring_from_ov = (arg->ui & c->tags & TAGMASK) == 0 ? true : false; - if (c->isfloating) { - // XRaiseWindow(dpy, c->win); // 提升悬浮窗口到顶层 - resize(c, c->overview_backup_geom, 0); - } else if (c->isfullscreen || c->ismaxmizescreen) { - if (want_restore_fullscreen( - c)) { // 如果同tag有其他窗口,且其他窗口是将要聚焦的,那么不恢复该窗口的全屏状态 - resize(c, c->overview_backup_geom, 0); - } else { - c->isfullscreen = 0; - c->ismaxmizescreen = 0; - setfullscreen(c, false); - } - } else { - if (c->is_restoring_from_ov) { - c->is_restoring_from_ov = false; - resize(c, c->overview_backup_geom, 0); - } - } + if (c->isfloating) { + // XRaiseWindow(dpy, c->win); // 提升悬浮窗口到顶层 + resize(c, c->overview_backup_geom, 0); + } else if (c->isfullscreen || c->ismaxmizescreen) { + if (want_restore_fullscreen( + c)) { // 如果同tag有其他窗口,且其他窗口是将要聚焦的,那么不恢复该窗口的全屏状态 + resize(c, c->overview_backup_geom, 0); + } else { + c->isfullscreen = 0; + c->ismaxmizescreen = 0; + setfullscreen(c, false); + } + } else { + if (c->is_restoring_from_ov) { + c->is_restoring_from_ov = false; + resize(c, c->overview_backup_geom, 0); + } + } - if (c->bw == 0 && !c->isfullscreen) { // 如果是在ov模式中创建的窗口,没有bw记录 - c->bw = c->isnoborder ? 0 : borderpx; - } + if (c->bw == 0 && + !c->isfullscreen) { // 如果是在ov模式中创建的窗口,没有bw记录 + c->bw = c->isnoborder ? 0 : borderpx; + } } void switch_proportion_preset(const Arg *arg) { - float target_proportion = 0; + float target_proportion = 0; - if (config.scroller_proportion_preset_count == 0) { - return; - } + if (config.scroller_proportion_preset_count == 0) { + return; + } - if (selmon->sel) { + if (selmon->sel) { - for (int i = 0; i < config.scroller_proportion_preset_count; i++) { - if (config.scroller_proportion_preset[i] == - selmon->sel->scroller_proportion) { - if (i == config.scroller_proportion_preset_count - 1) { - target_proportion = config.scroller_proportion_preset[0]; - break; - } else { - target_proportion = config.scroller_proportion_preset[i + 1]; - break; - } - } - } + for (int i = 0; i < config.scroller_proportion_preset_count; i++) { + if (config.scroller_proportion_preset[i] == + selmon->sel->scroller_proportion) { + if (i == config.scroller_proportion_preset_count - 1) { + target_proportion = config.scroller_proportion_preset[0]; + break; + } else { + target_proportion = + config.scroller_proportion_preset[i + 1]; + break; + } + } + } - if (target_proportion == 0) { - target_proportion = config.scroller_proportion_preset[0]; - } + if (target_proportion == 0) { + target_proportion = config.scroller_proportion_preset[0]; + } - 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); - arrange(selmon, false); - } + 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); + arrange(selmon, false); + } } void set_proportion(const Arg *arg) { - if (selmon->sel) { - 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); - arrange(selmon, false); - } + if (selmon->sel) { + 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); + arrange(selmon, false); + } } void handlecursoractivity(void) { - wl_event_source_timer_update(hide_source, cursor_hide_timeout * 1000); + wl_event_source_timer_update(hide_source, cursor_hide_timeout * 1000); - if (!cursor_hidden) - return; + if (!cursor_hidden) + return; - cursor_hidden = false; + cursor_hidden = false; - if (last_cursor.shape) - wlr_cursor_set_xcursor(cursor, cursor_mgr, - wlr_cursor_shape_v1_name(last_cursor.shape)); - else - wlr_cursor_set_surface(cursor, last_cursor.surface, last_cursor.hotspot_x, - last_cursor.hotspot_y); + if (last_cursor.shape) + wlr_cursor_set_xcursor(cursor, cursor_mgr, + wlr_cursor_shape_v1_name(last_cursor.shape)); + else + wlr_cursor_set_surface(cursor, last_cursor.surface, + last_cursor.hotspot_x, last_cursor.hotspot_y); } int hidecursor(void *data) { - wlr_cursor_unset_image(cursor); - cursor_hidden = true; - return 1; + wlr_cursor_unset_image(cursor); + cursor_hidden = true; + return 1; } void increase_proportion(const Arg *arg) { - if (selmon->sel) { - unsigned int max_client_width = - selmon->w.width - 2 * scroller_structs - gappih; - selmon->sel->scroller_proportion = - MIN(MAX(arg->f + selmon->sel->scroller_proportion, 0.1), 1.0); - selmon->sel->geom.width = max_client_width * arg->f; - arrange(selmon, false); - } + if (selmon->sel) { + unsigned int max_client_width = + selmon->w.width - 2 * scroller_structs - gappih; + selmon->sel->scroller_proportion = + MIN(MAX(arg->f + selmon->sel->scroller_proportion, 0.1), 1.0); + selmon->sel->geom.width = max_client_width * arg->f; + arrange(selmon, false); + } } // 显示所有tag 或 跳转到聚焦窗口的tag void toggleoverview(const Arg *arg) { - Client *c; + Client *c; - if (selmon->isoverview && ov_tab_mode && arg->i != -1 && selmon->sel) { - focusstack(&(Arg){.i = 1}); - return; - } + if (selmon->isoverview && ov_tab_mode && arg->i != -1 && selmon->sel) { + focusstack(&(Arg){.i = 1}); + return; + } - selmon->isoverview ^= 1; - unsigned int target; - unsigned int visible_client_number = 0; + selmon->isoverview ^= 1; + unsigned int target; + unsigned int visible_client_number = 0; - if (selmon->isoverview) { - wl_list_for_each(c, &clients, link) if (c && c->mon == selmon && - !client_is_unmanaged(c) && - !client_should_ignore_focus(c) && - !c->isminied && !c->isunglobal) { - visible_client_number++; - } - if (visible_client_number > 0) { - target = ~0; - } else { - selmon->isoverview ^= 1; - return; - } - } else if (!selmon->isoverview && selmon->sel) { - target = get_tags_first_tag(selmon->sel->tags); - } else if (!selmon->isoverview && !selmon->sel) { - target = (1 << (selmon->pertag->prevtag - 1)); - view(&(Arg){.ui = target}, false); - return; - } + if (selmon->isoverview) { + wl_list_for_each(c, &clients, + link) if (c && c->mon == selmon && + !client_is_unmanaged(c) && + !client_should_ignore_focus(c) && + !c->isminied && !c->isunglobal) { + visible_client_number++; + } + if (visible_client_number > 0) { + target = ~0; + } else { + selmon->isoverview ^= 1; + return; + } + } else if (!selmon->isoverview && selmon->sel) { + target = get_tags_first_tag(selmon->sel->tags); + } else if (!selmon->isoverview && !selmon->sel) { + target = (1 << (selmon->pertag->prevtag - 1)); + view(&(Arg){.ui = target}, false); + return; + } - // 正常视图到overview,退出所有窗口的浮动和全屏状态参与平铺, - // overview到正常视图,还原之前退出的浮动和全屏窗口状态 - if (selmon->isoverview) { - wl_list_for_each(c, &clients, link) { - if (c && !client_is_unmanaged(c) && !client_should_ignore_focus(c) && !c->isunglobal) - overview_backup(c); - } - } else { - wl_list_for_each(c, &clients, link) { - if (c && !c->iskilling && !client_is_unmanaged(c) && !c->isunglobal && - !client_should_ignore_focus(c) && client_surface(c)->mapped) - overview_restore(c, &(Arg){.ui = target}); - } - } + // 正常视图到overview,退出所有窗口的浮动和全屏状态参与平铺, + // overview到正常视图,还原之前退出的浮动和全屏窗口状态 + if (selmon->isoverview) { + wl_list_for_each(c, &clients, link) { + if (c && !client_is_unmanaged(c) && + !client_should_ignore_focus(c) && !c->isunglobal) + overview_backup(c); + } + } else { + wl_list_for_each(c, &clients, link) { + if (c && !c->iskilling && !client_is_unmanaged(c) && + !c->isunglobal && !client_should_ignore_focus(c) && + client_surface(c)->mapped) + overview_restore(c, &(Arg){.ui = target}); + } + } - view(&(Arg){.ui = target}, false); + view(&(Arg){.ui = target}, false); - if (ov_tab_mode && selmon->isoverview && selmon->sel) { - focusstack(&(Arg){.i = 1}); - } + if (ov_tab_mode && selmon->isoverview && selmon->sel) { + focusstack(&(Arg){.i = 1}); + } } void togglefloating(const Arg *arg) { - Client *sel = focustop(selmon); + Client *sel = focustop(selmon); - if (!sel) - return; + if (!sel) + return; - if ((sel->isfullscreen || sel->ismaxmizescreen)) { - sel->isfloating = 1; - } else { - sel->isfloating = !sel->isfloating; - } + if ((sel->isfullscreen || sel->ismaxmizescreen)) { + sel->isfloating = 1; + } else { + sel->isfloating = !sel->isfloating; + } - setfloating(sel, sel->isfloating); + setfloating(sel, sel->isfloating); } void togglefakefullscreen(const Arg *arg) { - Client *sel = focustop(selmon); - if (sel) - setfakefullscreen(sel, !sel->isfakefullscreen); + Client *sel = focustop(selmon); + if (sel) + setfakefullscreen(sel, !sel->isfakefullscreen); } void togglefullscreen(const Arg *arg) { - Client *sel = focustop(selmon); - if (!sel) - return; + Client *sel = focustop(selmon); + if (!sel) + return; - // if(sel->isfloating) - // setfloating(sel, 0); + // if(sel->isfloating) + // setfloating(sel, 0); - if (sel->isfullscreen || sel->ismaxmizescreen) - setfullscreen(sel, 0); - else - setfullscreen(sel, 1); + if (sel->isfullscreen || sel->ismaxmizescreen) + setfullscreen(sel, 0); + else + setfullscreen(sel, 1); - sel->is_scratchpad_show = 0; - sel->is_in_scratchpad = 0; - sel->isnamedscratchpand = 0; + sel->is_scratchpad_show = 0; + sel->is_in_scratchpad = 0; + sel->isnamedscratchpand = 0; } void togglemaxmizescreen(const Arg *arg) { - Client *sel = focustop(selmon); - if (!sel) - return; + Client *sel = focustop(selmon); + if (!sel) + return; - // if(sel->isfloating) - // setfloating(sel, 0); + // if(sel->isfloating) + // setfloating(sel, 0); - if (sel->isfullscreen || sel->ismaxmizescreen) - setmaxmizescreen(sel, 0); - else - setmaxmizescreen(sel, 1); + if (sel->isfullscreen || sel->ismaxmizescreen) + setmaxmizescreen(sel, 0); + else + setmaxmizescreen(sel, 1); - sel->is_scratchpad_show = 0; - sel->is_in_scratchpad = 0; - sel->isnamedscratchpand = 0; + sel->is_scratchpad_show = 0; + sel->is_in_scratchpad = 0; + sel->isnamedscratchpand = 0; } void togglegaps(const Arg *arg) { - enablegaps ^= 1; - arrange(selmon, false); + enablegaps ^= 1; + arrange(selmon, false); } void toggletag(const Arg *arg) { - unsigned int newtags; - Client *sel = focustop(selmon); - if (!sel) - return; - newtags = sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - sel->tags = newtags; - focusclient(focustop(selmon), 1); - arrange(selmon, false); - } - printstatus(); + unsigned int newtags; + Client *sel = focustop(selmon); + if (!sel) + return; + newtags = sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { + sel->tags = newtags; + focusclient(focustop(selmon), 1); + arrange(selmon, false); + } + printstatus(); } void toggleview(const Arg *arg) { - unsigned int newtagset = - selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0; + unsigned int newtagset = + selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0; - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focusclient(focustop(selmon), 1); - arrange(selmon, false); - } - printstatus(); + if (newtagset) { + selmon->tagset[selmon->seltags] = newtagset; + focusclient(focustop(selmon), 1); + arrange(selmon, false); + } + printstatus(); } void unlocksession(struct wl_listener *listener, void *data) { - SessionLock *lock = wl_container_of(listener, lock, unlock); - destroylock(lock, 1); + SessionLock *lock = wl_container_of(listener, lock, unlock); + destroylock(lock, 1); } void unmaplayersurfacenotify(struct wl_listener *listener, void *data) { - LayerSurface *l = wl_container_of(listener, l, unmap); + LayerSurface *l = wl_container_of(listener, l, unmap); - l->mapped = 0; - wlr_scene_node_set_enabled(&l->scene->node, false); - if (l == exclusive_focus) - exclusive_focus = NULL; - if (l->layer_surface->output && (l->mon = l->layer_surface->output->data)) - arrangelayers(l->mon); - if (l->layer_surface->surface == seat->keyboard_state.focused_surface) - focusclient(focustop(selmon), 1); - motionnotify(0, NULL, 0, 0, 0, 0); + l->mapped = 0; + wlr_scene_node_set_enabled(&l->scene->node, false); + if (l == exclusive_focus) + exclusive_focus = NULL; + if (l->layer_surface->output && (l->mon = l->layer_surface->output->data)) + arrangelayers(l->mon); + if (l->layer_surface->surface == seat->keyboard_state.focused_surface) + focusclient(focustop(selmon), 1); + motionnotify(0, NULL, 0, 0, 0, 0); } void init_fadeout_client(Client *c) { - if (!c->mon || client_is_unmanaged(c)) - return; + if (!c->mon || client_is_unmanaged(c)) + return; - if (!c->scene) { - return; - } + if (!c->scene) { + return; + } - if (c->animation_type_close && strcmp(c->animation_type_close, "none") == 0) { - return; - } + if (c->animation_type_close && + strcmp(c->animation_type_close, "none") == 0) { + return; + } - Client *fadeout_cient = ecalloc(1, sizeof(*fadeout_cient)); + Client *fadeout_cient = ecalloc(1, sizeof(*fadeout_cient)); - wlr_scene_node_set_enabled(&c->scene->node, true); - client_set_border_color(c, bordercolor); - fadeout_cient->scene = - wlr_scene_tree_snapshot(&c->scene->node, layers[LyrFadeOut]); - wlr_scene_node_set_enabled(&c->scene->node, false); + wlr_scene_node_set_enabled(&c->scene->node, true); + client_set_border_color(c, bordercolor); + fadeout_cient->scene = + wlr_scene_tree_snapshot(&c->scene->node, layers[LyrFadeOut]); + wlr_scene_node_set_enabled(&c->scene->node, false); - if (!fadeout_cient->scene) { - free(fadeout_cient); - return; - } + if (!fadeout_cient->scene) { + free(fadeout_cient); + return; + } - fadeout_cient->animation.duration = animation_duration_close; - fadeout_cient->geom = fadeout_cient->current = fadeout_cient->animainit_geom = - fadeout_cient->animation.initial = c->animation.current; - fadeout_cient->mon = c->mon; - fadeout_cient->animation_type_close = c->animation_type_close; - fadeout_cient->animation.action = CLOSE; - fadeout_cient->bw = c->bw; - fadeout_cient->nofadeout = c->nofadeout; + fadeout_cient->animation.duration = animation_duration_close; + fadeout_cient->geom = fadeout_cient->current = + fadeout_cient->animainit_geom = fadeout_cient->animation.initial = + c->animation.current; + fadeout_cient->mon = c->mon; + fadeout_cient->animation_type_close = c->animation_type_close; + fadeout_cient->animation.action = CLOSE; + fadeout_cient->bw = c->bw; + fadeout_cient->nofadeout = c->nofadeout; - // 这里snap节点的坐标设置是使用的相对坐标,所以不能加上原来坐标 - // 这跟普通node有区别 + // 这里snap节点的坐标设置是使用的相对坐标,所以不能加上原来坐标 + // 这跟普通node有区别 - fadeout_cient->animation.initial.x = 0; - fadeout_cient->animation.initial.y = 0; - if ((c->animation_type_close && - strcmp(c->animation_type_close, "slide") == 0) || - (!c->animation_type_close && - strcmp(animation_type_close, "slide") == 0)) { - fadeout_cient->current.y = - c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2 - ? c->mon->m.height - - (c->animation.current.y - c->mon->m.y) // down out - : c->mon->m.y - c->geom.height; // up out - fadeout_cient->current.x = 0; // x无偏差,垂直划出 - } else { - fadeout_cient->current.y = - (fadeout_cient->geom.height - - fadeout_cient->geom.height * zoom_initial_ratio) / - 2; - fadeout_cient->current.x = - (fadeout_cient->geom.width - - fadeout_cient->geom.width * zoom_initial_ratio) / - 2; - fadeout_cient->current.width = - fadeout_cient->geom.width * zoom_initial_ratio; - fadeout_cient->current.height = - fadeout_cient->geom.height * zoom_initial_ratio; - } + fadeout_cient->animation.initial.x = 0; + fadeout_cient->animation.initial.y = 0; + if ((c->animation_type_close && + strcmp(c->animation_type_close, "slide") == 0) || + (!c->animation_type_close && + strcmp(animation_type_close, "slide") == 0)) { + fadeout_cient->current.y = + c->geom.y + c->geom.height / 2 > c->mon->m.y + c->mon->m.height / 2 + ? c->mon->m.height - + (c->animation.current.y - c->mon->m.y) // down out + : c->mon->m.y - c->geom.height; // up out + fadeout_cient->current.x = 0; // x无偏差,垂直划出 + } else { + fadeout_cient->current.y = + (fadeout_cient->geom.height - + fadeout_cient->geom.height * zoom_initial_ratio) / + 2; + fadeout_cient->current.x = + (fadeout_cient->geom.width - + fadeout_cient->geom.width * zoom_initial_ratio) / + 2; + fadeout_cient->current.width = + fadeout_cient->geom.width * zoom_initial_ratio; + fadeout_cient->current.height = + fadeout_cient->geom.height * zoom_initial_ratio; + } - fadeout_cient->animation.passed_frames = 0; - fadeout_cient->animation.total_frames = - fadeout_cient->animation.duration / output_frame_duration_ms(c); - wlr_scene_node_set_enabled(&fadeout_cient->scene->node, true); - wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link); + fadeout_cient->animation.passed_frames = 0; + fadeout_cient->animation.total_frames = + fadeout_cient->animation.duration / output_frame_duration_ms(c); + wlr_scene_node_set_enabled(&fadeout_cient->scene->node, true); + wl_list_insert(&fadeout_clients, &fadeout_cient->fadeout_link); } void unmapnotify(struct wl_listener *listener, void *data) { - /* Called when the surface is unmapped, and should no longer be shown. */ - Client *c = wl_container_of(listener, c, unmap); - Monitor *m; - c->iskilling = 1; + /* Called when the surface is unmapped, and should no longer be shown. */ + Client *c = wl_container_of(listener, c, unmap); + Monitor *m; + c->iskilling = 1; - if (animations && !c->isminied && (!c->mon || VISIBLEON(c, c->mon))) - init_fadeout_client(c); + if (animations && !c->isminied && (!c->mon || VISIBLEON(c, c->mon))) + init_fadeout_client(c); - if (c->swallowedby) { - c->swallowedby->mon = c->mon; - swallow(c->swallowedby, c); - } + if (c->swallowedby) { + c->swallowedby->mon = c->mon; + swallow(c->swallowedby, c); + } - if (c == grabc) { - cursor_mode = CurNormal; - grabc = NULL; - } + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; + } - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) { - continue; - } - if (c == m->sel) { - m->sel = NULL; - } - if (c == m->prevsel) { - m->prevsel = NULL; - } - } + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + if (c == m->sel) { + m->sel = NULL; + } + if (c == m->prevsel) { + m->prevsel = NULL; + } + } - if (c->mon && c->mon == selmon) { - Client *nextfocus = focustop(selmon); + if (c->mon && c->mon == selmon) { + Client *nextfocus = focustop(selmon); - if (nextfocus) { - focusclient(nextfocus, 0); - } + if (nextfocus) { + focusclient(nextfocus, 0); + } - if (!nextfocus && selmon->isoverview) { - Arg arg = {0}; - toggleoverview(&arg); - } - } + if (!nextfocus && selmon->isoverview) { + Arg arg = {0}; + toggleoverview(&arg); + } + } - if (client_is_unmanaged(c)) { + if (client_is_unmanaged(c)) { #ifdef XWAYLAND - if(client_is_x11(c)) { - wl_list_remove(&c->set_geometry.link); - } + if (client_is_x11(c)) { + wl_list_remove(&c->set_geometry.link); + } #endif - if (c == exclusive_focus) - exclusive_focus = NULL; - if (client_surface(c) == seat->keyboard_state.focused_surface) - focusclient(focustop(selmon), 1); - } else { - if (!c->swallowing) - wl_list_remove(&c->link); - setmon(c, NULL, 0, true); - if (!c->swallowing) - wl_list_remove(&c->flink); - } + if (c == exclusive_focus) + exclusive_focus = NULL; + if (client_surface(c) == seat->keyboard_state.focused_surface) + focusclient(focustop(selmon), 1); + } else { + if (!c->swallowing) + wl_list_remove(&c->link); + setmon(c, NULL, 0, true); + if (!c->swallowing) + wl_list_remove(&c->flink); + } - if (c->foreign_toplevel) { - wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); - c->foreign_toplevel = NULL; - } + if (c->foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_destroy(c->foreign_toplevel); + c->foreign_toplevel = NULL; + } - if (c->swallowedby) { - setfullscreen(c->swallowedby, c->isfullscreen); - setmaxmizescreen(c->swallowedby, c->ismaxmizescreen); - c->swallowedby->swallowing = NULL; - c->swallowedby = NULL; - } + if (c->swallowedby) { + setfullscreen(c->swallowedby, c->isfullscreen); + setmaxmizescreen(c->swallowedby, c->ismaxmizescreen); + c->swallowedby->swallowing = NULL; + c->swallowedby = NULL; + } - if (c->swallowing) { - c->swallowing->swallowedby = NULL; - c->swallowing = NULL; - } + if (c->swallowing) { + c->swallowing->swallowedby = NULL; + c->swallowing = NULL; + } - wlr_scene_node_destroy(&c->scene->node); - printstatus(); - motionnotify(0, NULL, 0, 0, 0, 0); + wlr_scene_node_destroy(&c->scene->node); + printstatus(); + motionnotify(0, NULL, 0, 0, 0, 0); } void updatemons(struct wl_listener *listener, void *data) { - /* - * Called whenever the output layout changes: adding or removing a - * monitor, changing an output's mode or position, etc. This is where - * the change officially happens and we update geometry, window - * positions, focus, and the stored configuration in wlroots' - * output-manager implementation. - */ - struct wlr_output_configuration_v1 *config = - wlr_output_configuration_v1_create(); - Client *c; - struct wlr_output_configuration_head_v1 *config_head; - Monitor *m; + /* + * Called whenever the output layout changes: adding or removing a + * monitor, changing an output's mode or position, etc. This is where + * the change officially happens and we update geometry, window + * positions, focus, and the stored configuration in wlroots' + * output-manager implementation. + */ + struct wlr_output_configuration_v1 *config = + wlr_output_configuration_v1_create(); + Client *c; + struct wlr_output_configuration_head_v1 *config_head; + Monitor *m; - /* First remove from the layout the disabled monitors */ - wl_list_for_each(m, &mons, link) { - if (m->wlr_output->enabled || m->asleep) - continue; - config_head = - wlr_output_configuration_head_v1_create(config, m->wlr_output); - config_head->state.enabled = 0; - /* Remove this output from the layout to avoid cursor enter inside it */ - wlr_output_layout_remove(output_layout, m->wlr_output); - closemon(m); - m->m = m->w = (struct wlr_box){0}; - } - /* Insert outputs that need to */ - wl_list_for_each(m, &mons, link) { - if (m->wlr_output->enabled && - !wlr_output_layout_get(output_layout, m->wlr_output)) - wlr_output_layout_add_auto(output_layout, m->wlr_output); - } + /* First remove from the layout the disabled monitors */ + wl_list_for_each(m, &mons, link) { + if (m->wlr_output->enabled || m->asleep) + continue; + config_head = + wlr_output_configuration_head_v1_create(config, m->wlr_output); + config_head->state.enabled = 0; + /* Remove this output from the layout to avoid cursor enter inside it */ + wlr_output_layout_remove(output_layout, m->wlr_output); + closemon(m); + m->m = m->w = (struct wlr_box){0}; + } + /* Insert outputs that need to */ + wl_list_for_each(m, &mons, link) { + if (m->wlr_output->enabled && + !wlr_output_layout_get(output_layout, m->wlr_output)) + wlr_output_layout_add_auto(output_layout, m->wlr_output); + } - /* Now that we update the output layout we can get its box */ - wlr_output_layout_get_box(output_layout, NULL, &sgeom); + /* Now that we update the output layout we can get its box */ + wlr_output_layout_get_box(output_layout, NULL, &sgeom); - wlr_scene_node_set_position(&root_bg->node, sgeom.x, sgeom.y); - wlr_scene_rect_set_size(root_bg, sgeom.width, sgeom.height); + wlr_scene_node_set_position(&root_bg->node, sgeom.x, sgeom.y); + wlr_scene_rect_set_size(root_bg, sgeom.width, sgeom.height); - /* Make sure the clients are hidden when dwl is locked */ - wlr_scene_node_set_position(&locked_bg->node, sgeom.x, sgeom.y); - wlr_scene_rect_set_size(locked_bg, sgeom.width, sgeom.height); + /* Make sure the clients are hidden when dwl is locked */ + wlr_scene_node_set_position(&locked_bg->node, sgeom.x, sgeom.y); + wlr_scene_rect_set_size(locked_bg, sgeom.width, sgeom.height); - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) - continue; - config_head = - wlr_output_configuration_head_v1_create(config, m->wlr_output); + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) + continue; + config_head = + wlr_output_configuration_head_v1_create(config, m->wlr_output); - /* Get the effective monitor geometry to use for surfaces */ - wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m); - m->w = m->m; - wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y); + /* Get the effective monitor geometry to use for surfaces */ + wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m); + m->w = m->m; + wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y); - // wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); - // wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height); + // wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); + // wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height); - if (m->lock_surface) { - struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data; - wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); - wlr_session_lock_surface_v1_configure(m->lock_surface, m->m.width, - m->m.height); - } + if (m->lock_surface) { + struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data; + wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); + wlr_session_lock_surface_v1_configure(m->lock_surface, m->m.width, + m->m.height); + } - /* Calculate the effective monitor geometry to use for clients */ - arrangelayers(m); - /* Don't move clients to the left output when plugging monitors */ - arrange(m, false); - /* make sure fullscreen clients have the right size */ - if ((c = focustop(m)) && c->isfullscreen) - resize(c, m->m, 0); + /* Calculate the effective monitor geometry to use for clients */ + arrangelayers(m); + /* Don't move clients to the left output when plugging monitors */ + arrange(m, false); + /* make sure fullscreen clients have the right size */ + if ((c = focustop(m)) && c->isfullscreen) + resize(c, m->m, 0); - /* Try to re-set the gamma LUT when updating monitors, - * it's only really needed when enabling a disabled output, but meh. */ - m->gamma_lut_changed = 1; + /* Try to re-set the gamma LUT when updating monitors, + * it's only really needed when enabling a disabled output, but meh. */ + m->gamma_lut_changed = 1; - config_head->state.x = m->m.x; - config_head->state.y = m->m.y; + config_head->state.x = m->m.x; + config_head->state.y = m->m.y; - if (!selmon) { - selmon = m; - } - } + if (!selmon) { + selmon = m; + } + } - if (selmon && selmon->wlr_output->enabled) { - wl_list_for_each(c, &clients, link) { - if (!c->mon && client_surface(c)->mapped) { - setmon(c, selmon, c->tags, true); - reset_foreign_tolevel(c); - } - } - focusclient(focustop(selmon), 1); - if (selmon->lock_surface) { - client_notify_enter(selmon->lock_surface->surface, - wlr_seat_get_keyboard(seat)); - client_activate_surface(selmon->lock_surface->surface, 1); - } - } + if (selmon && selmon->wlr_output->enabled) { + wl_list_for_each(c, &clients, link) { + if (!c->mon && client_surface(c)->mapped) { + setmon(c, selmon, c->tags, true); + reset_foreign_tolevel(c); + } + } + focusclient(focustop(selmon), 1); + if (selmon->lock_surface) { + client_notify_enter(selmon->lock_surface->surface, + wlr_seat_get_keyboard(seat)); + client_activate_surface(selmon->lock_surface->surface, 1); + } + } - /* FIXME: figure out why the cursor image is at 0,0 after turning all - * the monitors on. - * Move the cursor image where it used to be. It does not generate a - * wl_pointer.motion event for the clients, it's only the image what it's - * at the wrong position after all. */ - wlr_cursor_move(cursor, NULL, 0, 0); + /* FIXME: figure out why the cursor image is at 0,0 after turning all + * the monitors on. + * Move the cursor image where it used to be. It does not generate a + * wl_pointer.motion event for the clients, it's only the image what it's + * at the wrong position after all. */ + wlr_cursor_move(cursor, NULL, 0, 0); - wlr_output_manager_v1_set_configuration(output_mgr, config); + wlr_output_manager_v1_set_configuration(output_mgr, config); } void updatetitle(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, set_title); + Client *c = wl_container_of(listener, c, set_title); - if (!c || c->iskilling) - return; + if (!c || c->iskilling) + return; - const char *title; - title = client_get_title(c); - if (title && c->foreign_toplevel) - wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); - if (c == focustop(c->mon)) - printstatus(); + const char *title; + title = client_get_title(c); + if (title && c->foreign_toplevel) + wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); + if (c == focustop(c->mon)) + printstatus(); } void // 17 fix to 0.5 urgent(struct wl_listener *listener, void *data) { - struct wlr_xdg_activation_v1_request_activate_event *event = data; - Client *c = NULL; - toplevel_from_wlr_surface(event->surface, &c, NULL); + struct wlr_xdg_activation_v1_request_activate_event *event = data; + Client *c = NULL; + toplevel_from_wlr_surface(event->surface, &c, NULL); - if (!c || !c->foreign_toplevel) - return; + if (!c || !c->foreign_toplevel) + return; - if (focus_on_activate && c != selmon->sel) { - view(&(Arg){.ui = c->tags}, true); - focusclient(c, 1); - } else if (c != focustop(selmon)) { - if (client_surface(c)->mapped) - client_set_border_color(c, urgentcolor); - c->isurgent = 1; - printstatus(); - } + if (focus_on_activate && c != selmon->sel) { + view(&(Arg){.ui = c->tags}, true); + focusclient(c, 1); + } else if (c != focustop(selmon)) { + if (client_surface(c)->mapped) + client_set_border_color(c, urgentcolor); + c->isurgent = 1; + printstatus(); + } } void bind_to_view(const Arg *arg) { view(arg, true); } void view_in_mon(const Arg *arg, bool want_animation, Monitor *m) { - size_t i, tmptag; + size_t i, tmptag; - if (!m || (arg->ui != ~0 && m->isoverview)) { - return; - } + if (!m || (arg->ui != ~0 && m->isoverview)) { + return; + } - if (arg->ui == 0) - return; + if (arg->ui == 0) + return; - if ((m->tagset[m->seltags] & arg->ui & TAGMASK) != 0) { - want_animation = false; - } + if ((m->tagset[m->seltags] & arg->ui & TAGMASK) != 0) { + want_animation = false; + } - m->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) { - m->tagset[m->seltags] = arg->ui & TAGMASK; - tmptag = m->pertag->curtag; + m->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) { + m->tagset[m->seltags] = arg->ui & TAGMASK; + tmptag = m->pertag->curtag; - if (arg->ui == ~0) - m->pertag->curtag = 0; - else { - for (i = 0; !(arg->ui & 1 << i) && i < LENGTH(tags) && arg->ui != 0; i++) - ; - m->pertag->curtag = i >= LENGTH(tags) ? LENGTH(tags) : i + 1; - } + if (arg->ui == ~0) + m->pertag->curtag = 0; + else { + for (i = 0; !(arg->ui & 1 << i) && i < LENGTH(tags) && arg->ui != 0; + i++) + ; + m->pertag->curtag = i >= LENGTH(tags) ? LENGTH(tags) : i + 1; + } - m->pertag->prevtag = - tmptag == m->pertag->curtag ? m->pertag->prevtag : tmptag; - } else { - tmptag = m->pertag->prevtag; - m->pertag->prevtag = m->pertag->curtag; - m->pertag->curtag = tmptag; - } + m->pertag->prevtag = + tmptag == m->pertag->curtag ? m->pertag->prevtag : tmptag; + } else { + tmptag = m->pertag->prevtag; + m->pertag->prevtag = m->pertag->curtag; + m->pertag->curtag = tmptag; + } - focusclient(focustop(m), 1); - arrange(m, want_animation); - printstatus(); + focusclient(focustop(m), 1); + arrange(m, want_animation); + printstatus(); } void view(const Arg *arg, bool want_animation) { - view_in_mon(arg, want_animation, selmon); + view_in_mon(arg, want_animation, selmon); } void viewtoleft(const Arg *arg) { - size_t tmptag; - unsigned int target = selmon->tagset[selmon->seltags]; + size_t tmptag; + unsigned int target = selmon->tagset[selmon->seltags]; - if (selmon->isoverview || selmon->pertag->curtag == 0) { - return; - } + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } - target >>= 1; + target >>= 1; - if (target == 0) { - return; - } + if (target == 0) { + return; + } - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = selmon->pertag->curtag - 1; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = selmon->pertag->curtag - 1; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } - focusclient(focustop(selmon), 1); - arrange(selmon, true); - printstatus(); + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } void viewtoright_have_client(const Arg *arg) { - size_t tmptag; - Client *c; - unsigned int found = 0; - unsigned int n = 1; - unsigned int target = selmon->tagset[selmon->seltags]; + size_t tmptag; + Client *c; + unsigned int found = 0; + unsigned int n = 1; + unsigned int target = selmon->tagset[selmon->seltags]; - if (selmon->isoverview || selmon->pertag->curtag == 0) { - return; - } + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } - for (target <<= 1; target & TAGMASK && n <= LENGTH(tags); target <<= 1, n++) { - wl_list_for_each(c, &clients, link) { - if (c->mon == selmon && target & c->tags) { - found = 1; - break; - } - } - if (found) { - break; - } - } + for (target <<= 1; target & TAGMASK && n <= LENGTH(tags); + target <<= 1, n++) { + wl_list_for_each(c, &clients, link) { + if (c->mon == selmon && target & c->tags) { + found = 1; + break; + } + } + if (found) { + break; + } + } - if (!(target & TAGMASK)) { - return; - } + if (!(target & TAGMASK)) { + return; + } - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ - int new_tag = selmon->pertag->curtag + n; - if (new_tag > LENGTH(tags)) - new_tag = LENGTH(tags); + int new_tag = selmon->pertag->curtag + n; + if (new_tag > LENGTH(tags)) + new_tag = LENGTH(tags); - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = new_tag; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = new_tag; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } - focusclient(focustop(selmon), 1); - arrange(selmon, true); - printstatus(); + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } void viewtoright(const Arg *arg) { - if (selmon->isoverview || selmon->pertag->curtag == 0) { - return; - } - size_t tmptag; - unsigned int target = selmon->tagset[selmon->seltags]; - target <<= 1; + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } + size_t tmptag; + unsigned int target = selmon->tagset[selmon->seltags]; + target <<= 1; - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - if (!(target & TAGMASK)) { - return; - } - selmon->seltags ^= 1; /* toggle sel tagset */ - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = selmon->pertag->curtag + 1; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + if (!(target & TAGMASK)) { + return; + } + selmon->seltags ^= 1; /* toggle sel tagset */ + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = selmon->pertag->curtag + 1; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } - focusclient(focustop(selmon), 1); - arrange(selmon, true); - printstatus(); + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } void viewtoleft_have_client(const Arg *arg) { - size_t tmptag; - Client *c; - unsigned int found = 0; - unsigned int n = 1; - unsigned int target = selmon->tagset[selmon->seltags]; + size_t tmptag; + Client *c; + unsigned int found = 0; + unsigned int n = 1; + unsigned int target = selmon->tagset[selmon->seltags]; - if (selmon->isoverview || selmon->pertag->curtag == 0) { - return; - } + if (selmon->isoverview || selmon->pertag->curtag == 0) { + return; + } - for (target >>= 1; target > 0 && n <= LENGTH(tags); target >>= 1, n++) { - wl_list_for_each(c, &clients, link) { - if (c->mon == selmon && target & c->tags) { - found = 1; - break; - } - } - if (found) { - break; - } - } + for (target >>= 1; target > 0 && n <= LENGTH(tags); target >>= 1, n++) { + wl_list_for_each(c, &clients, link) { + if (c->mon == selmon && target & c->tags) { + found = 1; + break; + } + } + if (found) { + break; + } + } - if (target == 0) { - return; - } + if (target == 0) { + return; + } - if (!selmon || (target) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ + if (!selmon || (target) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ - int new_tag = selmon->pertag->curtag - n; - if (new_tag < 1) - new_tag = 1; + int new_tag = selmon->pertag->curtag - n; + if (new_tag < 1) + new_tag = 1; - if (target) { - selmon->tagset[selmon->seltags] = target; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = new_tag; - } else { - tmptag = selmon->pertag->prevtag; - selmon->pertag->prevtag = selmon->pertag->curtag; - selmon->pertag->curtag = tmptag; - } + if (target) { + selmon->tagset[selmon->seltags] = target; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = new_tag; + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } - focusclient(focustop(selmon), 1); - arrange(selmon, true); - printstatus(); + focusclient(focustop(selmon), 1); + arrange(selmon, true); + printstatus(); } void tagtoleft(const Arg *arg) { - if (selmon->sel != NULL && - __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && - selmon->tagset[selmon->seltags] > 1) { - tag(&(Arg){.ui = selmon->tagset[selmon->seltags] >> 1}); - } + if (selmon->sel != NULL && + __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && + selmon->tagset[selmon->seltags] > 1) { + tag(&(Arg){.ui = selmon->tagset[selmon->seltags] >> 1}); + } } void tagtoright(const Arg *arg) { - if (selmon->sel != NULL && - __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && - selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { - tag(&(Arg){.ui = selmon->tagset[selmon->seltags] << 1}); - } + if (selmon->sel != NULL && + __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 && + selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { + tag(&(Arg){.ui = selmon->tagset[selmon->seltags] << 1}); + } } void virtualkeyboard(struct wl_listener *listener, void *data) { - struct wlr_virtual_keyboard_v1 *kb = data; - /* virtual keyboards shouldn't share keyboard group */ - KeyboardGroup *group = createkeyboardgroup(); - /* Set the keymap to match the group keymap */ - wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap); - LISTEN(&kb->keyboard.base.events.destroy, &group->destroy, - destroykeyboardgroup); + struct wlr_virtual_keyboard_v1 *kb = data; + /* virtual keyboards shouldn't share keyboard group */ + KeyboardGroup *group = createkeyboardgroup(); + /* Set the keymap to match the group keymap */ + wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap); + LISTEN(&kb->keyboard.base.events.destroy, &group->destroy, + destroykeyboardgroup); - /* Add the new keyboard to the group */ - wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard); + /* Add the new keyboard to the group */ + wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard); } void warp_cursor(const Client *c) { - if (cursor->x < c->geom.x || cursor->x > c->geom.x + c->geom.width || - cursor->y < c->geom.y || cursor->y > c->geom.y + c->geom.height) { - wlr_cursor_warp_closest(cursor, NULL, c->geom.x + c->geom.width / 2.0, - c->geom.y + c->geom.height / 2.0); - motionnotify(0, NULL, 0, 0, 0, 0); - } + if (cursor->x < c->geom.x || cursor->x > c->geom.x + c->geom.width || + cursor->y < c->geom.y || cursor->y > c->geom.y + c->geom.height) { + wlr_cursor_warp_closest(cursor, NULL, c->geom.x + c->geom.width / 2.0, + c->geom.y + c->geom.height / 2.0); + motionnotify(0, NULL, 0, 0, 0, 0); + } } void warp_cursor_to_selmon(const Monitor *m) { - wlr_cursor_warp_closest(cursor, NULL, m->w.x + m->w.width / 2.0, - m->w.y + m->w.height / 2.0); + wlr_cursor_warp_closest(cursor, NULL, m->w.x + m->w.width / 2.0, + m->w.y + m->w.height / 2.0); } void virtualpointer(struct wl_listener *listener, void *data) { - struct wlr_virtual_pointer_v1_new_pointer_event *event = data; - struct wlr_input_device *device = &event->new_pointer->pointer.base; + struct wlr_virtual_pointer_v1_new_pointer_event *event = data; + struct wlr_input_device *device = &event->new_pointer->pointer.base; - wlr_cursor_attach_input_device(cursor, device); - if (event->suggested_output) - wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); + wlr_cursor_attach_input_device(cursor, device); + if (event->suggested_output) + wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); - handlecursoractivity(); + handlecursoractivity(); } Monitor *xytomon(double x, double y) { - struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y); - return o ? o->data : NULL; + struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y); + return o ? o->data : NULL; } void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, - LayerSurface **pl, double *nx, double *ny) { - struct wlr_scene_node *node, *pnode; - struct wlr_surface *surface = NULL; - Client *c = NULL; - LayerSurface *l = NULL; - int layer; + LayerSurface **pl, double *nx, double *ny) { + struct wlr_scene_node *node, *pnode; + struct wlr_surface *surface = NULL; + Client *c = NULL; + LayerSurface *l = NULL; + int layer; - for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) { + for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) { - // ignore text-input layer - if (layer == LyrIMPopup) - continue; + // ignore text-input layer + if (layer == LyrIMPopup) + continue; - if (layer == LyrFadeOut) - continue; + if (layer == LyrFadeOut) + continue; - if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))) - continue; + if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))) + continue; - if (node->type == WLR_SCENE_NODE_BUFFER) - surface = - wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)) - ->surface; - /* Walk the tree to find a node that knows the client */ - for (pnode = node; pnode && !c; pnode = &pnode->parent->node) - c = pnode->data; - if (c && c->type == LayerShell) { - c = NULL; - l = pnode->data; - } - } + if (node->type == WLR_SCENE_NODE_BUFFER) + surface = wlr_scene_surface_try_from_buffer( + wlr_scene_buffer_from_node(node)) + ->surface; + /* Walk the tree to find a node that knows the client */ + for (pnode = node; pnode && !c; pnode = &pnode->parent->node) + c = pnode->data; + if (c && c->type == LayerShell) { + c = NULL; + l = pnode->data; + } + } - if (psurface) - *psurface = surface; - if (pc) - *pc = c; - if (pl) - *pl = l; + if (psurface) + *psurface = surface; + if (pc) + *pc = c; + if (pl) + *pl = l; } void toggleglobal(const Arg *arg) { - if (!selmon->sel) - return; - if (selmon->sel->is_in_scratchpad) { - selmon->sel->is_in_scratchpad = 0; - selmon->sel->is_scratchpad_show = 0; - selmon->sel->isnamedscratchpand = 0; - } - selmon->sel->isglobal ^= 1; - // selmon->sel->tags = - // selmon->sel->isglobal ? TAGMASK : selmon->tagset[selmon->seltags]; - // focustop(selmon); - setborder_color(selmon->sel); + if (!selmon->sel) + return; + if (selmon->sel->is_in_scratchpad) { + selmon->sel->is_in_scratchpad = 0; + selmon->sel->is_scratchpad_show = 0; + selmon->sel->isnamedscratchpand = 0; + } + selmon->sel->isglobal ^= 1; + // selmon->sel->tags = + // selmon->sel->isglobal ? TAGMASK : selmon->tagset[selmon->seltags]; + // focustop(selmon); + setborder_color(selmon->sel); } void zoom(const Arg *arg) { - Client *c, *sel = focustop(selmon); + Client *c, *sel = focustop(selmon); - if (!sel || !selmon || - !selmon->pertag->ltidxs[selmon->pertag->curtag]->arrange || - sel->isfloating) - return; + 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 - * NULL if we pass it along the way */ - wl_list_for_each(c, &clients, - link) if (VISIBLEON(c, selmon) && !c->isfloating) { - if (c != sel) - break; - sel = NULL; - } + /* Search for the first tiled window that is not sel, marking sel as + * NULL if we pass it along the way */ + wl_list_for_each(c, &clients, + link) if (VISIBLEON(c, selmon) && !c->isfloating) { + if (c != sel) + break; + sel = NULL; + } - /* Return if no other tiled window was found */ - if (&c->link == &clients) - return; + /* Return if no other tiled window was found */ + if (&c->link == &clients) + return; - /* If we passed sel, move c to the front; otherwise, move sel to the - * front */ - if (!sel) - sel = c; - wl_list_remove(&sel->link); - wl_list_insert(&clients, &sel->link); + /* If we passed sel, move c to the front; otherwise, move sel to the + * front */ + if (!sel) + sel = c; + wl_list_remove(&sel->link); + wl_list_insert(&clients, &sel->link); - focusclient(sel, 1); - arrange(selmon, false); + focusclient(sel, 1); + arrange(selmon, false); } void resizewin(const Arg *arg) { - Client *c; - c = selmon->sel; - if (!c || c->isfullscreen) - return; - if (!c->isfloating) - togglefloating(NULL); + Client *c; + c = selmon->sel; + if (!c || c->isfullscreen) + return; + if (!c->isfloating) + togglefloating(NULL); - switch (arg->ui) { - case NUM_TYPE_MINUS: - c->geom.width -= arg->i; - break; - case NUM_TYPE_PLUS: - c->geom.width += arg->i; - break; - default: - c->geom.width = arg->i; - break; - } + switch (arg->ui) { + case NUM_TYPE_MINUS: + c->geom.width -= arg->i; + break; + case NUM_TYPE_PLUS: + c->geom.width += arg->i; + break; + default: + c->geom.width = arg->i; + break; + } - switch (arg->ui2) { - case NUM_TYPE_MINUS: - c->geom.height -= arg->i2; - break; - case NUM_TYPE_PLUS: - c->geom.height += arg->i2; - break; - default: - c->geom.height = arg->i2; - break; - } + switch (arg->ui2) { + case NUM_TYPE_MINUS: + c->geom.height -= arg->i2; + break; + case NUM_TYPE_PLUS: + c->geom.height += arg->i2; + break; + default: + c->geom.height = arg->i2; + break; + } - c->oldgeom = c->geom; - resize(c, c->geom, 0); + c->oldgeom = c->geom; + resize(c, c->geom, 0); } void movewin(const Arg *arg) { - Client *c; - c = selmon->sel; - if (!c || c->isfullscreen) - return; - if (!c->isfloating) - togglefloating(NULL); + Client *c; + c = selmon->sel; + if (!c || c->isfullscreen) + return; + if (!c->isfloating) + togglefloating(NULL); - switch (arg->ui) { - case NUM_TYPE_MINUS: - c->geom.x -= arg->i; - break; - case NUM_TYPE_PLUS: - c->geom.x += arg->i; - break; - default: - c->geom.x = arg->i; - break; - } + switch (arg->ui) { + case NUM_TYPE_MINUS: + c->geom.x -= arg->i; + break; + case NUM_TYPE_PLUS: + c->geom.x += arg->i; + break; + default: + c->geom.x = arg->i; + break; + } - switch (arg->ui2) { - case NUM_TYPE_MINUS: - c->geom.y -= arg->i2; - break; - case NUM_TYPE_PLUS: - c->geom.y += arg->i2; - break; - default: - c->geom.y = arg->i2; - break; - } + switch (arg->ui2) { + case NUM_TYPE_MINUS: + c->geom.y -= arg->i2; + break; + case NUM_TYPE_PLUS: + c->geom.y += arg->i2; + break; + default: + c->geom.y = arg->i2; + break; + } - c->oldgeom = c->geom; - resize(c, c->geom, 0); + c->oldgeom = c->geom; + resize(c, c->geom, 0); } void smartmovewin(const Arg *arg) { - Client *c, *tc; - int nx, ny; - int buttom, top, left, right, tar; - c = selmon->sel; - if (!c || c->isfullscreen) - return; - if (!c->isfloating) - setfloating(selmon->sel, true); - nx = c->geom.x; - ny = c->geom.y; + Client *c, *tc; + int nx, ny; + int buttom, top, left, right, tar; + c = selmon->sel; + if (!c || c->isfullscreen) + return; + if (!c->isfloating) + setfloating(selmon->sel, true); + nx = c->geom.x; + ny = c->geom.y; - switch (arg->i) { - case UP: - tar = -99999; - top = c->geom.y; - ny -= c->mon->w.height / 4; + switch (arg->i) { + case UP: + tar = -99999; + top = c->geom.y; + ny -= c->mon->w.height / 4; - wl_list_for_each(tc, &clients, link) { - if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) - continue; - if (c->geom.x + c->geom.width < tc->geom.x || - c->geom.x > tc->geom.x + tc->geom.width) - continue; - buttom = tc->geom.y + tc->geom.height + gappiv; - if (top > buttom && ny < buttom) { - tar = MAX(tar, buttom); - }; - } + wl_list_for_each(tc, &clients, link) { + if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) + continue; + if (c->geom.x + c->geom.width < tc->geom.x || + c->geom.x > tc->geom.x + tc->geom.width) + continue; + buttom = tc->geom.y + tc->geom.height + gappiv; + if (top > buttom && ny < buttom) { + tar = MAX(tar, buttom); + }; + } - ny = tar == -99999 ? ny : tar; - ny = MAX(ny, c->mon->w.y); - break; - case DOWN: - tar = 99999; - buttom = c->geom.y + c->geom.height; - ny += c->mon->w.height / 4; + ny = tar == -99999 ? ny : tar; + ny = MAX(ny, c->mon->w.y); + break; + case DOWN: + tar = 99999; + buttom = c->geom.y + c->geom.height; + ny += c->mon->w.height / 4; - wl_list_for_each(tc, &clients, link) { - if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) - continue; - if (c->geom.x + c->geom.width < tc->geom.x || - c->geom.x > tc->geom.x + tc->geom.width) - continue; - top = tc->geom.y - gappiv; - if (buttom < top && (ny + c->geom.height) > top) { - tar = MIN(tar, top - c->geom.height); - }; - } - ny = tar == 99999 ? ny : tar; - ny = MIN(ny, c->mon->w.y + c->mon->w.height - c->geom.height); - break; - case LEFT: - tar = -99999; - left = c->geom.x; - nx -= c->mon->w.width / 6; + wl_list_for_each(tc, &clients, link) { + if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) + continue; + if (c->geom.x + c->geom.width < tc->geom.x || + c->geom.x > tc->geom.x + tc->geom.width) + continue; + top = tc->geom.y - gappiv; + if (buttom < top && (ny + c->geom.height) > top) { + tar = MIN(tar, top - c->geom.height); + }; + } + ny = tar == 99999 ? ny : tar; + ny = MIN(ny, c->mon->w.y + c->mon->w.height - c->geom.height); + break; + case LEFT: + tar = -99999; + left = c->geom.x; + nx -= c->mon->w.width / 6; - wl_list_for_each(tc, &clients, link) { - if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) - continue; - if (c->geom.y + c->geom.height < tc->geom.y || - c->geom.y > tc->geom.y + tc->geom.height) - continue; - right = tc->geom.x + tc->geom.width + gappih; - if (left > right && nx < right) { - tar = MAX(tar, right); - }; - } + wl_list_for_each(tc, &clients, link) { + if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) + continue; + if (c->geom.y + c->geom.height < tc->geom.y || + c->geom.y > tc->geom.y + tc->geom.height) + continue; + right = tc->geom.x + tc->geom.width + gappih; + if (left > right && nx < right) { + tar = MAX(tar, right); + }; + } - nx = tar == -99999 ? nx : tar; - nx = MAX(nx, c->mon->w.x); - break; - case RIGHT: - tar = 99999; - right = c->geom.x + c->geom.width; - nx += c->mon->w.width / 6; - wl_list_for_each(tc, &clients, link) { - if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) - continue; - if (c->geom.y + c->geom.height < tc->geom.y || - c->geom.y > tc->geom.y + tc->geom.height) - continue; - left = tc->geom.x - gappih; - if (right < left && (nx + c->geom.width) > left) { - tar = MIN(tar, left - c->geom.width); - }; - } - nx = tar == 99999 ? nx : tar; - nx = MIN(nx, c->mon->w.x + c->mon->w.width - c->geom.width); - break; - } + nx = tar == -99999 ? nx : tar; + nx = MAX(nx, c->mon->w.x); + break; + case RIGHT: + tar = 99999; + right = c->geom.x + c->geom.width; + nx += c->mon->w.width / 6; + wl_list_for_each(tc, &clients, link) { + if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) + continue; + if (c->geom.y + c->geom.height < tc->geom.y || + c->geom.y > tc->geom.y + tc->geom.height) + continue; + left = tc->geom.x - gappih; + if (right < left && (nx + c->geom.width) > left) { + tar = MIN(tar, left - c->geom.width); + }; + } + nx = tar == 99999 ? nx : tar; + nx = MIN(nx, c->mon->w.x + c->mon->w.width - c->geom.width); + break; + } - c->oldgeom = (struct wlr_box){ - .x = nx, .y = ny, .width = c->geom.width, .height = c->geom.height}; + c->oldgeom = (struct wlr_box){ + .x = nx, .y = ny, .width = c->geom.width, .height = c->geom.height}; - resize(c, c->oldgeom, 1); + resize(c, c->oldgeom, 1); } void smartresizewin(const Arg *arg) { - Client *c, *tc; - int nw, nh; - int buttom, top, left, right, tar; - c = selmon->sel; - if (!c || c->isfullscreen) - return; - if (!c->isfloating) - setfloating(c, true); - nw = c->geom.width; - nh = c->geom.height; + Client *c, *tc; + int nw, nh; + int buttom, top, left, right, tar; + c = selmon->sel; + if (!c || c->isfullscreen) + return; + if (!c->isfloating) + setfloating(c, true); + nw = c->geom.width; + nh = c->geom.height; - switch (arg->i) { - case UP: - nh -= selmon->w.height / 8; - nh = MAX(nh, selmon->w.height / 10); - break; - case DOWN: - tar = -99999; - buttom = c->geom.y + c->geom.height; - nh += selmon->w.height / 8; + switch (arg->i) { + case UP: + nh -= selmon->w.height / 8; + nh = MAX(nh, selmon->w.height / 10); + break; + case DOWN: + tar = -99999; + buttom = c->geom.y + c->geom.height; + nh += selmon->w.height / 8; - wl_list_for_each(tc, &clients, link) { - if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) - continue; - if (c->geom.x + c->geom.width < tc->geom.x || - c->geom.x > tc->geom.x + tc->geom.width) - continue; - top = tc->geom.y - gappiv; - if (buttom < top && (nh + c->geom.y) > top) { - tar = MAX(tar, top - c->geom.y); - }; - } - nh = tar == -99999 ? nh : tar; - if (c->geom.y + nh + gappov > selmon->w.y + selmon->w.height) - nh = selmon->w.y + selmon->w.height - c->geom.y - gappov; - break; - case LEFT: - nw -= selmon->w.width / 16; - nw = MAX(nw, selmon->w.width / 10); - break; - case RIGHT: - tar = 99999; - right = c->geom.x + c->geom.width; - nw += selmon->w.width / 16; - wl_list_for_each(tc, &clients, link) { - if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) - continue; - if (c->geom.y + c->geom.height < tc->geom.y || - c->geom.y > tc->geom.y + tc->geom.height) - continue; - left = tc->geom.x - gappih; - if (right < left && (nw + c->geom.x) > left) { - tar = MIN(tar, left - c->geom.x); - }; - } + wl_list_for_each(tc, &clients, link) { + if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) + continue; + if (c->geom.x + c->geom.width < tc->geom.x || + c->geom.x > tc->geom.x + tc->geom.width) + continue; + top = tc->geom.y - gappiv; + if (buttom < top && (nh + c->geom.y) > top) { + tar = MAX(tar, top - c->geom.y); + }; + } + nh = tar == -99999 ? nh : tar; + if (c->geom.y + nh + gappov > selmon->w.y + selmon->w.height) + nh = selmon->w.y + selmon->w.height - c->geom.y - gappov; + break; + case LEFT: + nw -= selmon->w.width / 16; + nw = MAX(nw, selmon->w.width / 10); + break; + case RIGHT: + tar = 99999; + right = c->geom.x + c->geom.width; + nw += selmon->w.width / 16; + wl_list_for_each(tc, &clients, link) { + if (!VISIBLEON(tc, selmon) || !tc->isfloating || tc == c) + continue; + if (c->geom.y + c->geom.height < tc->geom.y || + c->geom.y > tc->geom.y + tc->geom.height) + continue; + left = tc->geom.x - gappih; + if (right < left && (nw + c->geom.x) > left) { + tar = MIN(tar, left - c->geom.x); + }; + } - nw = tar == 99999 ? nw : tar; - if (c->geom.x + nw + gappoh > selmon->w.x + selmon->w.width) - nw = selmon->w.x + selmon->w.width - c->geom.x - gappoh; - break; - } + nw = tar == 99999 ? nw : tar; + if (c->geom.x + nw + gappoh > selmon->w.x + selmon->w.width) + nw = selmon->w.x + selmon->w.width - c->geom.x - gappoh; + break; + } - c->oldgeom = (struct wlr_box){ - .x = c->geom.x, .y = c->geom.y, .width = nw, .height = nh}; + c->oldgeom = (struct wlr_box){ + .x = c->geom.x, .y = c->geom.y, .width = nw, .height = nh}; - resize(c, c->oldgeom, 1); + resize(c, c->oldgeom, 1); } #ifdef XWAYLAND void activatex11(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, activate); - bool need_arrange = false; + Client *c = wl_container_of(listener, c, activate); + bool need_arrange = false; - if (!c || c->iskilling || !c->foreign_toplevel || client_is_unmanaged(c)) - return; + if (!c || c->iskilling || !c->foreign_toplevel || client_is_unmanaged(c)) + return; - if (c && c->swallowing) - return; + if (c && c->swallowing) + return; - if (c->isminied) { - c->isminied = 0; - c->tags = c->mini_restore_tag; - c->is_scratchpad_show = 0; - c->is_in_scratchpad = 0; - c->isnamedscratchpand = 0; - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); - setborder_color(c); - if (VISIBLEON(c, c->mon)) { - need_arrange = true; - } - } + if (c->isminied) { + c->isminied = 0; + c->tags = c->mini_restore_tag; + c->is_scratchpad_show = 0; + c->is_in_scratchpad = 0; + c->isnamedscratchpand = 0; + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, + false); + setborder_color(c); + if (VISIBLEON(c, c->mon)) { + need_arrange = true; + } + } - if (focus_on_activate && c != selmon->sel) { - view(&(Arg){.ui = c->tags}, true); - wlr_xwayland_surface_activate(c->surface.xwayland, 1); - focusclient(c, 1); - need_arrange = false; - } else if (c != focustop(selmon)) { - c->isurgent = 1; - if (client_surface(c)->mapped) - client_set_border_color(c, urgentcolor); - } + if (focus_on_activate && c != selmon->sel) { + view(&(Arg){.ui = c->tags}, true); + wlr_xwayland_surface_activate(c->surface.xwayland, 1); + focusclient(c, 1); + need_arrange = false; + } else if (c != focustop(selmon)) { + c->isurgent = 1; + if (client_surface(c)->mapped) + client_set_border_color(c, urgentcolor); + } - if (need_arrange) { - arrange(c->mon, false); - } + if (need_arrange) { + arrange(c->mon, false); + } - printstatus(); + printstatus(); } void configurex11(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, configure); - struct wlr_xwayland_surface_configure_event *event = data; - if (!client_surface(c) || !client_surface(c)->mapped) { - wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, - event->width, event->height); - return; - } - if (client_is_unmanaged(c)) { - wlr_scene_node_set_position(&c->scene->node, event->x, event->y); - wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, - event->width, event->height); - return; - } - 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, - .width = event->width + c->bw * 2, - .height = event->height + c->bw * 2}, - 0); - } else { - arrange(c->mon, false); - } + Client *c = wl_container_of(listener, c, configure); + struct wlr_xwayland_surface_configure_event *event = data; + if (!client_surface(c) || !client_surface(c)->mapped) { + wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, + event->width, event->height); + return; + } + if (client_is_unmanaged(c)) { + wlr_scene_node_set_position(&c->scene->node, event->x, event->y); + wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y, + event->width, event->height); + return; + } + 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, + .width = event->width + c->bw * 2, + .height = event->height + c->bw * 2}, + 0); + } else { + arrange(c->mon, false); + } } void createnotifyx11(struct wl_listener *listener, void *data) { - struct wlr_xwayland_surface *xsurface = data; - Client *c; + struct wlr_xwayland_surface *xsurface = data; + Client *c; - /* Allocate a Client for this surface */ - c = xsurface->data = ecalloc(1, sizeof(*c)); - c->surface.xwayland = xsurface; - c->type = X11; - /* Listen to the various events it can emit */ - LISTEN(&xsurface->events.associate, &c->associate, associatex11); - LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify); - LISTEN(&xsurface->events.dissociate, &c->dissociate, dissociatex11); - LISTEN(&xsurface->events.request_activate, &c->activate, activatex11); - LISTEN(&xsurface->events.request_configure, &c->configure, configurex11); - LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, - fullscreennotify); - LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints); - LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle); - LISTEN(&xsurface->events.request_maximize, &c->maximize, maximizenotify); - LISTEN(&xsurface->events.request_minimize, &c->minimize, minimizenotify); + /* Allocate a Client for this surface */ + c = xsurface->data = ecalloc(1, sizeof(*c)); + c->surface.xwayland = xsurface; + c->type = X11; + /* Listen to the various events it can emit */ + LISTEN(&xsurface->events.associate, &c->associate, associatex11); + LISTEN(&xsurface->events.destroy, &c->destroy, destroynotify); + LISTEN(&xsurface->events.dissociate, &c->dissociate, dissociatex11); + LISTEN(&xsurface->events.request_activate, &c->activate, activatex11); + LISTEN(&xsurface->events.request_configure, &c->configure, configurex11); + LISTEN(&xsurface->events.request_fullscreen, &c->fullscreen, + fullscreennotify); + LISTEN(&xsurface->events.set_hints, &c->set_hints, sethints); + LISTEN(&xsurface->events.set_title, &c->set_title, updatetitle); + LISTEN(&xsurface->events.request_maximize, &c->maximize, maximizenotify); + LISTEN(&xsurface->events.request_minimize, &c->minimize, minimizenotify); } void associatex11(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, associate); + Client *c = wl_container_of(listener, c, associate); - LISTEN(&client_surface(c)->events.map, &c->map, mapnotify); - LISTEN(&client_surface(c)->events.unmap, &c->unmap, unmapnotify); + LISTEN(&client_surface(c)->events.map, &c->map, mapnotify); + LISTEN(&client_surface(c)->events.unmap, &c->unmap, unmapnotify); } void dissociatex11(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, dissociate); - wl_list_remove(&c->map.link); - wl_list_remove(&c->unmap.link); + Client *c = wl_container_of(listener, c, dissociate); + wl_list_remove(&c->map.link); + wl_list_remove(&c->unmap.link); } void sethints(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, set_hints); - struct wlr_surface *surface = client_surface(c); - if (c == focustop(selmon) || !c || !c->surface.xwayland->hints) - return; + Client *c = wl_container_of(listener, c, set_hints); + struct wlr_surface *surface = client_surface(c); + if (c == focustop(selmon) || !c || !c->surface.xwayland->hints) + return; - c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); - printstatus(); + c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); + printstatus(); - if (c->isurgent && surface && surface->mapped) - client_set_border_color(c, urgentcolor); + if (c->isurgent && surface && surface->mapped) + client_set_border_color(c, urgentcolor); } void xwaylandready(struct wl_listener *listener, void *data) { - struct wlr_xcursor *xcursor; + struct wlr_xcursor *xcursor; - /* assign the one and only seat */ - wlr_xwayland_set_seat(xwayland, seat); + /* assign the one and only seat */ + wlr_xwayland_set_seat(xwayland, seat); - /* Set the default XWayland cursor to match the rest of dwl. */ - if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "default", 1))) - wlr_xwayland_set_cursor( - xwayland, xcursor->images[0]->buffer, xcursor->images[0]->width * 4, - xcursor->images[0]->width, xcursor->images[0]->height, - xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); + /* Set the default XWayland cursor to match the rest of dwl. */ + if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "default", 1))) + wlr_xwayland_set_cursor( + xwayland, xcursor->images[0]->buffer, xcursor->images[0]->width * 4, + xcursor->images[0]->width, xcursor->images[0]->height, + xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); } static void setgeometrynotify(struct wl_listener *listener, void *data) { - Client *c = wl_container_of(listener, c, set_geometry); + Client *c = wl_container_of(listener, c, set_geometry); - struct wlr_xwayland_surface *xsurface = c->surface.xwayland; - wlr_scene_node_set_position(&c->scene->node, xsurface->x, xsurface->y); - motionnotify(0, NULL, 0, 0, 0, 0); + struct wlr_xwayland_surface *xsurface = c->surface.xwayland; + wlr_scene_node_set_position(&c->scene->node, xsurface->x, xsurface->y); + motionnotify(0, NULL, 0, 0, 0, 0); } #endif int main(int argc, char *argv[]) { - char *startup_cmd = NULL; - int c; + char *startup_cmd = NULL; + int c; - while ((c = getopt(argc, argv, "s:hdv")) != -1) { - if (c == 's') - startup_cmd = optarg; - else if (c == 'd') - log_level = WLR_DEBUG; - else if (c == 'v') - die("maomao " VERSION); - else - goto usage; - } - if (optind < argc) - goto usage; + while ((c = getopt(argc, argv, "s:hdv")) != -1) { + if (c == 's') + startup_cmd = optarg; + else if (c == 'd') + log_level = WLR_DEBUG; + else if (c == 'v') + die("maomao " VERSION); + else + goto usage; + } + if (optind < argc) + goto usage; - /* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */ - if (!getenv("XDG_RUNTIME_DIR")) - die("XDG_RUNTIME_DIR must be set"); - setup(); - run(startup_cmd); - cleanup(); - return EXIT_SUCCESS; + /* Wayland requires XDG_RUNTIME_DIR for creating its communications socket + */ + if (!getenv("XDG_RUNTIME_DIR")) + die("XDG_RUNTIME_DIR must be set"); + setup(); + run(startup_cmd); + cleanup(); + return EXIT_SUCCESS; usage: - die("Usage: %s [-v] [-d] [-s startup command]", argv[0]); + die("Usage: %s [-v] [-d] [-s startup command]", argv[0]); } diff --git a/src/text_input/ime.h b/src/text_input/ime.h index 4143541..38cbb4b 100644 --- a/src/text_input/ime.h +++ b/src/text_input/ime.h @@ -9,12 +9,12 @@ #define DWL_SET_MAX_SIZE 16 #define SAME_CLIENT(wlr_obj1, wlr_obj2) \ - (wl_resource_get_client((wlr_obj1)->resource) == \ - wl_resource_get_client((wlr_obj2)->resource)) + (wl_resource_get_client((wlr_obj1)->resource) == \ + wl_resource_get_client((wlr_obj2)->resource)) struct dwl_set { - uint32_t values[DWL_SET_MAX_SIZE]; - int size; + uint32_t values[DWL_SET_MAX_SIZE]; + int size; }; /* @@ -25,56 +25,56 @@ struct dwl_set { * an active text-input is present, the relay passes messages between them. */ struct input_method_relay { - struct wl_list text_inputs; /* struct text_input.link */ - struct wlr_input_method_v2 *input_method; - struct wlr_surface *focused_surface; + struct wl_list text_inputs; /* struct text_input.link */ + struct wlr_input_method_v2 *input_method; + struct wlr_surface *focused_surface; - struct dwl_set forwarded_pressed_keys; - struct wlr_keyboard_modifiers forwarded_modifiers; + struct dwl_set forwarded_pressed_keys; + struct wlr_keyboard_modifiers forwarded_modifiers; - /* - * Text-input which is enabled by the client and communicating with - * input-method. - * This must be NULL if input-method is not present. - * Its client must be the same as that of focused_surface. - */ - struct text_input *active_text_input; + /* + * Text-input which is enabled by the client and communicating with + * input-method. + * This must be NULL if input-method is not present. + * Its client must be the same as that of focused_surface. + */ + struct text_input *active_text_input; - struct wl_list popups; /* input_method_popup.link */ - struct wlr_scene_tree *popup_tree; + struct wl_list popups; /* input_method_popup.link */ + struct wlr_scene_tree *popup_tree; - struct wl_listener new_text_input; - struct wl_listener new_input_method; + struct wl_listener new_text_input; + struct wl_listener new_input_method; - struct wl_listener input_method_commit; - struct wl_listener input_method_grab_keyboard; - struct wl_listener input_method_destroy; - struct wl_listener input_method_new_popup_surface; + struct wl_listener input_method_commit; + struct wl_listener input_method_grab_keyboard; + struct wl_listener input_method_destroy; + struct wl_listener input_method_new_popup_surface; - struct wl_listener keyboard_grab_destroy; - struct wl_listener focused_surface_destroy; + struct wl_listener keyboard_grab_destroy; + struct wl_listener focused_surface_destroy; }; struct input_method_popup { - struct wlr_input_popup_surface_v2 *popup_surface; - struct wlr_scene_tree *tree; - struct wlr_scene_tree *scene_surface; - struct input_method_relay *relay; - struct wl_list link; /* input_method_relay.popups */ + struct wlr_input_popup_surface_v2 *popup_surface; + struct wlr_scene_tree *tree; + struct wlr_scene_tree *scene_surface; + struct input_method_relay *relay; + struct wl_list link; /* input_method_relay.popups */ - struct wl_listener destroy; - struct wl_listener commit; + struct wl_listener destroy; + struct wl_listener commit; }; struct text_input { - struct input_method_relay *relay; - struct wlr_text_input_v3 *input; - struct wl_list link; + struct input_method_relay *relay; + struct wlr_text_input_v3 *input; + struct wl_list link; - struct wl_listener enable; - struct wl_listener commit; - struct wl_listener disable; - struct wl_listener destroy; + struct wl_listener enable; + struct wl_listener commit; + struct wl_listener disable; + struct wl_listener destroy; }; struct wlr_input_method_manager_v2 *input_method_manager; @@ -87,7 +87,7 @@ struct input_method_relay *input_method_relay; * Returns true if the key event was forwarded. */ bool input_method_keyboard_grab_forward_key( - KeyboardGroup *keyboard, struct wlr_keyboard_key_event *event); + KeyboardGroup *keyboard, struct wlr_keyboard_key_event *event); /* * Forward modifier state to keyboard grab of the seat from the keyboard @@ -102,73 +102,73 @@ void input_method_relay_finish(struct input_method_relay *relay); /* Updates currently focused surface. Surface must belong to the same seat. */ void input_method_relay_set_focus(struct input_method_relay *relay, - struct wlr_surface *surface); + struct wlr_surface *surface); bool dwl_set_contains(struct dwl_set *set, uint32_t value) { - for (int i = 0; i < set->size; ++i) { - if (set->values[i] == value) { - return true; - } - } - return false; + for (int i = 0; i < set->size; ++i) { + if (set->values[i] == value) { + return true; + } + } + return false; } void dwl_set_add(struct dwl_set *set, uint32_t value) { - if (dwl_set_contains(set, value)) { - return; - } - if (set->size >= DWL_SET_MAX_SIZE) { - wlr_log(WLR_ERROR, "dwl_set size exceeded"); - return; - } - set->values[set->size++] = value; + if (dwl_set_contains(set, value)) { + return; + } + if (set->size >= DWL_SET_MAX_SIZE) { + wlr_log(WLR_ERROR, "dwl_set size exceeded"); + return; + } + set->values[set->size++] = value; } void dwl_set_remove(struct dwl_set *set, uint32_t value) { - for (int i = 0; i < set->size; ++i) { - if (set->values[i] == value) { - --set->size; - set->values[i] = set->values[set->size]; - return; - } - } + for (int i = 0; i < set->size; ++i) { + if (set->values[i] == value) { + --set->size; + set->values[i] = set->values[set->size]; + return; + } + } } Monitor *output_from_wlr_output(struct wlr_output *wlr_output) { - Monitor *m; - wl_list_for_each(m, &mons, link) { - if (m->wlr_output == wlr_output) { - return m; - } - } - return NULL; + Monitor *m; + wl_list_for_each(m, &mons, link) { + if (m->wlr_output == wlr_output) { + return m; + } + } + return NULL; } Monitor *output_nearest_to(int lx, int ly) { - double closest_x, closest_y; - wlr_output_layout_closest_point(output_layout, NULL, lx, ly, &closest_x, - &closest_y); + double closest_x, closest_y; + wlr_output_layout_closest_point(output_layout, NULL, lx, ly, &closest_x, + &closest_y); - return output_from_wlr_output( - wlr_output_layout_output_at(output_layout, closest_x, closest_y)); + return output_from_wlr_output( + wlr_output_layout_output_at(output_layout, closest_x, closest_y)); } bool output_is_usable(Monitor *m) { - /* output_is_usable(NULL) is safe and returns false */ - return m && m->wlr_output->enabled; + /* output_is_usable(NULL) is safe and returns false */ + return m && m->wlr_output->enabled; } static bool is_keyboard_emulated_by_input_method(struct wlr_keyboard *keyboard, - struct wlr_input_method_v2 *input_method) { - if (!keyboard || !input_method) { - return false; - } + struct wlr_input_method_v2 *input_method) { + if (!keyboard || !input_method) { + return false; + } - struct wlr_virtual_keyboard_v1 *virtual_keyboard = - wlr_input_device_get_virtual_keyboard(&keyboard->base); + struct wlr_virtual_keyboard_v1 *virtual_keyboard = + wlr_input_device_get_virtual_keyboard(&keyboard->base); - return virtual_keyboard && SAME_CLIENT(virtual_keyboard, input_method); + return virtual_keyboard && SAME_CLIENT(virtual_keyboard, input_method); } /* @@ -177,85 +177,86 @@ is_keyboard_emulated_by_input_method(struct wlr_keyboard *keyboard, */ static struct wlr_input_method_keyboard_grab_v2 * get_keyboard_grab(KeyboardGroup *keyboard) { - struct wlr_input_method_v2 *input_method = input_method_relay->input_method; - if (!input_method || !input_method->keyboard_grab) { - return NULL; - } + struct wlr_input_method_v2 *input_method = input_method_relay->input_method; + if (!input_method || !input_method->keyboard_grab) { + return NULL; + } - // labwc not need this , but maomao need - if (keyboard != kb_group) - return NULL; + // labwc not need this , but maomao need + if (keyboard != kb_group) + return NULL; - /* - * Input-methods often use virtual keyboard to send raw key signals - * instead of sending encoded text via set_preedit_string and - * commit_string. We should not forward those key events back to the - * input-method so key events don't loop between the compositor and - * the input-method. - */ - if (is_keyboard_emulated_by_input_method(&keyboard->wlr_group->keyboard, - input_method)) { - return NULL; - } + /* + * Input-methods often use virtual keyboard to send raw key signals + * instead of sending encoded text via set_preedit_string and + * commit_string. We should not forward those key events back to the + * input-method so key events don't loop between the compositor and + * the input-method. + */ + if (is_keyboard_emulated_by_input_method(&keyboard->wlr_group->keyboard, + input_method)) { + return NULL; + } - return input_method->keyboard_grab; + return input_method->keyboard_grab; } bool input_method_keyboard_grab_forward_modifiers(KeyboardGroup *keyboard) { - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = - get_keyboard_grab(keyboard); + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = + get_keyboard_grab(keyboard); - struct wlr_keyboard_modifiers *forwarded_modifiers = - &input_method_relay->forwarded_modifiers; - struct wlr_keyboard_modifiers *modifiers = - &keyboard->wlr_group->keyboard.modifiers; + struct wlr_keyboard_modifiers *forwarded_modifiers = + &input_method_relay->forwarded_modifiers; + struct wlr_keyboard_modifiers *modifiers = + &keyboard->wlr_group->keyboard.modifiers; - if (forwarded_modifiers->depressed == modifiers->depressed && - forwarded_modifiers->latched == modifiers->latched && - forwarded_modifiers->locked == modifiers->locked && - forwarded_modifiers->group == modifiers->group) { - return false; - } + if (forwarded_modifiers->depressed == modifiers->depressed && + forwarded_modifiers->latched == modifiers->latched && + forwarded_modifiers->locked == modifiers->locked && + forwarded_modifiers->group == modifiers->group) { + return false; + } - if (keyboard_grab) { - *forwarded_modifiers = keyboard->wlr_group->keyboard.modifiers; - wlr_input_method_keyboard_grab_v2_set_keyboard( - keyboard_grab, &keyboard->wlr_group->keyboard); - wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab, modifiers); - return true; - } else { - return false; - } + if (keyboard_grab) { + *forwarded_modifiers = keyboard->wlr_group->keyboard.modifiers; + wlr_input_method_keyboard_grab_v2_set_keyboard( + keyboard_grab, &keyboard->wlr_group->keyboard); + wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab, + modifiers); + return true; + } else { + return false; + } } bool input_method_keyboard_grab_forward_key( - KeyboardGroup *keyboard, struct wlr_keyboard_key_event *event) { - /* - * We should not forward key-release events without corresponding - * key-press events forwarded - */ - struct dwl_set *pressed_keys = &input_method_relay->forwarded_pressed_keys; - if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED && - !dwl_set_contains(pressed_keys, event->keycode)) { - return false; - } + KeyboardGroup *keyboard, struct wlr_keyboard_key_event *event) { + /* + * We should not forward key-release events without corresponding + * key-press events forwarded + */ + struct dwl_set *pressed_keys = &input_method_relay->forwarded_pressed_keys; + if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED && + !dwl_set_contains(pressed_keys, event->keycode)) { + return false; + } - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = - get_keyboard_grab(keyboard); - if (keyboard_grab) { - if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - dwl_set_add(pressed_keys, event->keycode); - } else { - dwl_set_remove(pressed_keys, event->keycode); - } - wlr_input_method_keyboard_grab_v2_set_keyboard( - keyboard_grab, &keyboard->wlr_group->keyboard); - wlr_input_method_keyboard_grab_v2_send_key(keyboard_grab, event->time_msec, - event->keycode, event->state); - return true; - } else { - return false; - } + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = + get_keyboard_grab(keyboard); + if (keyboard_grab) { + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + dwl_set_add(pressed_keys, event->keycode); + } else { + dwl_set_remove(pressed_keys, event->keycode); + } + wlr_input_method_keyboard_grab_v2_set_keyboard( + keyboard_grab, &keyboard->wlr_group->keyboard); + wlr_input_method_keyboard_grab_v2_send_key( + keyboard_grab, event->time_msec, event->keycode, event->state); + return true; + } else { + return false; + } } /* @@ -264,17 +265,17 @@ bool input_method_keyboard_grab_forward_key( */ static struct text_input * get_active_text_input(struct input_method_relay *relay) { - if (!relay->input_method) { - return NULL; - } - struct text_input *text_input; - wl_list_for_each(text_input, &relay->text_inputs, link) { - if (text_input->input->focused_surface && - text_input->input->current_enabled) { - return text_input; - } - } - return NULL; + if (!relay->input_method) { + return NULL; + } + struct text_input *text_input; + wl_list_for_each(text_input, &relay->text_inputs, link) { + if (text_input->input->focused_surface && + text_input->input->current_enabled) { + return text_input; + } + } + return NULL; } /* @@ -282,18 +283,18 @@ get_active_text_input(struct input_method_relay *relay) { * value is changed. */ static void update_active_text_input(struct input_method_relay *relay) { - struct text_input *active_text_input = get_active_text_input(relay); + struct text_input *active_text_input = get_active_text_input(relay); - if (relay->input_method && relay->active_text_input != active_text_input) { - if (active_text_input) { - wlr_input_method_v2_send_activate(relay->input_method); - } else { - wlr_input_method_v2_send_deactivate(relay->input_method); - } - wlr_input_method_v2_send_done(relay->input_method); - } + if (relay->input_method && relay->active_text_input != active_text_input) { + if (active_text_input) { + wlr_input_method_v2_send_activate(relay->input_method); + } else { + wlr_input_method_v2_send_deactivate(relay->input_method); + } + wlr_input_method_v2_send_done(relay->input_method); + } - relay->active_text_input = active_text_input; + relay->active_text_input = active_text_input; } /* @@ -306,376 +307,384 @@ static void update_active_text_input(struct input_method_relay *relay) { */ static void update_text_inputs_focused_surface(struct input_method_relay *relay) { - struct text_input *text_input; - wl_list_for_each(text_input, &relay->text_inputs, link) { - struct wlr_text_input_v3 *input = text_input->input; + struct text_input *text_input; + wl_list_for_each(text_input, &relay->text_inputs, link) { + struct wlr_text_input_v3 *input = text_input->input; - struct wlr_surface *new_focused_surface; - if (relay->input_method && relay->focused_surface && - SAME_CLIENT(input, relay->focused_surface)) { - new_focused_surface = relay->focused_surface; - } else { - new_focused_surface = NULL; - } + struct wlr_surface *new_focused_surface; + if (relay->input_method && relay->focused_surface && + SAME_CLIENT(input, relay->focused_surface)) { + new_focused_surface = relay->focused_surface; + } else { + new_focused_surface = NULL; + } - if (input->focused_surface == new_focused_surface) { - continue; - } - if (input->focused_surface) { - wlr_text_input_v3_send_leave(input); - } - if (new_focused_surface) { - wlr_text_input_v3_send_enter(input, new_focused_surface); - } - } + if (input->focused_surface == new_focused_surface) { + continue; + } + if (input->focused_surface) { + wlr_text_input_v3_send_leave(input); + } + if (new_focused_surface) { + wlr_text_input_v3_send_enter(input, new_focused_surface); + } + } } static void update_popup_position(struct input_method_popup *popup) { - struct input_method_relay *relay = popup->relay; - struct text_input *text_input = relay->active_text_input; + struct input_method_relay *relay = popup->relay; + struct text_input *text_input = relay->active_text_input; - if (!text_input || !relay->focused_surface || - !popup->popup_surface->surface->mapped) { - return; - } + if (!text_input || !relay->focused_surface || + !popup->popup_surface->surface->mapped) { + return; + } - struct wlr_box cursor_rect; - struct wlr_xdg_surface *xdg_surface = - wlr_xdg_surface_try_from_wlr_surface(relay->focused_surface); - struct wlr_layer_surface_v1 *layer_surface = - wlr_layer_surface_v1_try_from_wlr_surface(relay->focused_surface); + struct wlr_box cursor_rect; + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_try_from_wlr_surface(relay->focused_surface); + struct wlr_layer_surface_v1 *layer_surface = + wlr_layer_surface_v1_try_from_wlr_surface(relay->focused_surface); - if ((text_input->input->current.features & - WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE) && - (xdg_surface || layer_surface)) { - cursor_rect = text_input->input->current.cursor_rectangle; + if ((text_input->input->current.features & + WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE) && + (xdg_surface || layer_surface)) { + cursor_rect = text_input->input->current.cursor_rectangle; - /* - * wlr_surface->data is: - * - for XDG surfaces: view->content_tree - * - for layer surfaces: dwl_layer_surface->scene_layer_surface->tree - * - for layer popups: dwl_layer_popup->scene_tree - */ - struct wlr_scene_tree *tree = relay->focused_surface->data; - int lx, ly; - wlr_scene_node_coords(&tree->node, &lx, &ly); - cursor_rect.x += lx; - cursor_rect.y += ly; + /* + * wlr_surface->data is: + * - for XDG surfaces: view->content_tree + * - for layer surfaces: dwl_layer_surface->scene_layer_surface->tree + * - for layer popups: dwl_layer_popup->scene_tree + */ + struct wlr_scene_tree *tree = relay->focused_surface->data; + int lx, ly; + wlr_scene_node_coords(&tree->node, &lx, &ly); + cursor_rect.x += lx; + cursor_rect.y += ly; - if (xdg_surface) { - /* Take into account invisible xdg-shell CSD borders */ - cursor_rect.x -= xdg_surface->geometry.x; - cursor_rect.y -= xdg_surface->geometry.y; - } - } else { - cursor_rect = (struct wlr_box){0}; - } + if (xdg_surface) { + /* Take into account invisible xdg-shell CSD borders */ + cursor_rect.x -= xdg_surface->geometry.x; + cursor_rect.y -= xdg_surface->geometry.y; + } + } else { + cursor_rect = (struct wlr_box){0}; + } - Monitor *output = output_nearest_to(cursor_rect.x, cursor_rect.y); - if (!output_is_usable(output)) { - wlr_log(WLR_ERROR, "Cannot position IME popup (unusable output)"); - return; - } - struct wlr_box output_box; - wlr_output_layout_get_box(output_layout, output->wlr_output, &output_box); + Monitor *output = output_nearest_to(cursor_rect.x, cursor_rect.y); + if (!output_is_usable(output)) { + wlr_log(WLR_ERROR, "Cannot position IME popup (unusable output)"); + return; + } + struct wlr_box output_box; + wlr_output_layout_get_box(output_layout, output->wlr_output, &output_box); - /* Use xdg-positioner utilities to position popup */ - struct wlr_xdg_positioner_rules rules = { - .anchor_rect = cursor_rect, - .anchor = XDG_POSITIONER_ANCHOR_BOTTOM_LEFT, - .gravity = XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT, - .size = - { - .width = popup->popup_surface->surface->current.width, - .height = popup->popup_surface->surface->current.height, - }, - .constraint_adjustment = XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y | - XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X, - }; + /* Use xdg-positioner utilities to position popup */ + struct wlr_xdg_positioner_rules rules = { + .anchor_rect = cursor_rect, + .anchor = XDG_POSITIONER_ANCHOR_BOTTOM_LEFT, + .gravity = XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT, + .size = + { + .width = popup->popup_surface->surface->current.width, + .height = popup->popup_surface->surface->current.height, + }, + .constraint_adjustment = XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y | + XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X, + }; - struct wlr_box popup_box; - wlr_xdg_positioner_rules_get_geometry(&rules, &popup_box); - wlr_xdg_positioner_rules_unconstrain_box(&rules, &output_box, &popup_box); + struct wlr_box popup_box; + wlr_xdg_positioner_rules_get_geometry(&rules, &popup_box); + wlr_xdg_positioner_rules_unconstrain_box(&rules, &output_box, &popup_box); - wlr_scene_node_set_position(&popup->tree->node, popup_box.x, popup_box.y); - /* Make sure IME popups are always on top, above layer-shell surfaces */ - wlr_scene_node_raise_to_top(&relay->popup_tree->node); + wlr_scene_node_set_position(&popup->tree->node, popup_box.x, popup_box.y); + /* Make sure IME popups are always on top, above layer-shell surfaces */ + wlr_scene_node_raise_to_top(&relay->popup_tree->node); - wlr_input_popup_surface_v2_send_text_input_rectangle( - popup->popup_surface, &(struct wlr_box){ - .x = cursor_rect.x - popup_box.x, - .y = cursor_rect.y - popup_box.y, - .width = cursor_rect.width, - .height = cursor_rect.height, - }); + wlr_input_popup_surface_v2_send_text_input_rectangle( + popup->popup_surface, &(struct wlr_box){ + .x = cursor_rect.x - popup_box.x, + .y = cursor_rect.y - popup_box.y, + .width = cursor_rect.width, + .height = cursor_rect.height, + }); } static void update_popups_position(struct input_method_relay *relay) { - struct input_method_popup *popup; - wl_list_for_each(popup, &relay->popups, link) { - update_popup_position(popup); - } + struct input_method_popup *popup; + wl_list_for_each(popup, &relay->popups, link) { + update_popup_position(popup); + } } static void handle_input_method_commit(struct wl_listener *listener, - void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, input_method_commit); - struct wlr_input_method_v2 *input_method = data; - assert(relay->input_method == input_method); + void *data) { + struct input_method_relay *relay = + wl_container_of(listener, relay, input_method_commit); + struct wlr_input_method_v2 *input_method = data; + assert(relay->input_method == input_method); - struct text_input *text_input = relay->active_text_input; - if (!text_input) { - return; - } + struct text_input *text_input = relay->active_text_input; + if (!text_input) { + return; + } - if (input_method->current.preedit.text) { - wlr_text_input_v3_send_preedit_string( - text_input->input, input_method->current.preedit.text, - input_method->current.preedit.cursor_begin, - input_method->current.preedit.cursor_end); - } - if (input_method->current.commit_text) { - wlr_text_input_v3_send_commit_string(text_input->input, - input_method->current.commit_text); - } - if (input_method->current.delete.before_length || - input_method->current.delete.after_length) { - wlr_text_input_v3_send_delete_surrounding_text( - text_input->input, input_method->current.delete.before_length, - input_method->current.delete.after_length); - } - wlr_text_input_v3_send_done(text_input->input); + if (input_method->current.preedit.text) { + wlr_text_input_v3_send_preedit_string( + text_input->input, input_method->current.preedit.text, + input_method->current.preedit.cursor_begin, + input_method->current.preedit.cursor_end); + } + if (input_method->current.commit_text) { + wlr_text_input_v3_send_commit_string(text_input->input, + input_method->current.commit_text); + } + if (input_method->current.delete.before_length || + input_method->current.delete.after_length) { + wlr_text_input_v3_send_delete_surrounding_text( + text_input->input, input_method->current.delete.before_length, + input_method->current.delete.after_length); + } + wlr_text_input_v3_send_done(text_input->input); } static void handle_keyboard_grab_destroy(struct wl_listener *listener, - void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, keyboard_grab_destroy); - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; - wl_list_remove(&relay->keyboard_grab_destroy.link); + void *data) { + struct input_method_relay *relay = + wl_container_of(listener, relay, keyboard_grab_destroy); + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; + wl_list_remove(&relay->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); - } + 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_input_method_grab_keyboard(struct wl_listener *listener, - void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, input_method_grab_keyboard); - struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; + void *data) { + struct input_method_relay *relay = + wl_container_of(listener, relay, input_method_grab_keyboard); + struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data; - struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(seat); + struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(seat); - if (!is_keyboard_emulated_by_input_method(active_keyboard, - relay->input_method)) { - /* Send modifier state to grab */ - wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab, - active_keyboard); - } + if (!is_keyboard_emulated_by_input_method(active_keyboard, + relay->input_method)) { + /* Send modifier state to grab */ + wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab, + active_keyboard); + } - relay->forwarded_pressed_keys = (struct dwl_set){0}; - relay->forwarded_modifiers = (struct wlr_keyboard_modifiers){0}; + relay->forwarded_pressed_keys = (struct dwl_set){0}; + relay->forwarded_modifiers = (struct wlr_keyboard_modifiers){0}; - relay->keyboard_grab_destroy.notify = handle_keyboard_grab_destroy; - wl_signal_add(&keyboard_grab->events.destroy, &relay->keyboard_grab_destroy); + relay->keyboard_grab_destroy.notify = handle_keyboard_grab_destroy; + wl_signal_add(&keyboard_grab->events.destroy, + &relay->keyboard_grab_destroy); } static void handle_input_method_destroy(struct wl_listener *listener, - void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, input_method_destroy); - assert(relay->input_method == data); - wl_list_remove(&relay->input_method_commit.link); - wl_list_remove(&relay->input_method_grab_keyboard.link); - wl_list_remove(&relay->input_method_new_popup_surface.link); - wl_list_remove(&relay->input_method_destroy.link); - relay->input_method = NULL; + void *data) { + struct input_method_relay *relay = + wl_container_of(listener, relay, input_method_destroy); + assert(relay->input_method == data); + wl_list_remove(&relay->input_method_commit.link); + wl_list_remove(&relay->input_method_grab_keyboard.link); + wl_list_remove(&relay->input_method_new_popup_surface.link); + wl_list_remove(&relay->input_method_destroy.link); + relay->input_method = NULL; - update_text_inputs_focused_surface(relay); - update_active_text_input(relay); + update_text_inputs_focused_surface(relay); + update_active_text_input(relay); } static void handle_popup_surface_destroy(struct wl_listener *listener, - void *data) { - struct input_method_popup *popup = wl_container_of(listener, popup, destroy); - wlr_scene_node_destroy(&popup->tree->node); - wl_list_remove(&popup->destroy.link); - wl_list_remove(&popup->commit.link); - wl_list_remove(&popup->link); - free(popup); + void *data) { + struct input_method_popup *popup = + wl_container_of(listener, popup, destroy); + wlr_scene_node_destroy(&popup->tree->node); + wl_list_remove(&popup->destroy.link); + wl_list_remove(&popup->commit.link); + wl_list_remove(&popup->link); + free(popup); } static void handle_popup_surface_commit(struct wl_listener *listener, - void *data) { - struct input_method_popup *popup = wl_container_of(listener, popup, commit); - update_popup_position(popup); + void *data) { + struct input_method_popup *popup = wl_container_of(listener, popup, commit); + update_popup_position(popup); } static void handle_input_method_new_popup_surface(struct wl_listener *listener, - void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, input_method_new_popup_surface); + void *data) { + struct input_method_relay *relay = + wl_container_of(listener, relay, input_method_new_popup_surface); - struct input_method_popup *popup = znew(*popup); - popup->popup_surface = data; - popup->relay = relay; + struct input_method_popup *popup = znew(*popup); + popup->popup_surface = data; + popup->relay = relay; - popup->destroy.notify = handle_popup_surface_destroy; - wl_signal_add(&popup->popup_surface->events.destroy, &popup->destroy); + popup->destroy.notify = handle_popup_surface_destroy; + wl_signal_add(&popup->popup_surface->events.destroy, &popup->destroy); - popup->commit.notify = handle_popup_surface_commit; - wl_signal_add(&popup->popup_surface->surface->events.commit, &popup->commit); + popup->commit.notify = handle_popup_surface_commit; + wl_signal_add(&popup->popup_surface->surface->events.commit, + &popup->commit); - // popup->tree = wlr_scene_subsurface_tree_create( - // relay->popup_tree, popup->popup_surface->surface); - // node_descriptor_create(&popup->tree->node, dwl_NODE_DESC_IME_POPUP, NULL); + // popup->tree = wlr_scene_subsurface_tree_create( + // relay->popup_tree, popup->popup_surface->surface); + // node_descriptor_create(&popup->tree->node, dwl_NODE_DESC_IME_POPUP, + // NULL); - popup->tree = wlr_scene_tree_create(layers[LyrIMPopup]); - popup->scene_surface = wlr_scene_subsurface_tree_create( - popup->tree, popup->popup_surface->surface); - popup->scene_surface->node.data = popup; + popup->tree = wlr_scene_tree_create(layers[LyrIMPopup]); + popup->scene_surface = wlr_scene_subsurface_tree_create( + popup->tree, popup->popup_surface->surface); + popup->scene_surface->node.data = popup; - wl_list_insert(&relay->popups, &popup->link); + wl_list_insert(&relay->popups, &popup->link); - update_popup_position(popup); + update_popup_position(popup); } static void handle_new_input_method(struct wl_listener *listener, void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, new_input_method); - struct wlr_input_method_v2 *input_method = data; - if (seat != input_method->seat) { - return; - } + struct input_method_relay *relay = + wl_container_of(listener, relay, new_input_method); + struct wlr_input_method_v2 *input_method = data; + if (seat != input_method->seat) { + return; + } - if (relay->input_method) { - wlr_log(WLR_INFO, "Attempted to connect second input method to a seat"); - wlr_input_method_v2_send_unavailable(input_method); - return; - } + if (relay->input_method) { + wlr_log(WLR_INFO, "Attempted to connect second input method to a seat"); + wlr_input_method_v2_send_unavailable(input_method); + return; + } - relay->input_method = input_method; + relay->input_method = input_method; - relay->input_method_commit.notify = handle_input_method_commit; - wl_signal_add(&relay->input_method->events.commit, - &relay->input_method_commit); + relay->input_method_commit.notify = handle_input_method_commit; + wl_signal_add(&relay->input_method->events.commit, + &relay->input_method_commit); - relay->input_method_grab_keyboard.notify = handle_input_method_grab_keyboard; - wl_signal_add(&relay->input_method->events.grab_keyboard, - &relay->input_method_grab_keyboard); + relay->input_method_grab_keyboard.notify = + handle_input_method_grab_keyboard; + wl_signal_add(&relay->input_method->events.grab_keyboard, + &relay->input_method_grab_keyboard); - relay->input_method_destroy.notify = handle_input_method_destroy; - wl_signal_add(&relay->input_method->events.destroy, - &relay->input_method_destroy); + relay->input_method_destroy.notify = handle_input_method_destroy; + wl_signal_add(&relay->input_method->events.destroy, + &relay->input_method_destroy); - relay->input_method_new_popup_surface.notify = - handle_input_method_new_popup_surface; - wl_signal_add(&relay->input_method->events.new_popup_surface, - &relay->input_method_new_popup_surface); + relay->input_method_new_popup_surface.notify = + handle_input_method_new_popup_surface; + wl_signal_add(&relay->input_method->events.new_popup_surface, + &relay->input_method_new_popup_surface); - update_text_inputs_focused_surface(relay); - update_active_text_input(relay); + update_text_inputs_focused_surface(relay); + update_active_text_input(relay); } /* Conveys state from active text-input to input-method */ static void send_state_to_input_method(struct input_method_relay *relay) { - assert(relay->active_text_input && relay->input_method); + assert(relay->active_text_input && relay->input_method); - struct wlr_input_method_v2 *input_method = relay->input_method; - struct wlr_text_input_v3 *input = relay->active_text_input->input; + struct wlr_input_method_v2 *input_method = relay->input_method; + struct wlr_text_input_v3 *input = relay->active_text_input->input; - /* TODO: only send each of those if they were modified */ - if (input->active_features & WLR_TEXT_INPUT_V3_FEATURE_SURROUNDING_TEXT) { - 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); - if (input->active_features & WLR_TEXT_INPUT_V3_FEATURE_CONTENT_TYPE) { - 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: only send each of those if they were modified */ + if (input->active_features & WLR_TEXT_INPUT_V3_FEATURE_SURROUNDING_TEXT) { + 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); + if (input->active_features & WLR_TEXT_INPUT_V3_FEATURE_CONTENT_TYPE) { + 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); } static void handle_text_input_enable(struct wl_listener *listener, void *data) { - struct text_input *text_input = wl_container_of(listener, text_input, enable); - struct input_method_relay *relay = text_input->relay; + struct text_input *text_input = + wl_container_of(listener, text_input, enable); + struct input_method_relay *relay = text_input->relay; - update_active_text_input(relay); - if (relay->active_text_input == text_input) { - update_popups_position(relay); - send_state_to_input_method(relay); - } + update_active_text_input(relay); + if (relay->active_text_input == text_input) { + update_popups_position(relay); + send_state_to_input_method(relay); + } } static void handle_text_input_disable(struct wl_listener *listener, - void *data) { - struct text_input *text_input = - wl_container_of(listener, text_input, disable); - /* - * When the focus is moved between surfaces from different clients and - * then the old client sends "disable" event, the relay ignores it and - * doesn't deactivate the input-method. - */ - update_active_text_input(text_input->relay); + void *data) { + struct text_input *text_input = + wl_container_of(listener, text_input, disable); + /* + * When the focus is moved between surfaces from different clients and + * then the old client sends "disable" event, the relay ignores it and + * doesn't deactivate the input-method. + */ + update_active_text_input(text_input->relay); } static void handle_text_input_commit(struct wl_listener *listener, void *data) { - struct text_input *text_input = wl_container_of(listener, text_input, commit); - struct input_method_relay *relay = text_input->relay; + struct text_input *text_input = + wl_container_of(listener, text_input, commit); + struct input_method_relay *relay = text_input->relay; - if (relay->active_text_input == text_input) { - update_popups_position(relay); - send_state_to_input_method(relay); - } + if (relay->active_text_input == text_input) { + update_popups_position(relay); + send_state_to_input_method(relay); + } } static void handle_text_input_destroy(struct wl_listener *listener, - void *data) { - struct text_input *text_input = - wl_container_of(listener, text_input, destroy); - wl_list_remove(&text_input->enable.link); - wl_list_remove(&text_input->disable.link); - wl_list_remove(&text_input->commit.link); - wl_list_remove(&text_input->destroy.link); - wl_list_remove(&text_input->link); - update_active_text_input(text_input->relay); - free(text_input); + void *data) { + struct text_input *text_input = + wl_container_of(listener, text_input, destroy); + wl_list_remove(&text_input->enable.link); + wl_list_remove(&text_input->disable.link); + wl_list_remove(&text_input->commit.link); + wl_list_remove(&text_input->destroy.link); + wl_list_remove(&text_input->link); + update_active_text_input(text_input->relay); + free(text_input); } static void handle_new_text_input(struct wl_listener *listener, void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, new_text_input); - struct wlr_text_input_v3 *wlr_text_input = data; - if (seat != wlr_text_input->seat) { - return; - } + struct input_method_relay *relay = + wl_container_of(listener, relay, new_text_input); + struct wlr_text_input_v3 *wlr_text_input = data; + if (seat != wlr_text_input->seat) { + return; + } - struct text_input *text_input = znew(*text_input); - text_input->input = wlr_text_input; - text_input->relay = relay; - wl_list_insert(&relay->text_inputs, &text_input->link); + struct text_input *text_input = znew(*text_input); + text_input->input = wlr_text_input; + text_input->relay = relay; + wl_list_insert(&relay->text_inputs, &text_input->link); - text_input->enable.notify = handle_text_input_enable; - wl_signal_add(&text_input->input->events.enable, &text_input->enable); + text_input->enable.notify = handle_text_input_enable; + wl_signal_add(&text_input->input->events.enable, &text_input->enable); - text_input->disable.notify = handle_text_input_disable; - wl_signal_add(&text_input->input->events.disable, &text_input->disable); + text_input->disable.notify = handle_text_input_disable; + wl_signal_add(&text_input->input->events.disable, &text_input->disable); - text_input->commit.notify = handle_text_input_commit; - wl_signal_add(&text_input->input->events.commit, &text_input->commit); + text_input->commit.notify = handle_text_input_commit; + wl_signal_add(&text_input->input->events.commit, &text_input->commit); - text_input->destroy.notify = handle_text_input_destroy; - wl_signal_add(&text_input->input->events.destroy, &text_input->destroy); + text_input->destroy.notify = handle_text_input_destroy; + wl_signal_add(&text_input->input->events.destroy, &text_input->destroy); - update_text_inputs_focused_surface(relay); + update_text_inputs_focused_surface(relay); } /* @@ -684,53 +693,55 @@ static void handle_new_text_input(struct wl_listener *listener, void *data) { * before wl_surface is destroyed. */ static void handle_focused_surface_destroy(struct wl_listener *listener, - void *data) { - struct input_method_relay *relay = - wl_container_of(listener, relay, focused_surface_destroy); - assert(relay->focused_surface == data); + void *data) { + struct input_method_relay *relay = + wl_container_of(listener, relay, focused_surface_destroy); + assert(relay->focused_surface == data); - input_method_relay_set_focus(relay, NULL); + input_method_relay_set_focus(relay, NULL); } struct input_method_relay *input_method_relay_create() { - struct input_method_relay *relay = znew(*relay); - wl_list_init(&relay->text_inputs); - wl_list_init(&relay->popups); - relay->popup_tree = wlr_scene_tree_create(&scene->tree); + struct input_method_relay *relay = znew(*relay); + wl_list_init(&relay->text_inputs); + wl_list_init(&relay->popups); + relay->popup_tree = wlr_scene_tree_create(&scene->tree); - relay->new_text_input.notify = handle_new_text_input; - wl_signal_add(&text_input_manager->events.text_input, &relay->new_text_input); + relay->new_text_input.notify = handle_new_text_input; + wl_signal_add(&text_input_manager->events.text_input, + &relay->new_text_input); - relay->new_input_method.notify = handle_new_input_method; - wl_signal_add(&input_method_manager->events.input_method, - &relay->new_input_method); + relay->new_input_method.notify = handle_new_input_method; + wl_signal_add(&input_method_manager->events.input_method, + &relay->new_input_method); - relay->focused_surface_destroy.notify = handle_focused_surface_destroy; + relay->focused_surface_destroy.notify = handle_focused_surface_destroy; - return relay; + return relay; } void input_method_relay_finish(struct input_method_relay *relay) { - wl_list_remove(&relay->new_text_input.link); - wl_list_remove(&relay->new_input_method.link); - free(relay); + wl_list_remove(&relay->new_text_input.link); + wl_list_remove(&relay->new_input_method.link); + free(relay); } void input_method_relay_set_focus(struct input_method_relay *relay, - struct wlr_surface *surface) { - if (relay->focused_surface == surface) { - wlr_log(WLR_INFO, "The surface is already focused"); - return; - } + struct wlr_surface *surface) { + if (relay->focused_surface == surface) { + wlr_log(WLR_INFO, "The surface is already focused"); + return; + } - if (relay->focused_surface) { - wl_list_remove(&relay->focused_surface_destroy.link); - } - relay->focused_surface = surface; - if (surface) { - wl_signal_add(&surface->events.destroy, &relay->focused_surface_destroy); - } + if (relay->focused_surface) { + wl_list_remove(&relay->focused_surface_destroy.link); + } + relay->focused_surface = surface; + if (surface) { + wl_signal_add(&surface->events.destroy, + &relay->focused_surface_destroy); + } - update_text_inputs_focused_surface(relay); - update_active_text_input(relay); + update_text_inputs_focused_surface(relay); + update_active_text_input(relay); } \ No newline at end of file