From 2943b066f420f73849a2bd1c33cb416a3b43df59 Mon Sep 17 00:00:00 2001 From: Ray Andrew <4437323+rayandrew@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:23:10 -0500 Subject: [PATCH] add minimize --- client.h | 9 ++-- config.def.h | 11 +++++ dwl.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 3 deletions(-) diff --git a/client.h b/client.h index bc9cad2..fd30473 100644 --- a/client.h +++ b/client.h @@ -94,9 +94,12 @@ 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); + struct wlr_xwayland_surface *surface; + if ((surface = wlr_xwayland_surface_try_from_wlr_surface(s))) { + if (activated && surface->minimized) + wlr_xwayland_surface_set_minimized(surface, false); + + wlr_xwayland_surface_activate(surface, activated); return; } #endif diff --git a/config.def.h b/config.def.h index afcce1f..8164359 100644 --- a/config.def.h +++ b/config.def.h @@ -82,6 +82,7 @@ static const char *const autostart[] = { { "teams", NULL, 0, 1, 0, 0, -1 }, { "wezterm", NULL, 0, 0, 1, 1, -1 }, /* make wezterm swallow clients that are not wezterm */ { "foot", NULL, 0, 0, 1, 1, -1 }, /* make foot swallow clients that are not foot */ + { "thesaurus-syn", NULL, 0, 1, 1, 1, -1 }, /* make foot swallow clients that are not foot */ { NULL, "wev", 0, 0, 0, 1, -1 }, /* xev */ { NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */ }; @@ -183,6 +184,7 @@ static const char *termcmd[] = { TERM_CMD, NULL }; // static const char *menucmd[] = { "wofi", "--show=drun", NULL }; static const char *menucmd[] = { "rofi", "-show", "drun", NULL }; static const char *calccmd[] = { "rofi", "-show", "calc", "-modi", "calc", "-no-show-match", "-no-sort", "-kb-accept-custom", "Return", "-kb-accept-entry", "Control+Return", "-calc-command", "wl-copy {result}", "-theme", "~/.config/rofi/calc.rasi", NULL}; +static const char *clipboardcmd[] = { "rofi", "-modi", "clipboard:~/bin/cliphist-rofi-img", "-show", "clipboard", "-show-icons", "-theme", "~/.config/rofi/clipboard.rasi", NULL }; static const char *swaynccmd[] = { "swaync-client", "-t", "-sw", NULL }; // volume // static const char *volmicmutecmd[] = { "/usr/bin/pactl", "set-source-mute", "@DEFAULT_SOURCE@", "toggle", NULL }; @@ -220,12 +222,16 @@ static const Key keys[] = { /* modifier key function argument */ { MODKEY, XKB_KEY_space, spawn, {.v = menucmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, spawn, {.v = calccmd} }, + { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_space, spawn, {.v = clipboardcmd} }, { MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} }, // { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_B, togglebar, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, focusstack, {.i = +1} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, focusstack, {.i = -1} }, + { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_j, relativeswap, {.i = +1} }, + { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_k, relativeswap, {.i = -1} }, + { MODKEY, XKB_KEY_h, focusdir, {.ui = 0} }, { MODKEY, XKB_KEY_l, focusdir, {.ui = 1} }, { MODKEY, XKB_KEY_k, focusdir, {.ui = 2} }, @@ -304,6 +310,11 @@ static const Key keys[] = { { MODKEY, XKB_KEY_n, spawn, {.v = swaynccmd}}, { 0, XKB_KEY_F12, spawn, SHCMD("~/bin/dwm-man") }, + // Thesaurus + { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_T, spawn, SHCMD("~/bin/thesaurus-rofi") }, + { MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_t, spawn, SHCMD("~/bin/thesaurus-rofi-syn") }, + + /* 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} }, // { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT, XKB_KEY_Terminate_Server, spawn, KILL_DWL }, diff --git a/dwl.c b/dwl.c index 4e7e6f2..a104988 100644 --- a/dwl.c +++ b/dwl.c @@ -154,6 +154,7 @@ struct Client { #ifdef XWAYLAND struct wl_listener activate; struct wl_listener associate; + struct wl_listener minimize; struct wl_listener dissociate; struct wl_listener configure; struct wl_listener set_hints; @@ -345,6 +346,7 @@ static void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resour static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset); static void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource); static void focusclient(Client *c, int lift); +static void focusto(const Arg *arg); static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); static void focusdir(const Arg *arg); @@ -383,6 +385,7 @@ static void pointerfocus(Client *c, struct wlr_surface *surface, static void powermgrsetmode(struct wl_listener *listener, void *data); static void printstatus(void); static void quit(const Arg *arg); +static void relativeswap(const Arg *arg); static void rendermon(struct wl_listener *listener, void *data); static void requestdecorationmode(struct wl_listener *listener, void *data); static void requeststartdrag(struct wl_listener *listener, void *data); @@ -405,6 +408,8 @@ static void setsel(struct wl_listener *listener, void *data); static void setup(void); static void spawn(const Arg *arg); static void startdrag(struct wl_listener *listener, void *data); +static void swapstack(const Arg *arg); +static void relativeswap(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); @@ -424,9 +429,11 @@ static void urgent(struct wl_listener *listener, void *data); static void view(const Arg *arg); static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualpointer(struct wl_listener *listener, void *data); +static Client *nextvisible(int i, struct wl_list *from, Monitor *m); 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); +static void wl_list_swap(struct wl_list *a, struct wl_list *b); static void zoom(const Arg *arg); static pid_t getparentprocess(pid_t p); static int isdescprocess(pid_t p, pid_t c); @@ -515,6 +522,7 @@ static void configurex11(struct wl_listener *listener, void *data); static void createnotifyx11(struct wl_listener *listener, void *data); static void dissociatex11(struct wl_listener *listener, void *data); static xcb_atom_t getatom(xcb_connection_t *xc, const char *name); +static void minimizenotify(struct wl_listener *listener, void *data); static void sethints(struct wl_listener *listener, void *data); static void xwaylandready(struct wl_listener *listener, void *data); static struct wlr_xwayland *xwayland; @@ -1632,6 +1640,7 @@ destroynotify(struct wl_listener *listener, void *data) wl_list_remove(&c->activate.link); wl_list_remove(&c->associate.link); wl_list_remove(&c->configure.link); + wl_list_remove(&c->minimize.link); wl_list_remove(&c->dissociate.link); wl_list_remove(&c->set_hints.link); } else @@ -1985,6 +1994,21 @@ focusclient(Client *c, int lift) wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, 1); } +void +focusto(const Arg *arg) +{ + Client *c, *sel = focustop(selmon); + int i; + if (!sel || (sel->isfullscreen && !client_has_children(sel))) + return; + + i = arg->i > -1 ? arg->i + 1 : arg->i; + + c = nextvisible(i, &clients, selmon); + if (c) + focusclient(c , 1); +} + void focusmon(const Arg *arg) { @@ -2881,6 +2905,24 @@ quit(const Arg *arg) wl_display_terminate(dpy); } +void +relativeswap(const Arg *arg) +{ + Client *trgt, *sel = focustop(selmon); + + if (!sel || !selmon) + return; + + trgt = nextvisible(arg->i, &sel->link, selmon); + if (!trgt || trgt == sel) + return; + + wl_list_swap(&sel->link, &trgt->link); + + focusclient(sel, 1); + arrange(selmon); +} + void rendermon(struct wl_listener *listener, void *data) { @@ -3508,6 +3550,26 @@ startdrag(struct wl_listener *listener, void *data) LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon); } +void +swapstack(const Arg *arg) +{ + Client *trgt, *sel = focustop(selmon); + int i; + + if (!sel || !selmon) + return; + + i = arg->i > -1 ? arg->i + 1 : arg->i; + trgt = nextvisible(i, &clients, selmon); + if (!trgt || trgt == sel) + return; + + wl_list_swap(&sel->link, &trgt->link); + + focusclient(sel, 1); + arrange(selmon); +} + void tag(const Arg *arg) { @@ -3931,6 +3993,28 @@ virtualpointer(struct wl_listener *listener, void *data) wlr_cursor_map_input_to_output(cursor, device, event->suggested_output); } +Client * +nextvisible(int i, struct wl_list *from, Monitor *m) +{ + Client *c; + if (i >= 0){ + wl_list_for_each(c, from, link) { + // if (VISIBLEON(c , m) && &c->link != from && i--) + if (VISIBLEON(c , m)) { + if (--i == 0) + return c; + } + } + } else if (i < 0) { + wl_list_for_each_reverse(c, from, link) { + if (VISIBLEON(c , m)) + if (++i == 0) + return c; + } + } + return NULL; +} + Monitor * xytomon(double x, double y) { @@ -3938,6 +4022,29 @@ xytomon(double x, double y) return o ? o->data : NULL; } +void +wl_list_swap(struct wl_list *a, struct wl_list *b) +{ + struct wl_list *prev_a = a->prev; + struct wl_list *prev_b = b->prev; + + if (prev_b == a) { + wl_list_remove(a); + wl_list_insert(b, a); + return; + } + if (prev_a == b) { + wl_list_remove(b); + wl_list_insert(a, b); + return; + } + wl_list_remove(a); + wl_list_insert(prev_b, a); + + wl_list_remove(b); + wl_list_insert(prev_a, b); +} + void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, LayerSurface **pl, double *nx, double *ny) @@ -4105,6 +4212,7 @@ createnotifyx11(struct wl_listener *listener, void *data) 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_minimize, &c->minimize, minimizenotify); 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); @@ -4132,6 +4240,21 @@ getatom(xcb_connection_t *xc, const char *name) return atom; } +void +minimizenotify(struct wl_listener *listener, void *data) +{ + Client *c = wl_container_of(listener, c, minimize); + struct wlr_xwayland_surface *xsurface = c->surface.xwayland; + struct wlr_xwayland_minimize_event *e = data; + int focused; + + if (xsurface->surface == NULL || !xsurface->surface->mapped) + return; + + focused = seat->keyboard_state.focused_surface == xsurface->surface; + wlr_xwayland_surface_set_minimized(xsurface, !focused && e->minimize); +} + void sethints(struct wl_listener *listener, void *data) {