diff --git a/Makefile b/Makefile index 90d9db5..4a6c727 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ DWLDEVCFLAGS = -pedantic -Wall -Wextra -Wdeclaration-after-statement -Wno-unused PKGS = wlroots wayland-server xkbcommon libinput $(XLIBS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS) +#CC = zig cc all: dwl dwl: dwl.o util.o dwl-ipc-unstable-v2-protocol.o diff --git a/client.h b/client.h index 5a45edc..0554c0d 100644 --- a/client.h +++ b/client.h @@ -10,385 +10,385 @@ static inline int client_is_x11(Client *c) { #ifdef XWAYLAND - return c->type == X11Managed || c->type == X11Unmanaged; + return c->type == X11Managed || c->type == X11Unmanaged; #else - return 0; + return 0; #endif } static inline void client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min) { - struct wlr_xdg_toplevel *toplevel; - struct wlr_xdg_toplevel_state *state; + struct wlr_xdg_toplevel *toplevel; + struct wlr_xdg_toplevel_state *state; #ifdef XWAYLAND - if (client_is_x11(c)) { - xcb_size_hints_t *size_hints = c->surface.xwayland->size_hints; - if (size_hints) { - max->width = size_hints->max_width; - max->height = size_hints->max_height; - min->width = size_hints->min_width; - min->height = size_hints->min_height; - } - return; - } + if (client_is_x11(c)) { + xcb_size_hints_t *size_hints = c->surface.xwayland->size_hints; + if (size_hints) { + max->width = size_hints->max_width; + max->height = size_hints->max_height; + min->width = size_hints->min_width; + min->height = size_hints->min_height; + } + return; + } #endif - toplevel = c->surface.xdg->toplevel; - state = &toplevel->current; - max->width = state->max_width; - max->height = state->max_height; - min->width = state->min_width; - min->height = state->min_height; + toplevel = c->surface.xdg->toplevel; + state = &toplevel->current; + max->width = state->max_width; + max->height = state->max_height; + min->width = state->min_width; + min->height = state->min_height; } 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; - struct wlr_surface *root_surface; - struct wlr_layer_surface_v1 *layer_surface; - Client *c = NULL; - LayerSurface *l = NULL; - int type = -1; + struct wlr_xdg_surface *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 type; - root_surface = wlr_surface_get_root_surface(s); + if (!s) + return type; + root_surface = wlr_surface_get_root_surface(s); #ifdef XWAYLAND - if (wlr_surface_is_xwayland_surface(root_surface) - && (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) { - c = xsurface->data; - type = c->type; - goto end; - } + if (wlr_surface_is_xwayland_surface(root_surface) + && (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) { + c = xsurface->data; + type = c->type; + goto end; + } #endif - if (wlr_surface_is_layer_surface(root_surface) - && (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) { - l = layer_surface->data; - type = LayerShell; - goto end; - } + if (wlr_surface_is_layer_surface(root_surface) + && (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) { + l = layer_surface->data; + type = LayerShell; + goto end; + } - if (wlr_surface_is_xdg_surface(root_surface) - && (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) { - while (1) { - switch (xdg_surface->role) { - case WLR_XDG_SURFACE_ROLE_POPUP: - if (!xdg_surface->popup->parent) - return -1; - else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent)) - return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl); + if (wlr_surface_is_xdg_surface(root_surface) + && (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) { + while (1) { + switch (xdg_surface->role) { + case WLR_XDG_SURFACE_ROLE_POPUP: + if (!xdg_surface->popup->parent) + return -1; + else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent)) + return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl); - xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent); - 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 = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent); + 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_surface *surface; + struct wlr_xdg_surface *surface; #ifdef XWAYLAND - struct wlr_xwayland_surface *xsurface; - if (wlr_surface_is_xwayland_surface(s) - && (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) { - wlr_xwayland_surface_activate(xsurface, activated); - return; - } + struct wlr_xwayland_surface *xsurface; + if (wlr_surface_is_xwayland_surface(s) + && (xsurface = wlr_xwayland_surface_from_wlr_surface(s))) { + wlr_xwayland_surface_activate(xsurface, activated); + return; + } #endif - if (wlr_surface_is_xdg_surface(s) - && (surface = wlr_xdg_surface_from_wlr_surface(s)) - && surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) - wlr_xdg_toplevel_set_activated(surface->toplevel, activated); + if (wlr_surface_is_xdg_surface(s) + && (surface = wlr_xdg_surface_from_wlr_surface(s)) + && surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) + wlr_xdg_toplevel_set_activated(surface->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; + if (client_is_x11(c)) + return 0; #endif - if (c->surface.xdg->client->shell->version >= - XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && width >= 0 && height >= 0) - return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height); - return 0; + if (c->surface.xdg->client->shell->version >= + XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && width >= 0 && height >= 0) + return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height); + return 0; } static inline void client_for_each_surface(Client *c, wlr_surface_iterator_func_t fn, void *data) { - wlr_surface_for_each_surface(client_surface(c), fn, data); + wlr_surface_for_each_surface(client_surface(c), fn, data); #ifdef XWAYLAND - if (client_is_x11(c)) - return; + if (client_is_x11(c)) + return; #endif - wlr_xdg_surface_for_each_popup_surface(c->surface.xdg, fn, data); + wlr_xdg_surface_for_each_popup_surface(c->surface.xdg, fn, data); } static inline const char * client_get_appid(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->class; + if (client_is_x11(c)) + return c->surface.xwayland->class; #endif - return c->surface.xdg->toplevel->app_id; + return c->surface.xdg->toplevel->app_id; } static inline void client_get_geometry(Client *c, struct wlr_box *geom) { #ifdef XWAYLAND - if (client_is_x11(c)) { - geom->x = c->surface.xwayland->x; - geom->y = c->surface.xwayland->y; - geom->width = c->surface.xwayland->width; - geom->height = c->surface.xwayland->height; - return; - } + if (client_is_x11(c)) { + geom->x = c->surface.xwayland->x; + geom->y = c->surface.xwayland->y; + geom->width = c->surface.xwayland->width; + geom->height = c->surface.xwayland->height; + return; + } #endif - wlr_xdg_surface_get_geometry(c->surface.xdg, geom); + wlr_xdg_surface_get_geometry(c->surface.xdg, geom); } static inline Client * client_get_parent(Client *c) { - Client *p = NULL; + Client *p = NULL; #ifdef XWAYLAND - if (client_is_x11(c) && c->surface.xwayland->parent) - toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); + if (client_is_x11(c) && c->surface.xwayland->parent) + toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL); #endif - if (c->surface.xdg->toplevel->parent) - toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL); + if (c->surface.xdg->toplevel->parent) + toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL); - return p; + return p; } static inline const char * client_get_title(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->title; + if (client_is_x11(c)) + return c->surface.xwayland->title; #endif - return c->surface.xdg->toplevel->title; + return c->surface.xdg->toplevel->title; } static inline int client_is_float_type(Client *c) { - struct wlr_box min = {0}, max = {0}; - client_get_size_hints(c, &max, &min); + struct wlr_box min = {0}, max = {0}; + client_get_size_hints(c, &max, &min); #ifdef XWAYLAND - if (client_is_x11(c)) { - struct wlr_xwayland_surface *surface = c->surface.xwayland; - if (surface->modal) - return 1; + if (client_is_x11(c)) { + struct wlr_xwayland_surface *surface = c->surface.xwayland; + if (surface->modal) + return 1; - for (size_t i = 0; i < surface->window_type_len; i++) - if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] - || surface->window_type[i] == netatom[NetWMWindowTypeSplash] - || surface->window_type[i] == netatom[NetWMWindowTypeToolbar] - || surface->window_type[i] == netatom[NetWMWindowTypeUtility]) - return 1; - } + for (size_t i = 0; i < surface->window_type_len; i++) + if (surface->window_type[i] == netatom[NetWMWindowTypeDialog] + || surface->window_type[i] == netatom[NetWMWindowTypeSplash] + || surface->window_type[i] == netatom[NetWMWindowTypeToolbar] + || surface->window_type[i] == netatom[NetWMWindowTypeUtility]) + return 1; + } #endif - return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0) - && (min.width == max.width || min.height == max.height)); + return ((min.width > 0 || min.height > 0 || max.width > 0 || max.height > 0) + && (min.width == max.width || min.height == max.height)); } static inline int client_is_mapped(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->mapped; + if (client_is_x11(c)) + return c->surface.xwayland->mapped; #endif - return c->surface.xdg->mapped; + return c->surface.xdg->mapped; } 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; - if (!c->scene->node.enabled) - return 0; - wl_list_for_each(s, &client_surface(c)->current_outputs, link) - if (s->output == m->wlr_output) - return 1; - return 0; + /* This is needed for when you don't want to check formal assignment, + * but rather actual displaying of the pixels. + * Usually VISIBLEON suffices and is also faster. */ + struct wlr_surface_output *s; + if (!c->scene->node.enabled) + return 0; + wl_list_for_each(s, &client_surface(c)->current_outputs, link) + if (s->output == m->wlr_output) + return 1; + return 0; } static inline int client_is_stopped(Client *c) { - int pid; - siginfo_t in = {0}; + int pid; + siginfo_t in = {0}; #ifdef XWAYLAND - if (client_is_x11(c)) - return 0; + if (client_is_x11(c)) + return 0; #endif - wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); - if (waitid(P_PID, pid, &in, WNOHANG|WCONTINUED|WSTOPPED|WNOWAIT) < 0) { - /* This process is not our child process, while is very unluckely that - * it is stopped, in order to do not skip frames assume that it is. */ - if (errno == ECHILD) - return 1; - } else if (in.si_pid) { - if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED) - return 1; - if (in.si_code == CLD_CONTINUED) - return 0; - } + wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); + if (waitid(P_PID, pid, &in, WNOHANG|WCONTINUED|WSTOPPED|WNOWAIT) < 0) { + /* This process is not our child process, while is very unluckely that + * it is stopped, in order to do not skip frames assume that it is. */ + if (errno == ECHILD) + return 1; + } else if (in.si_pid) { + if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED) + return 1; + if (in.si_code == CLD_CONTINUED) + return 0; + } - return 0; + return 0; } static inline int client_is_unmanaged(Client *c) { #ifdef XWAYLAND - return c->type == X11Unmanaged; + return c->type == X11Unmanaged; #endif - return 0; + return 0; } static inline void client_notify_enter(struct wlr_surface *s, struct wlr_keyboard *kb) { - if (kb) - wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, - kb->num_keycodes, &kb->modifiers); - else - wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); + if (kb) + wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, + kb->num_keycodes, &kb->modifiers); + else + wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); } static inline void client_restack_surface(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - wlr_xwayland_surface_restack(c->surface.xwayland, NULL, - XCB_STACK_MODE_ABOVE); + if (client_is_x11(c)) + wlr_xwayland_surface_restack(c->surface.xwayland, NULL, + XCB_STACK_MODE_ABOVE); #endif - return; + return; } static inline void client_send_close(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_close(c->surface.xwayland); - return; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_close(c->surface.xwayland); + return; + } #endif - wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel); + wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel); } static inline void client_set_fullscreen(Client *c, int fullscreen) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen); - return; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen); + return; + } #endif - wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); + wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); } static inline uint32_t client_set_size(Client *c, uint32_t width, uint32_t height) { #ifdef XWAYLAND - if (client_is_x11(c)) { - wlr_xwayland_surface_configure(c->surface.xwayland, - c->geom.x, c->geom.y, width, height); - return 0; - } + if (client_is_x11(c)) { + wlr_xwayland_surface_configure(c->surface.xwayland, + c->geom.x, c->geom.y, width, height); + return 0; + } #endif - if (width == c->surface.xdg->toplevel->current.width - && height ==c->surface.xdg->toplevel->current.height) - return 0; - return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height); + if (width == c->surface.xdg->toplevel->current.width + && height ==c->surface.xdg->toplevel->current.height) + return 0; + return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height); } static inline void client_set_tiled(Client *c, uint32_t edges) { #ifdef XWAYLAND - if (client_is_x11(c)) - return; + if (client_is_x11(c)) + return; #endif - wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges); + wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges); } static inline struct wlr_surface * client_surface_at(Client *c, double cx, double cy, double *sx, double *sy) { #ifdef XWAYLAND - if (client_is_x11(c)) - return wlr_surface_surface_at(c->surface.xwayland->surface, - cx, cy, sx, sy); + if (client_is_x11(c)) + return wlr_surface_surface_at(c->surface.xwayland->surface, + cx, cy, sx, sy); #endif - return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy); + return wlr_xdg_surface_surface_at(c->surface.xdg, cx, cy, sx, sy); } static inline int client_wants_focus(Client *c) { #ifdef XWAYLAND - return client_is_unmanaged(c) - && wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) - && wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; + return client_is_unmanaged(c) + && wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) + && wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; #endif - return 0; + return 0; } static inline int client_wants_fullscreen(Client *c) { #ifdef XWAYLAND - if (client_is_x11(c)) - return c->surface.xwayland->fullscreen; + if (client_is_x11(c)) + return c->surface.xwayland->fullscreen; #endif - return c->surface.xdg->toplevel->requested.fullscreen; + return c->surface.xdg->toplevel->requested.fullscreen; } diff --git a/config.def.h b/config.def.h index e5b9049..332d9ea 100644 --- a/config.def.h +++ b/config.def.h @@ -15,44 +15,42 @@ static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; static const int tagcount = 9; static const Rule rules[] = { - /* app_id title tags mask isfloating monitor */ - /* examples: - { "Gimp", NULL, 0, 1, -1 }, - */ - { "firefox", NULL, 1 << 8, 0, -1 }, + /* soft_id title tags mask isfloating monitor */ + { "Gimp", NULL, 1 << 8, 0, -1 }, }; /* layout(s) */ static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, + /* symbol arrange function */ + { "[]=", tile }, + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, }; /* autostart */ static const char *const autostart[] = { "wbg", "/home/suwako/.local/share/wallpapers/hurandorusukaretsuto-kabegami-2560x1600_7-1080.jpg", NULL, "dwl-bar", NULL, + "someblocks", NULL, NULL /* terminate */ }; /* monitors */ static const MonitorRule monrules[] = { - /* name mfact nmaster scale layout rotate/reflect x y */ - /* example of a HiDPI laptop monitor: - { "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, - */ - /* defaults */ - { NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, + /* name mfact nmaster scale layout rotate/reflect x y */ + /* example of a HiDPI laptop monitor: + { "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, + */ + /* defaults */ + { NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, }; /* keyboard */ static const struct xkb_rule_names xkb_rules = { - /* can specify fields: rules, model, layout, variant, options */ - /* example: - .options = "ctrl:nocaps", - */ + /* can specify fields: rules, model, layout, variant, options */ + /* example: + .options = "ctrl:nocaps", + */ .layout = "jp", }; @@ -105,10 +103,10 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA #define MODKEY WLR_MODIFIER_LOGO #define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|WLR_MODIFIER_SHIFT, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,KEY,toggletag, {.ui = 1 << TAG} } + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|WLR_MODIFIER_SHIFT, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,KEY,toggletag, {.ui = 1 << TAG} } #define STACKKEYS(MOD,ACTION) \ { MOD, XK_j, ACTION##stack, {.i = INC(+1) } }, \ { MOD, XK_k, ACTION##stack, {.i = INC(-1) } }, \ @@ -124,70 +122,75 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA /* commands */ static const char *termcmd[] = { TERMINAL, NULL }; -static const Key keys[] = { - /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ - /* modifier key function argument */ - TAGKEYS( XKB_KEY_1, 0), - TAGKEYS( XKB_KEY_2, 1), - TAGKEYS( XKB_KEY_3, 2), - TAGKEYS( XKB_KEY_4, 3), - TAGKEYS( XKB_KEY_5, 4), - TAGKEYS( XKB_KEY_6, 5), - TAGKEYS( XKB_KEY_7, 6), - TAGKEYS( XKB_KEY_8, 7), - TAGKEYS( XKB_KEY_9, 8), +#include "shiftview.c" - { MODKEY, XKB_KEY_Tab, view, {0} }, - { MODKEY, XKB_KEY_q, killclient, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} }, - { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, - { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, +static const Key keys[] = { + /* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */ + /* modifier key function argument */ + TAGKEYS( XKB_KEY_1, 0), + TAGKEYS( XKB_KEY_2, 1), + TAGKEYS( XKB_KEY_3, 2), + TAGKEYS( XKB_KEY_4, 3), + TAGKEYS( XKB_KEY_5, 4), + TAGKEYS( XKB_KEY_6, 5), + TAGKEYS( XKB_KEY_7, 6), + TAGKEYS( XKB_KEY_8, 7), + TAGKEYS( XKB_KEY_9, 8), + + { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_0, tag, {.ui = ~0} }, + + { MODKEY, XKB_KEY_Tab, view, {0} }, + { MODKEY, XKB_KEY_q, killclient, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} }, + { MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XKB_KEY_i, incnmaster, {.i = +1} }, + { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, { MODKEY, XKB_KEY_p, spawn, {.v = (const char*[]){ "mpc", "toggle", NULL } } }, - //{ MODKEY, XKB_KEY_Return, zoom, {0} }, - { MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} }, + //{ MODKEY, XKB_KEY_Return, zoom, {0} }, + { MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} }, { MODKEY, XKB_KEY_Eisu_toggle, spawn, {.v = (const char*[]){ "wofi-calc", NULL } } }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_S, spawn, SHCMD("swaylock -i ~/.local/share/wallpapers/hurandorusukaretsuto-kabegami-2560x1600_7-1080.png") }, - { MODKEY, XKB_KEY_d, spawn, {.v = (const char*[]){ "wofi", "--show", "drun", NULL } } }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D, spawn, {.v = (const char*[]){ "wofi-pass", NULL } } }, - { MODKEY, XKB_KEY_f, togglefullscreen, {0} }, - //{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XKB_KEY_d, spawn, {.v = (const char*[]){ "wofi", "--show", "drun", NULL } } }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_D, spawn, {.v = (const char*[]){ "wofi-pass", NULL } } }, + { MODKEY, XKB_KEY_f, togglefullscreen, {0} }, + //{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} }, //{ MODKEY, XKB_KEY_g, shiftview, { .i = -1 } }, //{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_G, shifttag, { .i = -1 } }, - { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} }, - { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, - { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, - { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} }, + { MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} }, + { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, + { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, + { MODKEY, XKB_KEY_l, setmfact, {.f = +0.05} }, { MODKEY, XKB_KEY_z, spawn, {.v = (const char*[]){ "wofi-youtube", "-i", NULL } } }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Z, spawn, {.v = (const char*[]){ "wofi-youtube", "-s", NULL } } }, { MODKEY, XKB_KEY_b, toggle_visibility, {0}}, - { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, - //{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, + { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, + //{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} }, - { MODKEY, XKB_KEY_comma, spawn, {.v = (const char*[]){ "mpc", "prev", NULL } } }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, spawn, {.v = (const char*[]){ "mpc", "seek", "0%", NULL } } }, - { MODKEY, XKB_KEY_period, spawn, {.v = (const char*[]){ "mpc", "next", NULL } } }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, spawn, {.v = (const char*[]){ "mpc", "repeat", NULL } } }, + { MODKEY, XKB_KEY_comma, spawn, {.v = (const char*[]){ "mpc", "prev", NULL } } }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, spawn, {.v = (const char*[]){ "mpc", "seek", "0%", NULL } } }, + { MODKEY, XKB_KEY_period, spawn, {.v = (const char*[]){ "mpc", "next", NULL } } }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, spawn, {.v = (const char*[]){ "mpc", "repeat", NULL } } }, - { MODKEY, XKB_KEY_space, setlayout, {0} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY, XKB_KEY_space, zoom, {0} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, - { MODKEY, XKB_KEY_Left, focusmon, {.i = WLR_DIRECTION_LEFT} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, tagmon, {.i = WLR_DIRECTION_LEFT} }, - { MODKEY, XKB_KEY_Right, focusmon, {.i = WLR_DIRECTION_RIGHT} }, - { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, tagmon, {.i = WLR_DIRECTION_RIGHT} }, + { MODKEY, XKB_KEY_Left, focusmon, {.i = WLR_DIRECTION_LEFT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Left, tagmon, {.i = WLR_DIRECTION_LEFT} }, + { MODKEY, XKB_KEY_Right, focusmon, {.i = WLR_DIRECTION_RIGHT} }, + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Right, tagmon, {.i = WLR_DIRECTION_RIGHT} }, - /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */ - { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} }, + /* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */ + { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} }, #define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} } - CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), - CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12), + CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), + CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12), }; static const Button buttons[] = { - { MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} }, - { MODKEY, BTN_MIDDLE, togglefloating, {0} }, - { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} }, + { MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} }, + { MODKEY, BTN_MIDDLE, togglefloating, {0} }, + { MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} }, }; diff --git a/shiftview.c b/shiftview.c new file mode 100644 index 0000000..ca04335 --- /dev/null +++ b/shiftview.c @@ -0,0 +1,35 @@ +// "arg->i" stores the number of tags to shift right (positive value) +// or left (negative value) +void +shiftview(const Arg *arg) +{ + Arg a; + Client *c; + size_t ntags = tagcount; + bool visible = false; + int i = arg->i; + int count = 0; + int nextseltags, curseltags = selmon->tagset[selmon->seltags]; + + do { + if (i > 0) // left circular shift + nextseltags = (curseltags << i) | (curseltags >> (ntags - i)); + else // right circular shift + nextseltags = curseltags >> (- i) | (curseltags << (ntags + i)); + + // Check if the tag is visible + wl_list_for_each(c, &clients, link) { + if (c->mon == selmon && nextseltags & c->tags) { + visible = true; + break; + } + } + + i += arg->i; + } while (!visible && ++count <= ntags); + + if (count <= ntags) { + a.i = nextseltags; + view(&a); + } +} diff --git a/util.c b/util.c index cca7c19..b8e1c14 100644 --- a/util.c +++ b/util.c @@ -8,28 +8,28 @@ void die(const char *fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } - exit(1); + exit(1); } void * ecalloc(size_t nmemb, size_t size) { - void *p; + void *p; - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; }