From 2f94b43b62bb860c2455233ad5b5f864b0720019 Mon Sep 17 00:00:00 2001 From: speedie Date: Wed, 30 Nov 2022 18:37:59 +0100 Subject: [PATCH] Add marking --- docs/example.signal | 3 + docs/keybinds | 3 + keybinds.h | 183 +++++++++++++++++++++++--------------------- signal.h | 3 + speedwm.c | 89 ++++++++++++++++++++- 5 files changed, 192 insertions(+), 89 deletions(-) diff --git a/docs/example.signal b/docs/example.signal index cc1dd28..e37e68f 100644 --- a/docs/example.signal +++ b/docs/example.signal @@ -113,4 +113,7 @@ - 113 - Enter an empty layout where all clients are hidden - 114 - Increase barpadding and gaps by 1 - 115 - Decrease barpadding and gaps by 1 +- 116 - Toggle mark on a client. +- 117 - Swap focus with the marked client. +- 118 - Swap the focused client with the marked client. diff --git a/docs/keybinds b/docs/keybinds index 9da85ff..0ad0c41 100644 --- a/docs/keybinds +++ b/docs/keybinds @@ -38,6 +38,9 @@ These keybinds are for navigating speedwm - Super+/ - Focus the next monitor. - Super+. - Increase bar padding by 1 - Super+, - Decrease bar padding by 1 +- Super+\ - Toggle mark on a client. +- Super+] - Swap focused client with the marked client. +- Super+[ - Swap focus with the marked client. - Super+1 - Move to tag 1 - Super+2 - Move to tag 2 - Super+3 - Move to tag 3 diff --git a/keybinds.h b/keybinds.h index 4c1c0f9..66f3408 100644 --- a/keybinds.h +++ b/keybinds.h @@ -44,8 +44,8 @@ static Key keys[] = { /* modifier chain key key function argument */ /* Run keybinds */ - { MODIFIER1|SHIFT, -1, XK_semicolon, spawn, cmd( "dmenu_run -l 0 -p 'Run:'" ) }, { MODIFIER1, -1, XK_semicolon, spawn, cmd( "j4-dmenu-desktop --term=st --dmenu='dmenu -l 20 -p Open:'" ) }, + { MODIFIER1|SHIFT, -1, XK_semicolon, spawn, cmd( "dmenu_run -l 0 -p 'Run:'" ) }, { MODIFIER1|CONTROL|SHIFT, -1, XK_semicolon, spawn, cmd( "speedwm-applist" ) }, /* Application keybinds */ @@ -84,6 +84,11 @@ static Key keys[] = { #if USESYSTRAY { MODIFIER1, -1, XK_s, togglesystray, {0} }, #endif + + /* Switcher */ + #if USESWITCHER + { MODIFIER1, -1, XK_Tab, switcherstart, {0} }, + #endif /* Layout keybinds */ { MODIFIER1|CONTROL|SHIFT, -1, XK_a, cyclelayout, {.i = -1 } }, @@ -132,115 +137,112 @@ static Key keys[] = { { MODIFIER1, -1, XK_comma, setbarpadding, {.i = -1 } }, { MODIFIER1|SHIFT, -1, XK_period, setbpgaps, {.i = +1 } }, { MODIFIER1|SHIFT, -1, XK_comma, setbpgaps, {.i = -1 } }, - #if USESWITCHER - { MODIFIER1, -1, XK_Tab, switcherstart, {0} }, - #endif { MODIFIER1|CONTROL, -1, XK_i, incstackcount, {.i = +1 } }, { MODIFIER1|CONTROL, -1, XK_u, incstackcount, {.i = -1 } }, /* Floating mode keybinds */ - { MODIFIER1, -1, XK_w, moveresizeaspect, {.i = +24} }, - { MODIFIER1, -1, XK_e, moveresizeaspect, {.i = -24} }, - { MODIFIER1, -1, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } }, - { MODIFIER1, -1, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } }, - { MODIFIER1, -1, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } }, - { MODIFIER1, -1, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } }, - { MODIFIER1|SHIFT, -1, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } }, - { MODIFIER1|SHIFT, -1, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } }, - { MODIFIER1|SHIFT, -1, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } }, - { MODIFIER1|SHIFT, -1, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } }, - { MODIFIER1|CONTROL, -1, XK_Up, moveresizeedge, {.v = "t"} }, - { MODIFIER1|CONTROL, -1, XK_Down, moveresizeedge, {.v = "b"} }, - { MODIFIER1|CONTROL, -1, XK_Left, moveresizeedge, {.v = "l"} }, - { MODIFIER1|CONTROL, -1, XK_Right, moveresizeedge, {.v = "r"} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_Up, moveresizeedge, {.v = "T"} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_Down, moveresizeedge, {.v = "B"} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_Left, moveresizeedge, {.v = "L"} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_Right, moveresizeedge, {.v = "R"} }, + { MODIFIER1, -1, XK_w, moveresizeaspect, {.i = +24} }, + { MODIFIER1, -1, XK_e, moveresizeaspect, {.i = -24} }, + { MODIFIER1, -1, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } }, + { MODIFIER1, -1, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } }, + { MODIFIER1, -1, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } }, + { MODIFIER1, -1, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } }, + { MODIFIER1|SHIFT, -1, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } }, + { MODIFIER1|SHIFT, -1, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } }, + { MODIFIER1|SHIFT, -1, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } }, + { MODIFIER1|SHIFT, -1, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } }, + { MODIFIER1|CONTROL, -1, XK_Up, moveresizeedge, {.v = "t"} }, + { MODIFIER1|CONTROL, -1, XK_Down, moveresizeedge, {.v = "b"} }, + { MODIFIER1|CONTROL, -1, XK_Left, moveresizeedge, {.v = "l"} }, + { MODIFIER1|CONTROL, -1, XK_Right, moveresizeedge, {.v = "r"} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_Up, moveresizeedge, {.v = "T"} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_Down, moveresizeedge, {.v = "B"} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_Left, moveresizeedge, {.v = "L"} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_Right, moveresizeedge, {.v = "R"} }, /* Tag keybinds */ - TAGKEYS( -1, XK_1, 0) - TAGKEYS( -1, XK_2, 1) - TAGKEYS( -1, XK_3, 2) - TAGKEYS( -1, XK_4, 3) - TAGKEYS( -1, XK_5, 4) - TAGKEYS( -1, XK_6, 5) - TAGKEYS( -1, XK_7, 6) - TAGKEYS( -1, XK_8, 7) - TAGKEYS( -1, XK_9, 8) - { MODIFIER1|CONTROL, -1, XK_a, viewtoleft, {0} }, - { MODIFIER1|CONTROL, -1, XK_d, viewtoright, {0} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_z, viewtoleft_vacant, {0} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_c, viewtoright_vacant, {0} }, + TAGKEYS( -1, XK_1, 0) + TAGKEYS( -1, XK_2, 1) + TAGKEYS( -1, XK_3, 2) + TAGKEYS( -1, XK_4, 3) + TAGKEYS( -1, XK_5, 4) + TAGKEYS( -1, XK_6, 5) + TAGKEYS( -1, XK_7, 6) + TAGKEYS( -1, XK_8, 7) + TAGKEYS( -1, XK_9, 8) + { MODIFIER1|CONTROL, -1, XK_a, viewtoleft, {0} }, + { MODIFIER1|CONTROL, -1, XK_d, viewtoright, {0} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_z, viewtoleft_vacant, {0} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_c, viewtoright_vacant, {0} }, /* Hide/Show keybinds */ - { MODIFIER1, -1, XK_o, hide, {0} }, - { MODIFIER1|CONTROL, -1, XK_o, show, {0} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_o, showall, {0} }, - { MODIFIER1|CONTROL|SHIFT, -1, XK_p, hideall, {0} }, + { MODIFIER1, -1, XK_o, hide, {0} }, + { MODIFIER1|CONTROL, -1, XK_o, show, {0} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_o, showall, {0} }, + { MODIFIER1|CONTROL|SHIFT, -1, XK_p, hideall, {0} }, /* Chained keybinds */ - { MODIFIER1, XK_c, XK_w, spawn, cmd( TERMINAL "speedwm-core -curl-weather" ) }, - { MODIFIER1, XK_c, XK_n, spawn, cmd( "cmus-remote --next" ) }, - { MODIFIER1, XK_c, XK_p, spawn, cmd( "cmus-remote --prev" ) }, - { MODIFIER1, XK_r, XK_s, spawn, cmd( "screenkey" ) }, - { MODIFIER1, XK_r, XK_d, spawn, cmd( "pkill screenkey" ) }, - { MODIFIER1, XK_t, XK_r, reorganizetags, {0} }, - { MODIFIER1, XK_p, XK_t, togglebarpadding, {0} }, - { MODIFIER1, XK_p, XK_u, setbarpadding, {.i = +5 } }, - { MODIFIER1, XK_p, XK_d, setbarpadding, {.i = -5 } }, - { MODIFIER1, XK_p, XK_r, resetbarpadding, {0} }, + { MODIFIER1, XK_c, XK_w, spawn, cmd( TERMINAL "speedwm-core -curl-weather" ) }, + { MODIFIER1, XK_c, XK_n, spawn, cmd( "cmus-remote --next" ) }, + { MODIFIER1, XK_c, XK_p, spawn, cmd( "cmus-remote --prev" ) }, + { MODIFIER1, XK_r, XK_s, spawn, cmd( "screenkey" ) }, + { MODIFIER1, XK_r, XK_d, spawn, cmd( "pkill screenkey" ) }, + { MODIFIER1, XK_t, XK_r, reorganizetags, {0} }, + { MODIFIER1, XK_p, XK_t, togglebarpadding, {0} }, + { MODIFIER1, XK_p, XK_u, setbarpadding, {.i = +5 } }, + { MODIFIER1, XK_p, XK_d, setbarpadding, {.i = -5 } }, + { MODIFIER1, XK_p, XK_r, resetbarpadding, {0} }, /* Chained toggle keybinds */ - { MODIFIER1, XK_t, XK_t, togglebartags, {0} }, - { MODIFIER1, XK_t, XK_w, togglebartitle, {0} }, - { MODIFIER1, XK_t, XK_u, togglebarunseltitle, {0} }, - { MODIFIER1, XK_t, XK_s, togglebarstatus, {0} }, - { MODIFIER1, XK_t, XK_y, togglebaremptytags, {0} }, - { MODIFIER1, XK_t, XK_l, togglebarlt, {0} }, - { MODIFIER1, XK_t, XK_i, togglebaricon, {0} }, - { MODIFIER1, XK_t, XK_o, toggleopacity, {0} }, - { MODIFIER1, XK_t, XK_b, togglebarpos, {0} }, - { MODIFIER1, XK_t, XK_r, resetbar, {0} }, + { MODIFIER1, XK_t, XK_t, togglebartags, {0} }, + { MODIFIER1, XK_t, XK_w, togglebartitle, {0} }, + { MODIFIER1, XK_t, XK_u, togglebarunseltitle, {0} }, + { MODIFIER1, XK_t, XK_s, togglebarstatus, {0} }, + { MODIFIER1, XK_t, XK_y, togglebaremptytags, {0} }, + { MODIFIER1, XK_t, XK_l, togglebarlt, {0} }, + { MODIFIER1, XK_t, XK_i, togglebaricon, {0} }, + { MODIFIER1, XK_t, XK_o, toggleopacity, {0} }, + { MODIFIER1, XK_t, XK_b, togglebarpos, {0} }, + { MODIFIER1, XK_t, XK_r, resetbar, {0} }, /* Chained powerline toggle keybinds */ - { MODIFIER1, XK_apostrophe, XK_w, toggletitlepowerline,{0} }, - { MODIFIER1, XK_apostrophe, XK_t, toggletagpowerline, {0} }, - { MODIFIER1, XK_apostrophe, XK_a, toggletitleplshape, {0} }, - { MODIFIER1, XK_apostrophe, XK_d, toggletagplshape, {0} }, - { MODIFIER1, XK_apostrophe, XK_s, toggleplshape, {0} }, - { MODIFIER1, XK_apostrophe, XK_r, resetpowerline, {0} }, + { MODIFIER1, XK_apostrophe, XK_w, toggletitlepowerline,{0} }, + { MODIFIER1, XK_apostrophe, XK_t, toggletagpowerline, {0} }, + { MODIFIER1, XK_apostrophe, XK_a, toggletitleplshape, {0} }, + { MODIFIER1, XK_apostrophe, XK_d, toggletagplshape, {0} }, + { MODIFIER1, XK_apostrophe, XK_s, toggleplshape, {0} }, + { MODIFIER1, XK_apostrophe, XK_r, resetpowerline, {0} }, /* Chained music keybinds */ - { MODIFIER1, XK_q, XK_n, spawn, cmd( "cmus-remote --next" ) }, - { MODIFIER1, XK_q, XK_p, spawn, cmd( "cmus-remote --prev" ) }, - { MODIFIER1, XK_q, XK_l, spawn, cmd( "cmus-remote --seek +3" ) }, - { MODIFIER1, XK_q, XK_h, spawn, cmd( "cmus-remote --seek -3" ) }, - { MODIFIER1, XK_q, XK_u, spawn, cmd( "cmus-remote --seek +10" ) }, - { MODIFIER1, XK_q, XK_d, spawn, cmd( "cmus-remote --seek -10" ) }, - { MODIFIER1, XK_q, XK_0, spawn, cmd( "cmus-remote --seek 0" ) }, + { MODIFIER1, XK_q, XK_n, spawn, cmd( "cmus-remote --next" ) }, + { MODIFIER1, XK_q, XK_p, spawn, cmd( "cmus-remote --prev" ) }, + { MODIFIER1, XK_q, XK_l, spawn, cmd( "cmus-remote --seek +3" ) }, + { MODIFIER1, XK_q, XK_h, spawn, cmd( "cmus-remote --seek -3" ) }, + { MODIFIER1, XK_q, XK_u, spawn, cmd( "cmus-remote --seek +10" ) }, + { MODIFIER1, XK_q, XK_d, spawn, cmd( "cmus-remote --seek -10" ) }, + { MODIFIER1, XK_q, XK_0, spawn, cmd( "cmus-remote --seek 0" ) }, /* Misc */ - { MODIFIER1, XK_q, XK_o, killunsel, {0} }, - { MODIFIER1, XK_l, XK_p, togglelayoutpos, {0} }, - { MODIFIER1|SHIFT, XK_e, XK_p, spawn, cmd( "speedwm-swal --previous" ) }, - { MODIFIER1|SHIFT, XK_e, XK_r, spawn, cmd( "speedwm-swal --randomize" ) }, - { MODIFIER1|SHIFT, XK_e, XK_a, spawn, cmd( "speedwm-virtualkeyboard" ) }, - { MODIFIER1|SHIFT, XK_e, XK_e, spawn, cmd( "speedwm-virtualkeyboard -e" ) }, + { MODIFIER1, XK_q, XK_o, killunsel, {0} }, + { MODIFIER1, XK_l, XK_p, togglelayoutpos, {0} }, + { MODIFIER1|SHIFT, XK_e, XK_p, spawn, cmd( "speedwm-swal --previous" ) }, + { MODIFIER1|SHIFT, XK_e, XK_r, spawn, cmd( "speedwm-swal --randomize" ) }, + { MODIFIER1|SHIFT, XK_e, XK_a, spawn, cmd( "speedwm-virtualkeyboard" ) }, + { MODIFIER1|SHIFT, XK_e, XK_e, spawn, cmd( "speedwm-virtualkeyboard -e" ) }, /* Gap keybinds */ - { MODIFIER1|CONTROL, -1, XK_z, incrgaps, {.i = +5 } }, - { MODIFIER1|CONTROL, -1, XK_x, incrgaps, {.i = -5 } }, + { MODIFIER1|CONTROL, -1, XK_z, incrgaps, {.i = +5 } }, + { MODIFIER1|CONTROL, -1, XK_x, incrgaps, {.i = -5 } }, /* Chained gap keybinds */ - { MODIFIER1, XK_g, XK_t, togglegaps, {0} }, - { MODIFIER1, XK_g, XK_0, defaultgaps, {0} }, - { MODIFIER1, XK_g, XK_i, incrigaps, {.i = +1} }, - { MODIFIER1|SHIFT, XK_g, XK_i, incrigaps, {.i = -1} }, - { MODIFIER1, XK_g, XK_o, incrogaps, {.i = +1} }, - { MODIFIER1|SHIFT, XK_g, XK_o, incrogaps, {.i = -1} }, - { MODIFIER1|SHIFT, XK_g, XK_j, incrgaps, {.i = +1 } }, - { MODIFIER1|SHIFT, XK_g, XK_k, incrgaps, {.i = -1 } }, + { MODIFIER1, XK_g, XK_t, togglegaps, {0} }, + { MODIFIER1, XK_g, XK_0, defaultgaps, {0} }, + { MODIFIER1, XK_g, XK_i, incrigaps, {.i = +1} }, + { MODIFIER1|SHIFT, XK_g, XK_i, incrigaps, {.i = -1} }, + { MODIFIER1, XK_g, XK_o, incrogaps, {.i = +1} }, + { MODIFIER1|SHIFT, XK_g, XK_o, incrogaps, {.i = -1} }, + { MODIFIER1|SHIFT, XK_g, XK_j, incrgaps, {.i = +1 } }, + { MODIFIER1|SHIFT, XK_g, XK_k, incrgaps, {.i = -1 } }, /* Media buttons */ #if USEMEDIA @@ -259,4 +261,9 @@ static Key keys[] = { { 0, -1, XF86XK_WLAN, spawn, cmd( "speedwm-netctrl disconnect" ) }, { 0, -1, XF86XK_Music, spawn, cmd( TERMINAL "tmux new-session -A -D -s cmus $(which --skip-alias cmus)" ) }, #endif + + /* Marking */ + { MODIFIER1, -1, XK_bracketleft, swapfocus, {0} }, + { MODIFIER1, -1, XK_bracketright, swapclient, {0} }, + { MODIFIER1, -1, XK_backslash, togglemark, {0} }, }; diff --git a/signal.h b/signal.h index 35d6c0a..76d0b8c 100644 --- a/signal.h +++ b/signal.h @@ -124,4 +124,7 @@ static Signal signals[] = { { 113, setlayout, {.v = &layouts[14]} }, /* Empty layout */ { 114, setbpgaps, {.i = +1 } }, { 115, setbpgaps, {.i = -1 } }, + { 116, togglemark, {0} }, + { 117, swapfocus, {0} }, + { 118, swapclient, {0} }, }; diff --git a/speedwm.c b/speedwm.c index c5fa721..41dc533 100644 --- a/speedwm.c +++ b/speedwm.c @@ -601,6 +601,9 @@ static void sortscreens(XineramaScreenInfo *screens, int n); static void sighup(int unused); static void sigterm(int unused); static void spawn(const Arg *arg); +static void swapclient(const Arg *arg); +static void swapfocus(const Arg *arg); +static void togglemark(const Arg *arg); static void spawnbar(); static void unmanagealtbar(Window w); static void unmanagetray(Window w); @@ -916,7 +919,7 @@ static char tilesymb[] = { }; static Window root, wmcheckwin; - +static Client *mark; static KeySym keychain = -1; /* scratchpad */ @@ -5015,6 +5018,87 @@ reset_layout(const Arg *arg) } } +void +setmark(Client *c) +{ + if (c == mark) + return; + if (mark) { + mark = 0; + } + if (c) { + mark = c; + } +} + +void +swapclient(const Arg *arg) +{ + Client *s, *m, t; + + if (!mark || !selmon->sel || mark == selmon->sel + || !selmon->lt[selmon->sellt]->arrange) + return; + s = selmon->sel; + m = mark; + t = *s; + strcpy(s->name, m->name); + s->win = m->win; + s->x = m->x; + s->y = m->y; + s->w = m->w; + s->h = m->h; + + m->win = t.win; + strcpy(m->name, t.name); + m->x = t.x; + m->y = t.y; + m->w = t.w; + m->h = t.h; + + selmon->sel = m; + mark = s; + focus(s); + setmark(m); + + arrange(s->mon); + if (s->mon != m->mon) { + arrange(m->mon); + } +} + +void +swapfocus(const Arg *arg) +{ + Client *t; + + if (!selmon->sel || !mark || selmon->sel == mark) + return; + t = selmon->sel; + if (mark->mon != selmon) { + unfocus(selmon->sel, 0); + selmon = mark->mon; + } + if (ISVISIBLE(mark)) { + focus(mark); + restack(selmon); + } else { + selmon->seltags ^= 1; + selmon->tagset[selmon->seltags] = mark->tags; + focus(mark); + arrange(selmon); + } + setmark(t); +} + +void +togglemark(const Arg *arg) +{ + if (!selmon->sel) + return; + setmark(selmon->sel == mark ? 0 : selmon->sel); +} + void reset_mfact(const Arg *arg) { Arg new_mfact = {.f = mfact + 1}; @@ -6415,6 +6499,9 @@ unmanage(Client *c, int destroyed) Monitor *m = c->mon; XWindowChanges wc; + if (c == mark) + setmark(0); + if (c->swallowing) { unswallow(c); return;