diff --git a/src/client.h b/src/client.h index d9f90bb..74dcf3b 100644 --- a/src/client.h +++ b/src/client.h @@ -6,399 +6,369 @@ */ /* Leave these functions first; they're used in the others */ -static inline int -client_is_x11(Client *c) -{ +static inline int client_is_x11(Client *c) { #ifdef XWAYLAND - return c->type == X11; + return c->type == X11; #endif - return 0; + return 0; } -static inline struct wlr_surface * -client_surface(Client *c) -{ +static inline struct wlr_surface *client_surface(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->surface; + if (client_is_x11(c)) + return c->surface.xwayland->surface; #endif - return c->surface.xdg->surface; + return c->surface.xdg->surface; } -static inline int -toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl) -{ - struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface; - struct wlr_surface *root_surface; - struct wlr_layer_surface_v1 *layer_surface; - Client *c = NULL; - LayerSurface *l = NULL; - int type = -1; +static inline int toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, + LayerSurface **pl) { + struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface; + struct wlr_surface *root_surface; + struct wlr_layer_surface_v1 *layer_surface; + Client *c = NULL; + LayerSurface *l = NULL; + int type = -1; #ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface; + struct wlr_xwayland_surface *xsurface; #endif - if (!s) - return -1; - root_surface = wlr_surface_get_root_surface(s); + if (!s) + return -1; + root_surface = wlr_surface_get_root_surface(s); #ifdef XWAYLAND - if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) { - c = xsurface->data; - type = c->type; - goto end; - } + if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) { + c = xsurface->data; + type = c->type; + goto end; + } #endif - if ((layer_surface = wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) { - l = layer_surface->data; - type = LayerShell; - goto end; - } + if ((layer_surface = + wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) { + l = layer_surface->data; + type = LayerShell; + goto end; + } - xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface); - while (xdg_surface) { - tmp_xdg_surface = NULL; - switch (xdg_surface->role) { - case WLR_XDG_SURFACE_ROLE_POPUP: - if (!xdg_surface->popup || !xdg_surface->popup->parent) - return -1; + xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface); + while (xdg_surface) { + tmp_xdg_surface = NULL; + switch (xdg_surface->role) { + case WLR_XDG_SURFACE_ROLE_POPUP: + if (!xdg_surface->popup || !xdg_surface->popup->parent) + return -1; - tmp_xdg_surface = wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent); + tmp_xdg_surface = + wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent); - if (!tmp_xdg_surface) - return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl); + if (!tmp_xdg_surface) + return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl); - xdg_surface = tmp_xdg_surface; - break; - case WLR_XDG_SURFACE_ROLE_TOPLEVEL: - c = xdg_surface->data; - type = c->type; - goto end; - case WLR_XDG_SURFACE_ROLE_NONE: - return -1; - } - } + xdg_surface = tmp_xdg_surface; + break; + case WLR_XDG_SURFACE_ROLE_TOPLEVEL: + c = xdg_surface->data; + type = c->type; + goto end; + case WLR_XDG_SURFACE_ROLE_NONE: + return -1; + } + } end: - if (pl) - *pl = l; - if (pc) - *pc = c; - return type; + if (pl) + *pl = l; + if (pc) + *pc = c; + return type; } /* The others */ -static inline void -client_activate_surface(struct wlr_surface *s, int activated) -{ - struct wlr_xdg_toplevel *toplevel; +static inline void client_activate_surface(struct wlr_surface *s, + int activated) { + struct wlr_xdg_toplevel *toplevel; #ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface; - if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) { - wlr_xwayland_surface_activate(xsurface, activated); - return; - } -#endif - 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) -{ -#ifdef XWAYLAND - 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; -} - -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"; -#endif - return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id : "broken"; -} - -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, - }; - -#ifdef XWAYLAND - if (client_is_x11(c)) - return; -#endif - - 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; - } -#endif - *geom = c->surface.xdg->geometry; -} - -static inline Client * -client_get_parent(Client *c) -{ - Client *p = NULL; -#ifdef XWAYLAND - if (client_is_x11(c)) { - if (c->surface.xwayland->parent) - toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); - return p; - } -#endif - 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); -#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; -} - -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"; -#endif - 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; - -#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 (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); - } -#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)); -} - -static inline int -client_is_rendered_on_mon(Client *c, Monitor *m) -{ - /* This is needed for when you don't want to check formal assignment, - * but rather actual displaying of the pixels. - * Usually VISIBLEON suffices and is also faster. */ - struct wlr_surface_output *s; - int unused_lx, unused_ly; - if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly)) - return 0; - wl_list_for_each(s, &client_surface(c)->current_outputs, link) - if (s->output == m->wlr_output) - return 1; - return 0; -} - -static inline int -client_is_stopped(Client *c) -{ - int pid; - siginfo_t in = {0}; -#ifdef XWAYLAND - 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 unlikely 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; -} - -static inline int -client_is_unmanaged(Client *c) -{ -#ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->override_redirect; -#endif - return 0; -} - -static inline void -client_notify_enter(struct wlr_surface *s, struct wlr_keyboard *kb) -{ - if (kb) - wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, - kb->num_keycodes, &kb->modifiers); - else - wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); -} - -static inline void -client_send_close(Client *c) -{ -#ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_close(c->surface.xwayland); - return; - } -#endif - wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel); -} - -static inline void -client_set_border_color(Client *c, const float color[static 4]) -{ - int i; - for (i = 0; i < 4; i++) - wlr_scene_rect_set_color(c->border[i], color); -} - -static inline void -client_set_fullscreen(Client *c, int fullscreen) -{ -#ifdef XWAYLAND - 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); -} - -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)); -} - -static inline uint32_t -client_set_size(Client *c, uint32_t width, uint32_t height) -{ -#ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_configure(c->surface.xwayland, - c->geom.x + c->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); -} - -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; + struct wlr_xwayland_surface *xsurface; + if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) { + wlr_xwayland_surface_activate(xsurface, activated); + return; } #endif - if (wl_resource_get_version(c->surface.xdg->toplevel->resource) - >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { - wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges); - } else { - wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel, edges != WLR_EDGE_NONE); - } + if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s))) + wlr_xdg_toplevel_set_activated(toplevel, activated); } -static inline void -client_set_suspended(Client *c, int suspended) -{ +static inline uint32_t client_set_bounds(Client *c, int32_t width, + int32_t height) { #ifdef XWAYLAND - if (client_is_x11(c)) - return; + 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; +} + +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"; +#endif + return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id + : "broken"; +} + +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, + }; + +#ifdef XWAYLAND + if (client_is_x11(c)) + return; #endif - wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended); + clip->x = c->surface.xdg->geometry.x; + clip->y = c->surface.xdg->geometry.y; } -static inline int -client_wants_focus(Client *c) -{ +static inline void client_get_geometry(Client *c, struct wlr_box *geom) { #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; + 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 - return 0; + *geom = c->surface.xdg->geometry; } -static inline int -client_wants_fullscreen(Client *c) -{ +static inline Client *client_get_parent(Client *c) { + Client *p = NULL; #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->fullscreen; + if (client_is_x11(c)) { + if (c->surface.xwayland->parent) + toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); + return p; + } #endif - return c->surface.xdg->toplevel->requested.fullscreen; + 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); +#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; +} + +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"; +#endif + 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; + +#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 (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); + } +#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)); +} + +static inline int client_is_rendered_on_mon(Client *c, Monitor *m) { + /* This is needed for when you don't want to check formal assignment, + * but rather actual displaying of the pixels. + * Usually VISIBLEON suffices and is also faster. */ + struct wlr_surface_output *s; + int unused_lx, unused_ly; + if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly)) + return 0; + wl_list_for_each(s, &client_surface(c)->current_outputs, + link) if (s->output == m->wlr_output) return 1; + return 0; +} + +static inline int client_is_stopped(Client *c) { + int pid; + siginfo_t in = {0}; +#ifdef XWAYLAND + 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 unlikely 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; +} + +static inline int client_is_unmanaged(Client *c) { +#ifdef XWAYLAND + if (client_is_x11(c)) + return c->surface.xwayland->override_redirect; +#endif + return 0; +} + +static inline void client_notify_enter(struct wlr_surface *s, + struct wlr_keyboard *kb) { + if (kb) + wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, kb->num_keycodes, + &kb->modifiers); + else + wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); +} + +static inline void client_send_close(Client *c) { +#ifdef XWAYLAND + if (client_is_x11(c)) { + wlr_xwayland_surface_close(c->surface.xwayland); + return; + } +#endif + wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel); +} + +static inline void client_set_border_color(Client *c, + const float color[static 4]) { + int i; + for (i = 0; i < 4; i++) + wlr_scene_rect_set_color(c->border[i], color); +} + +static inline void client_set_fullscreen(Client *c, int fullscreen) { +#ifdef XWAYLAND + 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); +} + +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)); +} + +static inline uint32_t client_set_size(Client *c, uint32_t width, + uint32_t height) { +#ifdef XWAYLAND + if (client_is_x11(c)) { + wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->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); +} + +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; + } +#endif + if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >= + XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { + wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges); + } else { + wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel, + edges != WLR_EDGE_NONE); + } +} + +static inline void client_set_suspended(Client *c, int suspended) { +#ifdef XWAYLAND + if (client_is_x11(c)) + return; +#endif + + wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended); +} + +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; +#endif + return 0; +} + +static inline int client_wants_fullscreen(Client *c) { +#ifdef XWAYLAND + if (client_is_x11(c)) + return c->surface.xwayland->fullscreen; +#endif + return c->surface.xdg->toplevel->requested.fullscreen; } diff --git a/src/main.c b/src/main.c index 12f441e..67a5c1e 100644 --- a/src/main.c +++ b/src/main.c @@ -83,160 +83,170 @@ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ -enum { XDGShell, LayerShell, X11 }; /* client types */ -enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrOverlay, LyrBlock, NUM_LAYERS }; /* scene layers */ +enum { XDGShell, LayerShell, X11 }; /* client types */ +enum { + LyrBg, + LyrBottom, + LyrTile, + LyrFloat, + LyrTop, + LyrFS, + LyrOverlay, + LyrBlock, + NUM_LAYERS +}; /* scene layers */ typedef union { - int i; - uint32_t ui; - float f; - const void *v; + int i; + uint32_t ui; + float f; + const void *v; } 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 Monitor Monitor; typedef struct { - /* Must keep this field first */ - unsigned int type; /* XDGShell or X11* */ + /* Must keep this field first */ + unsigned int type; /* XDGShell or X11* */ - 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 wlr_box geom; /* layout-relative, includes border */ - struct wlr_box prev; /* layout-relative, includes border */ - struct wlr_box bounds; /* only width and height are used */ - union { - struct wlr_xdg_surface *xdg; - struct wlr_xwayland_surface *xwayland; - } surface; - struct wlr_xdg_toplevel_decoration_v1 *decoration; - struct wl_listener commit; - struct wl_listener map; - struct wl_listener maximize; - struct wl_listener unmap; - struct wl_listener destroy; - struct wl_listener set_title; - struct wl_listener fullscreen; - struct wl_listener set_decoration_mode; - struct wl_listener destroy_decoration; + 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 wlr_box geom; /* layout-relative, includes border */ + struct wlr_box prev; /* layout-relative, includes border */ + struct wlr_box bounds; /* only width and height are used */ + union { + struct wlr_xdg_surface *xdg; + struct wlr_xwayland_surface *xwayland; + } surface; + struct wlr_xdg_toplevel_decoration_v1 *decoration; + struct wl_listener commit; + struct wl_listener map; + struct wl_listener maximize; + struct wl_listener unmap; + struct wl_listener destroy; + struct wl_listener set_title; + struct wl_listener fullscreen; + struct wl_listener set_decoration_mode; + struct wl_listener destroy_decoration; #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 activate; + struct wl_listener associate; + struct wl_listener dissociate; + struct wl_listener configure; + struct wl_listener set_hints; #endif - unsigned int bw; - uint32_t tags; - int isfloating, isurgent, isfullscreen; - uint32_t resize; /* configure serial of a pending resize */ + unsigned int bw; + uint32_t tags; + int isfloating, isurgent, isfullscreen; + uint32_t resize; /* configure serial of a pending resize */ } Client; 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 { - /* Must keep this field first */ - unsigned int type; /* LayerShell */ + /* Must keep this field first */ + unsigned int type; /* LayerShell */ - 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; + 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 unmap; - struct wl_listener surface_commit; + struct wl_listener destroy; + struct wl_listener unmap; + struct wl_listener surface_commit; } LayerSurface; typedef struct { - const char *symbol; - void (*arrange)(Monitor *); + const char *symbol; + void (*arrange)(Monitor *); } 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[2]; - unsigned int seltags; - unsigned int sellt; - uint32_t tagset[2]; - float mfact; - int gamma_lut_changed; - int nmaster; - char ltsymbol[16]; - int asleep; + 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[2]; + unsigned int seltags; + unsigned int sellt; + uint32_t tagset[2]; + float mfact; + int gamma_lut_changed; + int nmaster; + char ltsymbol[16]; + int asleep; }; 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; - uint32_t tags; - int isfloating; - int monitor; + const char *id; + const char *title; + uint32_t tags; + int isfloating; + int monitor; } 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 */ @@ -244,7 +254,7 @@ static void applybounds(Client *c, struct wlr_box *bbox); static void applyrules(Client *c); static void arrange(Monitor *m); 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 void axisnotify(struct wl_listener *listener, void *data); static void buttonpress(struct wl_listener *listener, void *data); @@ -301,15 +311,17 @@ static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(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); +static void motionnotify(uint32_t time, struct wlr_input_device *device, + double sx, double sy, double sx_unaccel, + double sy_unaccel); static void motionrelative(struct wl_listener *listener, void *data); static void moveresize(const Arg *arg); static void outputmgrapply(struct wl_listener *listener, void *data); -static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test); +static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, + 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); +static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, + double sy, uint32_t time); static void printstatus(void); static void powermgrsetmode(struct wl_listener *listener, void *data); static void quit(const Arg *arg); @@ -349,7 +361,7 @@ static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualpointer(struct wl_listener *listener, void *data); 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 zoom(const Arg *arg); /* variables */ @@ -363,7 +375,7 @@ static struct wlr_scene *scene; static struct wlr_scene_tree *layers[NUM_LAYERS]; static struct wlr_scene_tree *drag_icon; /* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */ -static const int layermap[] = { LyrBg, LyrBottom, LyrTop, LyrOverlay }; +static const int layermap[] = {LyrBg, LyrBottom, LyrTop, LyrOverlay}; static struct wlr_renderer *drw; static struct wlr_allocator *alloc; static struct wlr_compositor *compositor; @@ -418,7 +430,8 @@ static struct wl_listener new_idle_inhibitor = {.notify = createidleinhibitor}; 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}; +static struct wl_listener new_pointer_constraint = { + .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}; @@ -426,7 +439,8 @@ static struct wl_listener new_xdg_decoration = {.notify = createdecoration}; 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}; +static struct wl_listener output_power_mgr_set_mode = {.notify = + 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}; @@ -456,2759 +470,2616 @@ static struct wlr_xwayland *xwayland; #include "client.h" /* function implementations */ -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); +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); - 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; } -void -applyrules(Client *c) -{ - /* rule matching */ - const char *appid, *title; - uint32_t newtags = 0; - int i; - const Rule *r; - Monitor *mon = selmon, *m; +void applyrules(Client *c) { + /* rule matching */ + const char *appid, *title; + uint32_t newtags = 0; + int i; + const Rule *r; + Monitor *mon = selmon, *m; - appid = client_get_appid(c); - title = client_get_title(c); + appid = client_get_appid(c); + title = client_get_title(c); - for (r = rules; r < END(rules); r++) { - if ((!r->title || strstr(title, r->title)) - && (!r->id || strstr(appid, r->id))) { - c->isfloating = r->isfloating; - newtags |= r->tags; - i = 0; - wl_list_for_each(m, &mons, link) { - if (r->monitor == i++) - mon = m; - } - } - } + for (r = rules; r < END(rules); r++) { + if ((!r->title || strstr(title, r->title)) && + (!r->id || strstr(appid, r->id))) { + c->isfloating = r->isfloating; + newtags |= r->tags; + i = 0; + wl_list_for_each(m, &mons, link) { + if (r->monitor == i++) + mon = m; + } + } + } - c->isfloating |= client_is_float_type(c); - setmon(c, mon, newtags); + c->isfloating |= client_is_float_type(c); + setmon(c, mon, newtags); } -void -arrange(Monitor *m) -{ - Client *c; +void arrange(Monitor *m) { + Client *c; - if (!m->wlr_output->enabled) - return; + if (!m->wlr_output->enabled) + return; - wl_list_for_each(c, &clients, link) { - if (c->mon == m) { - wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m)); - client_set_suspended(c, !VISIBLEON(c, m)); - } - } + wl_list_for_each(c, &clients, link) { + if (c->mon == m) { + wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m)); + client_set_suspended(c, !VISIBLEON(c, m)); + } + } - wlr_scene_node_set_enabled(&m->fullscreen_bg->node, - (c = focustop(m)) && c->isfullscreen); + wlr_scene_node_set_enabled(&m->fullscreen_bg->node, + (c = focustop(m)) && c->isfullscreen); - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); - /* We move all clients (except fullscreen and unmanaged) to LyrTile while - * in floating layout to avoid "real" floating clients be always on top */ - wl_list_for_each(c, &clients, link) { - if (c->mon != m || c->scene->node.parent == layers[LyrFS]) - continue; + /* We move all clients (except fullscreen and unmanaged) to LyrTile while + * in floating layout to avoid "real" floating clients be always on top */ + wl_list_for_each(c, &clients, link) { + if (c->mon != m || c->scene->node.parent == layers[LyrFS]) + continue; - wlr_scene_node_reparent(&c->scene->node, - (!m->lt[m->sellt]->arrange && c->isfloating) - ? layers[LyrTile] - : (m->lt[m->sellt]->arrange && c->isfloating) - ? layers[LyrFloat] - : c->scene->node.parent); - } + wlr_scene_node_reparent( + &c->scene->node, + (!m->lt[m->sellt]->arrange && c->isfloating) ? layers[LyrTile] + : (m->lt[m->sellt]->arrange && c->isfloating) ? layers[LyrFloat] + : c->scene->node.parent); + } - if (m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); - motionnotify(0, NULL, 0, 0, 0, 0); - checkidleinhibitor(NULL); + if (m->lt[m->sellt]->arrange) + m->lt[m->sellt]->arrange(m); + 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; +void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, + 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 (!layer_surface->initialized) - continue; + if (!layer_surface->initialized) + continue; - if (exclusive != (layer_surface->current.exclusive_zone > 0)) - continue; + if (exclusive != (layer_surface->current.exclusive_zone > 0)) + 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); + } } -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; +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; - /* 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); - } + if (!wlr_box_equal(&usable_area, &m->w)) { + m->w = usable_area; + arrange(m); + } - /* 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; + } + } } -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; - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - /* TODO: allow usage of scroll wheel for mousebindings, it can be implemented - * by 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); +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; + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + /* TODO: allow usage of scroll wheel for mousebindings, it can be implemented + * by 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); } -void -buttonpress(struct wl_listener *listener, void *data) -{ - struct wlr_pointer_button_event *event = data; - struct wlr_keyboard *keyboard; - uint32_t mods; - Client *c; - const Button *b; +void buttonpress(struct wl_listener *listener, void *data) { + struct wlr_pointer_button_event *event = data; + struct wlr_keyboard *keyboard; + uint32_t mods; + Client *c; + const Button *b; - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + 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, NULL, &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, NULL, &c, NULL, NULL, NULL); + if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) + focusclient(c, 1); - keyboard = wlr_seat_get_keyboard(seat); - mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; - for (b = buttons; b < END(buttons); b++) { - if (CLEANMASK(mods) == CLEANMASK(b->mod) && - event->button == b->button && b->func) { - b->func(&b->arg); - return; - } - } - break; - case WL_POINTER_BUTTON_STATE_RELEASED: - /* If you released any buttons, we exit interactive move/resize mode. */ - /* TODO: should reset to the pointer focus's current setcursor */ - if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { - wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); - cursor_mode = CurNormal; - /* Drop the window off on its new monitor */ - selmon = xytomon(cursor->x, cursor->y); - setmon(grabc, selmon, 0); - grabc = NULL; - return; - } - 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 (b = buttons; b < END(buttons); b++) { + if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button && + b->func) { + b->func(&b->arg); + return; + } + } + break; + case WL_POINTER_BUTTON_STATE_RELEASED: + /* If you released any buttons, we exit interactive move/resize mode. */ + /* TODO: should reset to the pointer focus's current setcursor */ + if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { + wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); + cursor_mode = CurNormal; + /* Drop the window off on its new monitor */ + selmon = xytomon(cursor->x, cursor->y); + setmon(grabc, selmon, 0); + grabc = NULL; + return; + } + 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 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; + } + } + + wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited); } -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; - } - } - - wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited); -} - -void -cleanup(void) -{ - cleanuplisteners(); +void cleanup(void) { + 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); - /* If it's not destroyed manually, it will cause a use-after-free of wlr_seat. - * Destroy it until it's fixed on 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 on 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 -cleanupmon(struct wl_listener *listener, void *data) -{ - Monitor *m = wl_container_of(listener, m, destroy); - LayerSurface *l, *tmp; - size_t i; +void cleanupmon(struct wl_listener *listener, void *data) { + 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); - if (m->lock_surface) - destroylocksurface(&m->destroy_lock_surface, NULL); - 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); + if (m->lock_surface) + destroylocksurface(&m->destroy_lock_surface, NULL); + 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 -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); +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); #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 -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); +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); - 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) - setmon(c, selmon, c->tags); - } - 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) + setmon(c, selmon, c->tags); + } + 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; +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; - 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 -commitnotify(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, commit); +void commitnotify(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, commit); - if (c->surface.xdg->initial_commit) { - /* - * Get the monitor this client will be rendered on - * Note that if the user set a rule in which the client is placed on - * a different monitor based on its title, this will likely select - * a wrong monitor. - */ - applyrules(c); - if (c->mon) { - client_set_scale(client_surface(c), c->mon->wlr_output->scale); - } - setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ + if (c->surface.xdg->initial_commit) { + /* + * Get the monitor this client will be rendered on + * Note that if the user set a rule in which the client is placed on + * a different monitor based on its title, this will likely select + * a wrong monitor. + */ + applyrules(c); + if (c->mon) { + client_set_scale(client_surface(c), c->mon->wlr_output->scale); + } + setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ - wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, - WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); - if (c->decoration) - requestdecorationmode(&c->set_decoration_mode, c->decoration); - wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); - return; - } + wlr_xdg_toplevel_set_wm_capabilities( + c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + if (c->decoration) + requestdecorationmode(&c->set_decoration_mode, c->decoration); + wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); + return; + } - resize(c, c->geom, (c->isfloating && !c->isfullscreen)); + resize(c, c->geom, (c->isfloating && !c->isfullscreen)); - /* mark a pending resize as completed */ - if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) - c->resize = 0; + /* mark a pending resize as completed */ + if (c->resize && c->resize <= c->surface.xdg->current.configure_serial) + c->resize = 0; } -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; +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; - 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)) { - wlr_xdg_popup_destroy(popup); - return; - } - box = type == LayerShell ? l->mon->m : c->mon->w; - box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x); - box.y -= (type == LayerShell ? l->scene->node.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)) { + wlr_xdg_popup_destroy(popup); + return; + } + box = type == LayerShell ? l->mon->m : c->mon->w; + box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x); + box.y -= (type == LayerShell ? l->scene->node.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; +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; - 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); +void createidleinhibitor(struct wl_listener *listener, void *data) { + 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); +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); - /* 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 *createkeyboardgroup(void) { + 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); - xkb_keymap_unref(keymap); - xkb_context_unref(context); + wlr_keyboard_set_keymap(&group->wlr_group->keyboard, keymap); + 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]]; +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]]; - 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; +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; - 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 MonitorRule *r; - size_t i; - struct wlr_output_state state; - Monitor *m; +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 MonitorRule *r; + size_t i; + 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; - 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->tagset[0] = m->tagset[1] = 1; - for (r = monrules; r < END(monrules); r++) { - if (!r->name || strstr(wlr_output->name, r->name)) { - m->m.x = r->x; - m->m.y = r->y; - m->mfact = r->mfact; - m->nmaster = r->nmaster; - m->lt[0] = r->lt; - m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]]; - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); - wlr_output_state_set_scale(&state, r->scale); - wlr_output_state_set_transform(&state, r->rr); - break; - } - } + wlr_output_state_init(&state); + /* Initialize monitor state using configured rules */ + m->tagset[0] = m->tagset[1] = 1; + for (r = monrules; r < END(monrules); r++) { + if (!r->name || strstr(wlr_output->name, r->name)) { + m->m.x = r->x; + m->m.y = r->y; + m->mfact = r->mfact; + m->nmaster = r->nmaster; + m->lt[0] = r->lt; + m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]]; + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol)); + 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); - printstatus(); + wl_list_insert(&mons, &m->link); + 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 -createnotify(struct wl_listener *listener, void *data) -{ - /* This event is raised when a client creates a new toplevel (application window). */ - struct wlr_xdg_toplevel *toplevel = data; - Client *c = NULL; +void createnotify(struct wl_listener *listener, void *data) { + /* This event is raised when a client creates a new toplevel (application + * window). */ + 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.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.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))) { +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))) { - 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); - } + 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); + } - if (libinput_device_config_scroll_has_natural_scroll(device)) - libinput_device_config_scroll_set_natural_scroll_enabled(device, natural_scrolling); + if (libinput_device_config_scroll_has_natural_scroll(device)) + libinput_device_config_scroll_set_natural_scroll_enabled( + device, 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); +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); } -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); +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); } -void -cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) -{ - if (active_constraint == constraint) - return; +void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) { + 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 a 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 cursorframe(struct wl_listener *listener, void *data) { + /* This event is forwarded by the cursor when a pointer emits a 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; +void cursorwarptohint(void) { + 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 -destroydecoration(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, destroy_decoration); +void destroydecoration(struct wl_listener *listener, void *data) { + 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 -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); +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); } -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); +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); } -void -destroylayersurfacenotify(struct wl_listener *listener, void *data) -{ - LayerSurface *l = wl_container_of(listener, l, destroy); +void destroylayersurfacenotify(struct wl_listener *listener, void *data) { + 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; +void destroylock(SessionLock *lock, int unlock) { + wlr_seat_keyboard_notify_clear_focus(seat); + if ((locked = !unlock)) + goto destroy; - wlr_scene_node_set_enabled(&locked_bg->node, 0); + wlr_scene_node_set_enabled(&locked_bg->node, 0); - 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; +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; - 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 -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); +void 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); #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); - wl_list_remove(&c->maximize.link); - } - free(c); + { + wl_list_remove(&c->commit.link); + wl_list_remove(&c->map.link); + wl_list_remove(&c->unmap.link); + wl_list_remove(&c->maximize.link); + } + free(c); } -void -destroypointerconstraint(struct wl_listener *listener, void *data) -{ - PointerConstraint *pointer_constraint = wl_container_of(listener, pointer_constraint, destroy); +void destroypointerconstraint(struct wl_listener *listener, void *data) { + 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); +void destroysessionlock(struct wl_listener *listener, void *data) { + 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); +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); } -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, - 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; +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, 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 -focusclient(Client *c, int lift) -{ - struct wlr_surface *old = seat->keyboard_state.focused_surface; - int unused_lx, unused_ly, old_client_type; - Client *old_c = NULL; - LayerSurface *old_l = NULL; +void focusclient(Client *c, int lift) { + struct wlr_surface *old = seat->keyboard_state.focused_surface; + int unused_lx, unused_ly, old_client_type; + Client *old_c = NULL; + LayerSurface *old_l = NULL; - if (locked) - return; + if (locked) + 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) - return; + if (c && client_surface(c) == old) + return; - if ((old_client_type = toplevel_from_wlr_surface(old, &old_c, &old_l)) == XDGShell) { - struct wlr_xdg_popup *popup, *tmp; - wl_list_for_each_safe(popup, tmp, &old_c->surface.xdg->popups, link) - wlr_xdg_popup_destroy(popup); - } + if ((old_client_type = toplevel_from_wlr_surface(old, &old_c, &old_l)) == + XDGShell) { + struct wlr_xdg_popup *popup, *tmp; + wl_list_for_each_safe(popup, tmp, &old_c->surface.xdg->popups, link) + wlr_xdg_popup_destroy(popup); + } - /* Put the new client atop the focus stack and select its monitor */ - if (c && !client_is_unmanaged(c)) { - wl_list_remove(&c->flink); - wl_list_insert(&fstack, &c->flink); - selmon = c->mon; - c->isurgent = 0; + /* Put the new client atop the focus stack and select its monitor */ + if (c && !client_is_unmanaged(c)) { + wl_list_remove(&c->flink); + wl_list_insert(&fstack, &c->flink); + selmon = c->mon; + c->isurgent = 0; - /* Don't change border color if there is an exclusive focus or we are - * handling a drag operation */ - if (!exclusive_focus && !seat->drag) - client_set_border_color(c, focuscolor); - } + /* Don't change border color if there is an exclusive focus or we are + * handling a drag operation */ + if (!exclusive_focus && !seat->drag) + client_set_border_color(c, focuscolor); + } - /* Deactivate old client if focus is changing */ - if (old && (!c || client_surface(c) != old)) { - /* 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. */ - if (old_client_type == LayerShell && wlr_scene_node_coords( - &old_l->scene->node, &unused_lx, &unused_ly) - && old_l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { - return; - } else if (old_c && old_c == exclusive_focus && client_wants_focus(old_c)) { - return; - /* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg - * and probably other clients */ - } else if (old_c && !client_is_unmanaged(old_c) && (!c || !client_wants_focus(c))) { - client_set_border_color(old_c, bordercolor); + /* Deactivate old client if focus is changing */ + if (old && (!c || client_surface(c) != old)) { + /* 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. */ + if (old_client_type == LayerShell && + wlr_scene_node_coords(&old_l->scene->node, &unused_lx, &unused_ly) && + old_l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { + return; + } else if (old_c && old_c == exclusive_focus && client_wants_focus(old_c)) { + return; + /* Don't deactivate old client if the new one wants focus, as this causes + * issues with winecfg and probably other clients */ + } else if (old_c && !client_is_unmanaged(old_c) && + (!c || !client_wants_focus(c))) { + client_set_border_color(old_c, bordercolor); - client_activate_surface(old, 0); - } - } - printstatus(); + client_activate_surface(old, 0); + } + } + printstatus(); - if (!c) { - /* With no client, all we have left is to clear focus */ - wlr_seat_keyboard_notify_clear_focus(seat); - return; - } + if (!c) { + /* With no client, all we have left is to clear focus */ + 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)); - /* Activate the new client */ - client_activate_surface(client_surface(c), 1); + /* Activate the new client */ + client_activate_surface(client_surface(c), 1); } -void -focusmon(const Arg *arg) -{ - 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); - } - focusclient(focustop(selmon), 1); +void focusmon(const Arg *arg) { + 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); + } + focusclient(focustop(selmon), 1); } -void -focusstack(const Arg *arg) -{ - /* Focus the next or previous client (in tiling order) on selmon */ - Client *c, *sel = focustop(selmon); - if (!sel || (sel->isfullscreen && !client_has_children(sel))) - return; - if (arg->i > 0) { - wl_list_for_each(c, &sel->link, link) { - if (&c->link == &clients) - 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)) - break; /* found it */ - } - } - /* If only one client is visible on selmon, then c == sel */ - focusclient(c, 1); +void focusstack(const Arg *arg) { + /* Focus the next or previous client (in tiling order) on selmon */ + Client *c, *sel = focustop(selmon); + if (!sel || (sel->isfullscreen && !client_has_children(sel))) + return; + if (arg->i > 0) { + wl_list_for_each(c, &sel->link, link) { + if (&c->link == &clients) + 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)) + 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 it * will focus the topmost client of this mon, when actually will * only return that client */ -Client * -focustop(Monitor *m) -{ - Client *c; - wl_list_for_each(c, &fstack, flink) { - if (VISIBLEON(c, m)) - return c; - } - return NULL; +Client *focustop(Monitor *m) { + Client *c; + wl_list_for_each(c, &fstack, flink) { + if (VISIBLEON(c, m)) + return c; + } + return NULL; } -void -fullscreennotify(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, fullscreen); - setfullscreen(c, client_wants_fullscreen(c)); +void fullscreennotify(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, fullscreen); + setfullscreen(c, client_wants_fullscreen(c)); } -void -gpureset(struct wl_listener *listener, void *data) -{ - struct wlr_renderer *old_drw = drw; - struct wlr_allocator *old_alloc = alloc; - struct Monitor *m; - if (!(drw = wlr_renderer_autocreate(backend))) - die("couldn't recreate renderer"); +void gpureset(struct wl_listener *listener, void *data) { + struct wlr_renderer *old_drw = drw; + struct wlr_allocator *old_alloc = alloc; + struct Monitor *m; + 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); +void handlesig(int signo) { + if (signo == SIGCHLD) + while (waitpid(-1, NULL, WNOHANG) > 0) + ; + else if (signo == SIGINT || signo == SIGTERM) + quit(NULL); } -void -incnmaster(const Arg *arg) -{ - if (!arg || !selmon) - return; - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); - arrange(selmon); +void incnmaster(const Arg *arg) { + if (!arg || !selmon) + return; + selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); } -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; +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; - 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 -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. - */ - const Key *k; - for (k = keys; k < END(keys); k++) { - if (CLEANMASK(mods) == CLEANMASK(k->mod) - && sym == k->keysym && k->func) { - k->func(&k->arg); - return 1; - } - } - return 0; +int 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. + */ + const Key *k; + for (k = keys; k < END(keys); k++) { + if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->keysym && k->func) { + k->func(&k->arg); + return 1; + } + } + return 0; } -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; +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; - /* 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); - /* 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; - 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); + 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); +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); - 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); + 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); } -int -keyrepeat(void *data) -{ - KeyboardGroup *group = data; - int i; - if (!group->nsyms || group->wlr_group->keyboard.repeat_info.rate <= 0) - return 0; +int keyrepeat(void *data) { + 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; } -void -killclient(const Arg *arg) -{ - Client *sel = focustop(selmon); - if (sel) - client_send_close(sel); +void killclient(const Arg *arg) { + Client *sel = focustop(selmon); + if (sel) + client_send_close(sel); } -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, 1); - if (cur_lock) { - wlr_session_lock_v1_destroy(session_lock); - return; - } - lock = session_lock->data = ecalloc(1, sizeof(*lock)); - focusclient(NULL, 0); +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, 1); + 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 -mapnotify(struct wl_listener *listener, void *data) -{ - /* Called when the surface is mapped, or ready to display on-screen. */ - Client *p = NULL; - Client *w, *c = wl_container_of(listener, c, map); - Monitor *m; - int i; +void mapnotify(struct wl_listener *listener, void *data) { + /* Called when the surface is mapped, or ready to display on-screen. */ + Client *p = NULL; + Client *w, *c = wl_container_of(listener, c, map); + Monitor *m; + int i; - /* Create scene tree for this client and its border */ - c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); - /* Enabled later by a call to arrange() */ - wlr_scene_node_set_enabled(&c->scene->node, client_is_unmanaged(c)); - 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; + /* Create scene tree for this client and its border */ + c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); + /* Enabled later by a call to arrange() */ + wlr_scene_node_set_enabled(&c->scene->node, client_is_unmanaged(c)); + 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); - /* 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, c->geom.y); - client_set_size(c, c->geom.width, c->geom.height); - if (client_wants_focus(c)) { - focusclient(c, 1); - exclusive_focus = c; - } - goto unset_fullscreen; - } + /* 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, c->geom.y); + client_set_size(c, c->geom.width, c->geom.height); + if (client_wants_focus(c)) { + focusclient(c, 1); + exclusive_focus = c; + } + goto unset_fullscreen; + } - 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; + /* 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; - /* Insert this client into client lists. */ - wl_list_insert(&clients, &c->link); - wl_list_insert(&fstack, &c->flink); + /* Insert this client into client lists. */ + wl_list_insert(&clients, &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 as its parent. - * If there is no parent, apply rules */ - if ((p = client_get_parent(c))) { - c->isfloating = 1; - setmon(c, p->mon, p->tags); - } else { - applyrules(c); - } - printstatus(); + /* 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 as its parent. + * If there is no parent, apply rules */ + if ((p = client_get_parent(c))) { + c->isfloating = 1; + setmon(c, p->mon, p->tags); + } else { + applyrules(c); + } + printstatus(); unset_fullscreen: - m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); - wl_list_for_each(w, &clients, link) { - if (w != c && w != p && w->isfullscreen && m == w->mon && (w->tags & c->tags)) - setfullscreen(w, 0); - } + m = c->mon ? c->mon : xytomon(c->geom.x, c->geom.y); + wl_list_for_each(w, &clients, link) { + if (w != c && w != p && w->isfullscreen && m == w->mon && + (w->tags & c->tags)) + setfullscreen(w, 0); + } } -void -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 (c->surface.xdg->initialized - && wl_resource_get_version(c->surface.xdg->toplevel->resource) - < XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) - wlr_xdg_surface_schedule_configure(c->surface.xdg); +void 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 (c->surface.xdg->initialized && + wl_resource_get_version(c->surface.xdg->toplevel->resource) < + XDG_TOPLEVEL_WM_CAPABILITIES_SINCE_VERSION) + wlr_xdg_surface_schedule_configure(c->surface.xdg); } -void -monocle(Monitor *m) -{ - Client *c; - int n = 0; +void monocle(Monitor *m) { + Client *c; + int n = 0; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; - resize(c, m->w, 0); - n++; - } - if (n) - snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n); - if ((c = focustop(m))) - wlr_scene_node_raise_to_top(&c->scene->node); + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + resize(c, m->w, 0); + n++; + } + if (n) + snprintf(m->ltsymbol, LENGTH(m->ltsymbol), "[%d]", n); + if ((c = focustop(m))) + wlr_scene_node_raise_to_top(&c->scene->node); } -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. Also, some hardware emits these events. */ - struct wlr_pointer_motion_absolute_event *event = data; - double lx, ly, dx, dy; +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. Also, some hardware 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; +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; - /* 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); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); + wlr_cursor_move(cursor, device, dx, dy); + 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. */ - resize(grabc, (struct wlr_box){.x = (int)round(cursor->x) - grabcx, .y = (int)round(cursor->y) - grabcy, - .width = grabc->geom.width, .height = grabc->geom.height}, 1); - return; - } else if (cursor_mode == CurResize) { - resize(grabc, (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}, 1); - return; - } + /* If we are currently grabbing the mouse, handle and return */ + if (cursor_mode == CurMove) { + /* Move the grabbed client to the new position. */ + resize(grabc, + (struct wlr_box){.x = (int)round(cursor->x) - grabcx, + .y = (int)round(cursor->y) - grabcy, + .width = grabc->geom.width, + .height = grabc->geom.height}, + 1); + return; + } else if (cursor_mode == CurResize) { + resize(grabc, + (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}, + 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) - 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) + wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); - pointerfocus(c, surface, sx, sy, time); + pointerfocus(c, surface, sx, sy, time); } -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); +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); } -void -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; +void 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; - /* Float the window and tell motionnotify to grab it */ - setfloating(grabc, 1); - switch (cursor_mode = arg->ui) { - case CurMove: - grabcx = (int)round(cursor->x) - grabc->geom.x; - grabcy = (int)round(cursor->y) - grabc->geom.y; - wlr_cursor_set_xcursor(cursor, cursor_mgr, "all-scroll"); - 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, "se-resize"); - break; - } + /* Float the window and tell motionnotify to grab it */ + setfloating(grabc, 1); + switch (cursor_mode = arg->ui) { + case CurMove: + grabcx = (int)round(cursor->x) - grabc->geom.x; + grabcy = (int)round(cursor->y) - grabc->geom.y; + wlr_cursor_set_xcursor(cursor, cursor_mgr, "all-scroll"); + 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, "se-resize"); + break; + } } -void -outputmgrapply(struct wl_listener *listener, void *data) -{ - struct wlr_output_configuration_v1 *config = data; - outputmgrapplyortest(config, 0); +void outputmgrapply(struct wl_listener *listener, void *data) { + struct wlr_output_configuration_v1 *config = data; + outputmgrapplyortest(config, 0); } -void -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; +void 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; - 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 avoids - * 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 avoids + * 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); +void outputmgrtest(struct wl_listener *listener, void *data) { + 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; +void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, + 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 -printstatus(void) -{ - Monitor *m = NULL; - Client *c; - uint32_t occ, urg, sel; +void printstatus(void) { + Monitor *m = NULL; + Client *c; + uint32_t occ, urg, sel; - wl_list_for_each(m, &mons, link) { - occ = urg = 0; - wl_list_for_each(c, &clients, link) { - if (c->mon != m) - continue; - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - if ((c = focustop(m))) { - printf("%s title %s\n", m->wlr_output->name, client_get_title(c)); - printf("%s appid %s\n", m->wlr_output->name, client_get_appid(c)); - printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen); - printf("%s floating %d\n", m->wlr_output->name, c->isfloating); - sel = c->tags; - } else { - printf("%s title \n", m->wlr_output->name); - printf("%s appid \n", m->wlr_output->name); - printf("%s fullscreen \n", m->wlr_output->name); - printf("%s floating \n", m->wlr_output->name); - sel = 0; - } + wl_list_for_each(m, &mons, link) { + occ = urg = 0; + wl_list_for_each(c, &clients, link) { + if (c->mon != m) + continue; + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; + } + if ((c = focustop(m))) { + printf("%s title %s\n", m->wlr_output->name, client_get_title(c)); + printf("%s appid %s\n", m->wlr_output->name, client_get_appid(c)); + printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen); + printf("%s floating %d\n", m->wlr_output->name, c->isfloating); + sel = c->tags; + } else { + printf("%s title \n", m->wlr_output->name); + printf("%s appid \n", m->wlr_output->name); + printf("%s fullscreen \n", m->wlr_output->name); + printf("%s floating \n", m->wlr_output->name); + sel = 0; + } - printf("%s selmon %u\n", m->wlr_output->name, m == selmon); - printf("%s tags %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32"\n", - m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg); - printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol); - } - fflush(stdout); + printf("%s selmon %u\n", m->wlr_output->name, m == selmon); + printf("%s tags %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 "\n", + m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg); + printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol); + } + fflush(stdout); } -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; +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; - 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 -quit(const Arg *arg) -{ - wl_display_terminate(dpy); -} +void quit(const Arg *arg) { wl_display_terminate(dpy); } -void -rendermon(struct wl_listener *listener, void *data) -{ - /* This function is called every time an output is ready to display a frame, - * generally at the output's refresh rate (e.g. 60Hz). */ - Monitor *m = wl_container_of(listener, m, frame); - Client *c; - struct wlr_output_state pending = {0}; - struct timespec now; +void rendermon(struct wl_listener *listener, void *data) { + /* This function is called every time an output is ready to display a frame, + * generally at the output's refresh rate (e.g. 60Hz). */ + Monitor *m = wl_container_of(listener, m, frame); + Client *c; + struct wlr_output_state pending = {0}; + struct timespec now; - /* Render if no XDG clients have an outstanding resize and are visible on - * this monitor. */ - wl_list_for_each(c, &clients, link) { - if (c->resize && !c->isfloating && client_is_rendered_on_mon(c, m) && !client_is_stopped(c)) - goto skip; - } + /* Render if no XDG clients have an outstanding resize and are visible on + * this monitor. */ + wl_list_for_each(c, &clients, link) { + if (c->resize && !c->isfloating && client_is_rendered_on_mon(c, m) && + !client_is_stopped(c)) + goto skip; + } - wlr_scene_output_commit(m->scene_output, NULL); + wlr_scene_output_commit(m->scene_output, NULL); skip: - /* Let clients know a frame has been rendered */ - clock_gettime(CLOCK_MONOTONIC, &now); - wlr_scene_output_send_frame_done(m->scene_output, &now); - wlr_output_state_finish(&pending); + /* Let clients know a frame has been rendered */ + clock_gettime(CLOCK_MONOTONIC, &now); + wlr_scene_output_send_frame_done(m->scene_output, &now); + wlr_output_state_finish(&pending); } -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); +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); } -void -requeststartdrag(struct wl_listener *listener, void *data) -{ - struct wlr_seat_request_start_drag_event *event = data; +void requeststartdrag(struct wl_listener *listener, void *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 -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); +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); } -void -resize(Client *c, struct wlr_box geo, int interact) -{ - struct wlr_box *bbox; - struct wlr_box clip; +void resize(Client *c, struct wlr_box geo, int interact) { + struct wlr_box *bbox; + struct wlr_box clip; - if (!c->mon || !client_surface(c)->mapped) - return; + if (!c->mon || !client_surface(c)->mapped) + return; - bbox = interact ? &sgeom : &c->mon->w; + bbox = interact ? &sgeom : &c->mon->w; - client_set_bounds(c, geo.width, geo.height); - c->geom = geo; - applybounds(c, bbox); + client_set_bounds(c, geo.width, geo.height); + c->geom = geo; + applybounds(c, bbox); - /* Update scene-graph, including borders */ - wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); - wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); - wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw); - wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw); - wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw); - wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - 2 * c->bw); - wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw); - wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); - wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw); + /* Update scene-graph, including borders */ + wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); + wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); + wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw); + wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw); + wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw); + wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - 2 * c->bw); + wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw); + wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); + wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, + c->bw); - /* this is a no-op if size hasn't changed */ - c->resize = client_set_size(c, c->geom.width - 2 * c->bw, - c->geom.height - 2 * c->bw); - client_get_clip(c, &clip); - wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); + /* this is a no-op if size hasn't changed */ + c->resize = + client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); + client_get_clip(c, &clip); + wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); } -void -run(char *startup_cmd) -{ - /* 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); +void run(char *startup_cmd) { + /* 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) { - 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) { + 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 the startup script - * causing dwl to freeze when a user neither closes stdin - * nor consumes standard input in his startup script */ + /* Mark stdout as non-blocking to avoid the startup script + * causing dwl to freeze when a user neither closes stdin + * nor consumes standard input in his startup script */ - if (fd_set_nonblock(STDOUT_FILENO) < 0) - close(STDOUT_FILENO); + 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, "default"); + /* 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, "default"); - /* 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); + /* 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); } -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 - * 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) - wlr_cursor_set_surface(cursor, event->surface, - event->hotspot_x, event->hotspot_y); +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 + * 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) + wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x, + event->hotspot_y); } -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 - * 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) - wlr_cursor_set_xcursor(cursor, cursor_mgr, - wlr_cursor_shape_v1_name(event->shape)); +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 + * 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) + wlr_cursor_set_xcursor(cursor, cursor_mgr, + wlr_cursor_shape_v1_name(event->shape)); } -void -setfloating(Client *c, int floating) -{ - Client *p = client_get_parent(c); - c->isfloating = floating; - /* If in floating layout do not change the client's layer */ - if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange) - return; - wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen || - (p && p->isfullscreen) ? LyrFS - : c->isfloating ? LyrFloat : LyrTile]); - arrange(c->mon); - printstatus(); +void setfloating(Client *c, int floating) { + Client *p = client_get_parent(c); + c->isfloating = floating; + /* If in floating layout do not change the client's layer */ + if (!c->mon || !client_surface(c)->mapped || + !c->mon->lt[c->mon->sellt]->arrange) + return; + wlr_scene_node_reparent( + &c->scene->node, layers[c->isfullscreen || (p && p->isfullscreen) ? LyrFS + : c->isfloating ? LyrFloat + : LyrTile]); + arrange(c->mon); + printstatus(); } -void -setfullscreen(Client *c, int fullscreen) -{ - c->isfullscreen = fullscreen; - if (!c->mon || !client_surface(c)->mapped) - return; - c->bw = fullscreen ? 0 : borderpx; - client_set_fullscreen(c, fullscreen); - wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen - ? LyrFS : c->isfloating ? LyrFloat : LyrTile]); +void setfullscreen(Client *c, int fullscreen) { + c->isfullscreen = fullscreen; + if (!c->mon || !client_surface(c)->mapped) + return; + c->bw = fullscreen ? 0 : borderpx; + client_set_fullscreen(c, fullscreen); + wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ? LyrFS + : c->isfloating ? LyrFloat + : LyrTile]); - if (fullscreen) { - c->prev = c->geom; - resize(c, c->mon->m, 0); - } else { - /* restore previous size instead of arrange for floating windows since - * client positions are set by the user and cannot be recalculated */ - resize(c, c->prev, 0); - } - arrange(c->mon); - printstatus(); + if (fullscreen) { + c->prev = c->geom; + resize(c, c->mon->m, 0); + } else { + /* restore previous size instead of arrange for floating windows since + * client positions are set by the user and cannot be recalculated */ + resize(c, c->prev, 0); + } + arrange(c->mon); + printstatus(); } -void -setlayout(const Arg *arg) -{ - if (!selmon) - return; - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); - arrange(selmon); - printstatus(); +void setlayout(const Arg *arg) { + if (!selmon) + return; + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if (arg && arg->v) + selmon->lt[selmon->sellt] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, + LENGTH(selmon->ltsymbol)); + arrange(selmon); + printstatus(); } /* arg > 1.0 will set mfact absolutely */ -void -setmfact(const Arg *arg) -{ - float f; +void setmfact(const Arg *arg) { + float f; - if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange) - return; - f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f; - if (f < 0.1 || f > 0.9) - return; - selmon->mfact = f; - arrange(selmon); + if (!arg || !selmon || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f; + if (f < 0.1 || f > 0.9) + return; + selmon->mfact = f; + arrange(selmon); } -void -setmon(Client *c, Monitor *m, uint32_t newtags) -{ - Monitor *oldmon = c->mon; +void setmon(Client *c, Monitor *m, uint32_t newtags) { + Monitor *oldmon = c->mon; - if (oldmon == m) - return; - c->mon = m; - c->prev = c->geom; + if (oldmon == m) + return; + c->mon = m; + c->prev = c->geom; - /* Scene graph sends surface leave/enter events on move and resize */ - if (oldmon) - arrange(oldmon); - 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 */ - setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ - setfloating(c, c->isfloating); - } - focusclient(focustop(selmon), 1); + /* Scene graph sends surface leave/enter events on move and resize */ + if (oldmon) + arrange(oldmon); + 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 */ + setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */ + setfloating(c, c->isfloating); + } + focusclient(focustop(selmon), 1); } -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 them - */ - struct wlr_seat_request_set_primary_selection_event *event = data; - wlr_seat_set_primary_selection(seat, event->source, event->serial); +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 them + */ + 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 them - */ - struct wlr_seat_request_set_selection_event *event = data; - wlr_seat_set_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 them + */ + struct wlr_seat_request_set_selection_event *event = data; + wlr_seat_set_selection(seat, event->source, event->serial); } -void -setup(void) -{ - int drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; - struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; - sigemptyset(&sa.sa_mask); +void setup(void) { + 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 < (int)LENGTH(sig); i++) - sigaction(sig[i], &sa, NULL); + for (i = 0; i < (int)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); + /* 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); - /* 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. */ - if (!(backend = wlr_backend_autocreate(event_loop, &session))) - die("couldn't create backend"); + /* 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. */ + if (!(backend = wlr_backend_autocreate(event_loop, &session))) + die("couldn't create 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); - /* Autocreates a renderer, either Pixman, GLES2 or Vulkan for us. The user - * can also specify a renderer using the WLR_RENDERER env var. - * The renderer is responsible for defining the various pixel formats it - * supports for shared memory, this configures that for clients. */ - if (!(drw = wlr_renderer_autocreate(backend))) - die("couldn't create renderer"); - wl_signal_add(&drw->events.lost, &gpu_reset); + /* Autocreates a renderer, either Pixman, GLES2 or Vulkan for us. The user + * can also specify a renderer using the WLR_RENDERER env var. + * The renderer is responsible for defining the various pixel formats it + * supports for shared memory, this configures that for clients. */ + if (!(drw = wlr_renderer_autocreate(backend))) + die("couldn't create renderer"); + wl_signal_add(&drw->events.lost, &gpu_reset); - /* Create shm, drm and linux_dmabuf interfaces by ourselves. - * The simplest way is to call: - * wlr_renderer_init_wl_display(drw); - * but we need to create the linux_dmabuf interface manually 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 to call: + * wlr_renderer_init_wl_display(drw); + * but we need to create the linux_dmabuf interface manually 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); - /* Autocreates an allocator for us. - * The allocator is the bridge between the renderer and the backend. It - * handles the buffer creation, allowing wlroots to render onto the - * screen */ - if (!(alloc = wlr_allocator_autocreate(backend, drw))) - die("couldn't create allocator"); + /* Autocreates an allocator for us. + * The allocator is the bridge between the renderer and the backend. It + * handles the buffer creation, allowing wlroots to render onto the + * screen */ + 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_subcompositor_create(dpy); - wlr_data_device_manager_create(dpy); - wlr_export_dmabuf_manager_v1_create(dpy); - wlr_screencopy_manager_v1_create(dpy); - wlr_data_control_manager_v1_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_alpha_modifier_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_subcompositor_create(dpy); + wlr_data_device_manager_create(dpy); + wlr_export_dmabuf_manager_v1_create(dpy); + wlr_screencopy_manager_v1_create(dpy); + wlr_data_control_manager_v1_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_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 is 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); + /* Creates an output layout, which is 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); + 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, the xdg-shell and the layer-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); + /* Set up our client lists, the xdg-shell and the layer-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); - 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); - layer_shell = wlr_layer_shell_v1_create(dpy, 3); - wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface); + layer_shell = wlr_layer_shell_v1_create(dpy, 3); + wl_signal_add(&layer_shell->events.new_surface, &new_layer_surface); - 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); - 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.1f, 0.1f, 0.1f, 1.0f}); - wlr_scene_node_set_enabled(&locked_bg->node, 0); + 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.1f, 0.1f, 0.1f, 1.0f}); + wlr_scene_node_set_enabled(&locked_bg->node, 0); - /* 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(NULL, 24); - setenv("XCURSOR_SIZE", "24", 1); + /* 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(NULL, 24); + setenv("XCURSOR_SIZE", "24", 1); - /* - * 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 - * 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 + * 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); - 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); + 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); - /* - * 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_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_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); - 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); - /* Make sure XWayland clients don't connect to the parent X server, - * e.g when running in the x11 backend or the wayland backend and the - * compositor has Xwayland support */ - unsetenv("DISPLAY"); + /* Make sure XWayland clients don't connect to the parent X server, + * e.g when running in the x11 backend or the wayland backend and the + * compositor has Xwayland support */ + unsetenv("DISPLAY"); #ifdef XWAYLAND - /* - * Initialise the XWayland X server. - * It will be started when the first X client is started. - */ - if ((xwayland = wlr_xwayland_create(dpy, compositor, 1))) { - 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. + */ + if ((xwayland = wlr_xwayland_create(dpy, compositor, 1))) { + 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 (fork() == 0) { - dup2(STDERR_FILENO, STDOUT_FILENO); - setsid(); - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwl: execvp %s failed:", ((char **)arg->v)[0]); - } +void spawn(const Arg *arg) { + if (fork() == 0) { + dup2(STDERR_FILENO, STDOUT_FILENO); + setsid(); + execvp(((char **)arg->v)[0], (char **)arg->v); + die("dwl: execvp %s failed:", ((char **)arg->v)[0]); + } } -void -startdrag(struct wl_listener *listener, void *data) -{ - struct wlr_drag *drag = data; - if (!drag->icon) - return; +void startdrag(struct wl_listener *listener, void *data) { + 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(const Arg *arg) -{ - Client *sel = focustop(selmon); - if (!sel || (arg->ui & TAGMASK) == 0) - return; +void tag(const Arg *arg) { + Client *sel = focustop(selmon); + if (!sel || (arg->ui & TAGMASK) == 0) + return; - sel->tags = arg->ui & TAGMASK; - focusclient(focustop(selmon), 1); - arrange(selmon); - printstatus(); + sel->tags = arg->ui & TAGMASK; + focusclient(focustop(selmon), 1); + arrange(selmon); + printstatus(); } -void -tagmon(const Arg *arg) -{ - Client *sel = focustop(selmon); - if (sel) - setmon(sel, dirtomon(arg->i), 0); +void tagmon(const Arg *arg) { + Client *sel = focustop(selmon); + if (sel) + setmon(sel, dirtomon(arg->i), 0); } -void -tile(Monitor *m) -{ - unsigned int mw, my, ty; - int i, n = 0; - Client *c; +void tile(Monitor *m) { + unsigned int mw, my, ty; + int i, n = 0; + Client *c; - wl_list_for_each(c, &clients, link) - if (VISIBLEON(c, m) && !c->isfloating && !c->isfullscreen) - n++; - if (n == 0) - return; + wl_list_for_each(c, &clients, link) if (VISIBLEON(c, m) && !c->isfloating && + !c->isfullscreen) n++; + if (n == 0) + return; - if (n > m->nmaster) - mw = m->nmaster ? (int)roundf(m->w.width * m->mfact) : 0; - else - mw = m->w.width; - i = my = ty = 0; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) - continue; - if (i < m->nmaster) { - resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw, - .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0); - my += c->geom.height; - } else { - resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty, - .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0); - ty += c->geom.height; - } - i++; - } + if (n > m->nmaster) + mw = m->nmaster ? (int)roundf(m->w.width * m->mfact) : 0; + else + mw = m->w.width; + i = my = ty = 0; + wl_list_for_each(c, &clients, link) { + if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen) + continue; + if (i < m->nmaster) { + resize(c, + (struct wlr_box){.x = m->w.x, + .y = m->w.y + my, + .width = mw, + .height = (m->w.height - my) / + (MIN(n, m->nmaster) - i)}, + 0); + my += c->geom.height; + } else { + resize(c, + (struct wlr_box){.x = m->w.x + mw, + .y = m->w.y + ty, + .width = m->w.width - mw, + .height = (m->w.height - ty) / (n - i)}, + 0); + ty += c->geom.height; + } + i++; + } } -void -togglefloating(const Arg *arg) -{ - Client *sel = focustop(selmon); - /* return if fullscreen */ - if (sel && !sel->isfullscreen) - setfloating(sel, !sel->isfloating); +void togglefloating(const Arg *arg) { + Client *sel = focustop(selmon); + /* return if fullscreen */ + if (sel && !sel->isfullscreen) + setfloating(sel, !sel->isfloating); } -void -togglefullscreen(const Arg *arg) -{ - Client *sel = focustop(selmon); - if (sel) - setfullscreen(sel, !sel->isfullscreen); +void togglefullscreen(const Arg *arg) { + Client *sel = focustop(selmon); + if (sel) + setfullscreen(sel, !sel->isfullscreen); } -void -toggletag(const Arg *arg) -{ - uint32_t newtags; - Client *sel = focustop(selmon); - if (!sel || !(newtags = sel->tags ^ (arg->ui & TAGMASK))) - return; +void toggletag(const Arg *arg) { + uint32_t newtags; + Client *sel = focustop(selmon); + if (!sel || !(newtags = sel->tags ^ (arg->ui & TAGMASK))) + return; - sel->tags = newtags; - focusclient(focustop(selmon), 1); - arrange(selmon); - printstatus(); + sel->tags = newtags; + focusclient(focustop(selmon), 1); + arrange(selmon); + printstatus(); } -void -toggleview(const Arg *arg) -{ - uint32_t newtagset; - if (!(newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0)) - return; +void toggleview(const Arg *arg) { + uint32_t newtagset; + if (!(newtagset = + selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0)) + return; - selmon->tagset[selmon->seltags] = newtagset; - focusclient(focustop(selmon), 1); - arrange(selmon); - printstatus(); + selmon->tagset[selmon->seltags] = newtagset; + focusclient(focustop(selmon), 1); + arrange(selmon); + printstatus(); } -void -unlocksession(struct wl_listener *listener, void *data) -{ - SessionLock *lock = wl_container_of(listener, lock, unlock); - destroylock(lock, 1); +void unlocksession(struct wl_listener *listener, void *data) { + 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); +void unmaplayersurfacenotify(struct wl_listener *listener, void *data) { + LayerSurface *l = wl_container_of(listener, l, unmap); - l->mapped = 0; - wlr_scene_node_set_enabled(&l->scene->node, 0); - 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, 0); + 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 -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); - if (c == grabc) { - cursor_mode = CurNormal; - grabc = NULL; - } +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); + if (c == grabc) { + cursor_mode = CurNormal; + grabc = NULL; + } - if (client_is_unmanaged(c)) { - if (c == exclusive_focus) { - exclusive_focus = NULL; - focusclient(focustop(selmon), 1); - } - } else { - wl_list_remove(&c->link); - setmon(c, NULL, 0); - wl_list_remove(&c->flink); - } + if (client_is_unmanaged(c)) { + if (c == exclusive_focus) { + exclusive_focus = NULL; + focusclient(focustop(selmon), 1); + } + } else { + wl_list_remove(&c->link); + setmon(c, NULL, 0); + wl_list_remove(&c->flink); + } - 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; +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; - /* 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); - /* 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); + /* 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); - } - 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); + } + 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); - if (c == focustop(c->mon)) - printstatus(); +void updatetitle(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, set_title); + if (c == focustop(c->mon)) + printstatus(); } -void -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); - if (!c || c == focustop(selmon)) - return; +void 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); + if (!c || c == focustop(selmon)) + return; - c->isurgent = 1; - printstatus(); + c->isurgent = 1; + printstatus(); - if (client_surface(c)->mapped) - client_set_border_color(c, urgentcolor); + if (client_surface(c)->mapped) + client_set_border_color(c, urgentcolor); } -void -view(const Arg *arg) -{ - if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focusclient(focustop(selmon), 1); - arrange(selmon); - printstatus(); +void view(const Arg *arg) { + if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + focusclient(focustop(selmon), 1); + arrange(selmon); + printstatus(); } -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); +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); - /* 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 -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; +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; - 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); } -Monitor * -xytomon(double x, double y) -{ - struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y); - return o ? o->data : NULL; +Monitor *xytomon(double x, double y) { + 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; +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; - for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) { - if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))) - continue; + for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) { + 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 -zoom(const Arg *arg) -{ - Client *c, *sel = focustop(selmon); +void zoom(const Arg *arg) { + Client *c, *sel = focustop(selmon); - if (!sel || !selmon || !selmon->lt[selmon->sellt]->arrange || sel->isfloating) - return; + if (!sel || !selmon || !selmon->lt[selmon->sellt]->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); + focusclient(sel, 1); + arrange(selmon); } #ifdef XWAYLAND -void -activatex11(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, activate); +void activatex11(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, activate); - /* Only "managed" windows can be activated */ - if (!client_is_unmanaged(c)) - wlr_xwayland_surface_activate(c->surface.xwayland, 1); + /* Only "managed" windows can be activated */ + if (!client_is_unmanaged(c)) + wlr_xwayland_surface_activate(c->surface.xwayland, 1); } -void -associatex11(struct wl_listener *listener, void *data) -{ - Client *c = wl_container_of(listener, c, associate); +void associatex11(struct wl_listener *listener, void *data) { + 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 -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->lt[c->mon->sellt]->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); - } +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->lt[c->mon->sellt]->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); + } } -void -createnotifyx11(struct wl_listener *listener, void *data) -{ - struct wlr_xwayland_surface *xsurface = data; - Client *c; +void createnotifyx11(struct wl_listener *listener, void *data) { + 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; - c->bw = client_is_unmanaged(c) ? 0 : borderpx; + /* Allocate a Client for this surface */ + c = xsurface->data = ecalloc(1, sizeof(*c)); + c->surface.xwayland = xsurface; + c->type = X11; + c->bw = client_is_unmanaged(c) ? 0 : borderpx; - /* 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 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); } -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); +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); } -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->surface.xwayland->hints) - return; +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->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; +void xwaylandready(struct wl_listener *listener, void *data) { + 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); } #endif -int -main(int argc, char *argv[]) -{ - char *startup_cmd = NULL; - int c; +int main(int argc, char *argv[]) { + 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("dwl " 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("dwl " 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/util.c b/src/util.c index b925987..2f1195c 100644 --- a/src/util.c +++ b/src/util.c @@ -1,51 +1,47 @@ /* See LICENSE.dwm file for copyright and license details. */ +#include #include #include #include #include -#include #include "util.h" -void -die(const char *fmt, ...) { - va_list ap; +void die(const char *fmt, ...) { + va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } + if (fmt[0] && fmt[strlen(fmt) - 1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } - exit(1); + exit(1); } -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; +void *ecalloc(size_t nmemb, size_t size) { + void *p; - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; } -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 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; + } - return 0; + return 0; }