From 5166081c69e93a9bc125b19e0f553045b1cc7ab4 Mon Sep 17 00:00:00 2001 From: Raheman Vaiya Date: Wed, 29 Mar 2023 23:41:58 -0400 Subject: [PATCH] swap: Add support for swapping toggled layers (#410) Sometimes it is desirable to transition directly from one toggled layer to another. This commit extends swap() to work not just with keys bound to layer(), but also toggle() and oneshot(). For swaps which occur one layer deep (the anticipated use case), this is rougly equivalent of a clear() followed by toggle(). --- data/keyd-application-mapper.1.gz | Bin 1527 -> 1528 bytes data/keyd.1.gz | Bin 9104 -> 9255 bytes docs/keyd.scdoc | 19 +++++++++--- src/keyboard.c | 50 ++++++++++++++++++++---------- t/swap-oneshot.t | 10 ++++++ t/swap-toggle.t | 15 +++++++++ t/test.conf | 7 +++++ 7 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 t/swap-oneshot.t create mode 100644 t/swap-toggle.t diff --git a/data/keyd-application-mapper.1.gz b/data/keyd-application-mapper.1.gz index 8c11f228d8ffa811603294613e284aeaa8ce3e4c..c08f74c3f1e48f7ed7d3131debea777783467c5c 100644 GIT binary patch delta 1253 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 JR|;Kd000ImIAH() literal 9104 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
    |P z;0a>i5LkQ|YOcJ4b;Y(H8F8Q|U7^1j5YaPFQc_4lzukV<5_u(76yCUu## z>Ao8{D5}DHb6Ysj=6D?7dk=y>hbTtl4z$>$+rD5lQnVUH4jYXf(IB5KX-m<0*RYY; zxTe*>RTBE+L}&d4Mrxf%UEnFCxJH_H14{Osrw5~^6pDxp?g43#b42y3=$xv81|0K! zWSDK%sEJ-XZ~uAJ`N3Rt>`uQs$C1djKz?xLn9_-qAmrH_7A0{wvCNe#Xa`2pNFARX z_5*Wc0MPUR=T`Fs8GYq#9Kxc&CPD=gHA9pUtGr1)4{7tAgw;KifF{Cq&d@Q&U3@e{k%>;H)ji!qD7L)kdh&V#uOBBxoYp%htK zqJ_~kq-0=7wkksCLZV&hn4`lyB>yOKkQO)T%ExCN22Q69vw^@GediPkrVS2TJO4|} zk@_FJmoJC<<=}z-j*yEBgOj##ga?EE(TD>+_>AJ6o$HGt_M~TQWQ8HZh{Q(ZyCObU zEa$0uB@DYHm`MR?^QhhkXJD(hB&JYhj`-FfmPp`n8gy`Iv=sI8y5%LJ6;R?1ki?~^?2D=#+j3SoKaZv(_Yzqs zxyuNZtg7;EZ7)*t1C#rY*nde5>#9sZi>zvtB_oZG)hJuVh-lg8fD0h6J)a7pdq>$w zQ8eMn+tOuKZj%dkCt+0KZZ>}(v^xfyc)}cAf~YJO7NC`-VN^;NCyU*a7N99eJR=b^ z>Vxd~?+qyc@Kv=5_gN# z6RV5;=^GaMcz@wX7%57#3@qU$*Z|A<%EN&zaGV;jX=_vi zGa?KMnQ7=G3R1`^Gjhtr&LAcQ{0fIBy+y3Aw{O1trjxitRbqd7z<`a#{+{LUUPZ_YQg~sa8OIs!Xu?OJ& z#5%a$q%G5lC`vQ-=F_V;y`iGCE&%B?&s}imV}1=0L1{zgP$w~!xZhr=V1=bn7EeDL zihPPVHfCb73RG^8Smcz+ubo6+Q95&^P8hfF4c=jqE-i|x zf*`@%gDerak?ey&YvnBUw8u^zgjqx*q$T|cP=ri?lLRoC$v0`;@JUTEjgKk8_h_7a zkd~a`Ya^RO9UFOVoNmmU*PRN&SmaUfEEGN`Nl9L5%sq<|rfyQqAs|&C(yBpEa8vZ^ zpWUSz(4E`CKYA2Zx!HYK9n?Arw zoRQ{T(@Qr-MQL6jLWB+7ix@vc2;q|$ba++|;Nt1g9$|kertit|3?UQpt%*GdgNQGa z#v6K1;(*#QNr*)J?=QO+;u3`H8!b&3*}7%Jcv zBwT(2Q~qM$w#!;%>+C2v^CewG-TCaD*N5b`hlfbt$(F}A$<}=nY=k5lSP%$Lakq~) z`j&Nh3`E>}ksmUww^($zgdPhZ*Q}#sP-tfu7K!;U3ZNJ3)&> z5)>s-eA0QA*~0q7xqDT+F7>Q_oI%&hbf>6=u|v7m4~3EhzI`^ZY7sa?Uk_05Lw(m>m@? zge>_7bS60FP1f2aB|Y_NO&%HUh<1&=!-=kxOS4mZ%;li)#skIi0_zl{amHy~3C zrCj3Zx$1BsZwf^kVa_i(+p-A>Ds*eL z4N_^^&->vDG;!4(sm)5oqT5v5SAdDn#eE}9Iac?9l!|}~fQ5IGKO>H$r1MTmqBW-` zg3fFkr=+nh{O-tnwZA{ol2-x=8>Y=>$Rap=%f25<3luPX1V?|C$6*rU93PM)f{IYp zG(OhtS&G&>Ns@2cS`+nz(G}!oqk=ZD>#P8Y*T9T_I6i%k%vr`W+*=p?2iyU^EO`eDfA3QCXlrj}6X+q8Cq(yfEt`*ZTB+uV> z-j1G^H*C-%y>*Lr!5gIjM!ST{A7=tBYb!o+v@dwiXiUn4*tBUpj1nccDIP>@wanfq$cWH4;xV%rCxa3XZ zqHrl{^iiU?Hh9Tv@jIbGe3v=&xLJ7ErFWL1(86|(8?LIP4J zmWh3UsqWqmu7G2^BVG1#^nnE>I*1;SsRZVTFw|gS|4wgd6nz zf3M!jf#WX<3UPfa#YZKgEE!~ERt-{a2Zhu^hQi&W(niir#9w~|le=m?(+Nj=JUPvm zjc|#srddZgU3>F4Rn2`$|2f#bTe2SPid>~xx2YC;^eI7o_=&*|b+C6`0&Xu`)*MEq z@?-KdeQK_UpP1{R&UK6%e$vzSyZl~yr}>lO@@a>JqA@I5{4fcaUNqH}Ef1*NAHN;; z3;s>W_NBKQQ+@w#)im-~A@rY1ojT>5v%^kmf1Xj1{kd6-)F0xdYl!!sZ@w^zB508H z^+19!As*Sqgg+xHl_yLGJSHoFYxNwX@bnGdH!v3b}jK>K-ab&)k*0ab6Pgsr|zTk7-b4CroS) ziO3#H;zpEng0^DU7nsrG-c&H!JrVyGsPe;@lsM$+HRXz0s|jMLdYxXJou9{=PKf?X z#l#@3p-b^c1x3m!SliefGz>8^uI6Xmg+S)q8q#6BK^4$Y(i(Cny||?_RoG9&wK*rF z=nfz;0wV2?jXBi_bG-89KZ4=LH zqKW-Yy4AC(?0 zbkrTKQHq8?kNKzepkx)~HS8u4P9d8u7KmENT_FHxLT#k>Uj>5n`Fubiar`O>utS($ z`Gz`4^vVkYDmQMiusNmy6|1DP;qL~9_wbY8Jncp2L!Sd@+>(8EW+~ zAwFFW$W-QR)+dc_<+=+q+MCfrSt4lwqzhE~Jiq zBHXcJ*d>v2CX7V5)ifpDsvFS6@WE|Js7)$CG|1Ir3sQ?ua}yr5yqs# z_fPaR1#+EBK6}U|i3g{9K|luIHJ+i|Ee?@LKPI9?4t3mKcX3A#TI9a(<%y=5w*=sw{SEU38 zk8md*!{58?xlw3(a0t!5!Hu(6{;IkZ7scV7U)#qXHlWZezitdIt=t}n{D_q0Yn2YsH$ePlQ8YM zaQ~qB*yb*CWUF`9LRnSOt%%>!O;Ypzm7{3BoWDAwYMy8Ot4m3$ToeD0w+)=C!7JXfg&~)o7zKLB0%zf_)9<1Ww3VoLN9SRq`OOOA1HX zImjoQ6%&@^Lx(FB;1S*+809jamw|nf!Bs>7Ae+U^zAdx^>=gNnrt?Al56jDo=u?XqC zm_MdBA?|cQEa=KA-TPj$3R)S#3x=$&h=8yK$7bwNy_}JtvxTWfmQfDA_SLzRIp_6J1tBb+@_2`IdMcN@4K| z%xwoFlcZ@EQE_X3Ks+V2?XJj-Gn@7HU)@K!B}!@u=_*7uCCJk*vgy;8NfB=kSJG{| zQiQAhL?1%uen^!4Gb)lXHPGb&IK>#K=J~$?&`tMTzM5-6r3E@uZ&zvXWNuF3xkDxE%;6j9Ukoc zT6%7jYPIza8e@x};g$GPG)rty?5b-xWMRhSGws9>T}{Wa|-p{3h9Y3?KiTY<&eE|C(%l4If`5Ti?LPZ-G!cq#LGkiX$S%}2v*Jc zMyaY#R_cP>AxEYbG~KwYyIz3$u|X*J18aC|1~}r%Uo^p_vlOj#7cnKD!g#o{E8N!b%1?=U*PtHq1)lUn5PRBT>-T(xxo{ujtBTsvbNSF!n^JjIh z3dB1+$cS^(=@DMEk!<0}zlWC>_?r7s%e(OScrfFA6y$o<9alf$!CR~AZ`LZikoL56 z3dfPlgCzZAR;-qD%y>1xfWI5m9wHkBmVA3PL2)wXhysowARH}h*&>@INqj%tracwk zNlt-xssgh)v!VNx1kQKlc3B*vR8Psxfr+!5ss#6J`Qhya4DwZxOC(U^XtSjmsDG#wBedYh8PM2S{I20f1)Y4YK9+ z=sUg^MU4U9JH~WLyrX={egzBICG)+Hdslk}RaN!sgtVSE6x`u$jfvii5Jh>kVSL#m z-%x%hZ;LajgR@kh?HH1nB0~dq2KRRS`nxV;oPL83zU>mTEY8W^R(9d}yJ2Uz&}xS7 z&|1FtX8OULzJ2qN`*ZYLb^-K(#0Vom^eU?y09 OlKdZ_81}%+W&i-g(P5MT diff --git a/docs/keyd.scdoc b/docs/keyd.scdoc index 37e2bdb..9c60112 100644 --- a/docs/keyd.scdoc +++ b/docs/keyd.scdoc @@ -66,7 +66,7 @@ the form _[section_name]_ followed by a set of _bindings_. Lines beginning with a hash are ignored. Config files are stored in _/etc/keyd/_ and loaded upon initialization. -The reload command can be used to update the working set of config +The reload command can be used to update the working set of config files (e.g sudo keyd reload). A valid config file has the extension _.conf_ and *must* begin with an _[ids]_ @@ -253,7 +253,7 @@ the full config actually looks something like this: j = down ``` -If multiple bindings for the same key are present, the most recent one takes precedence. +If multiple bindings for the same key are present, the most recent one takes precedence. A layer heading may also appear multiple times, in which case the layer will contain the sum of all bindings. Note that the layer type may not be reassigned. @@ -620,9 +620,11 @@ A key may optionally be bound to an _action_ which accepts zero or more argument If tapped, activate the supplied layer for the duration of the next keypress. *swap()* - Swap the currently active layer with the supplied one. The - supplied layer is active for the duration of the depression of the - current layer's activation key. + Swap the currently active layer with the supplied one. If the current + layer is toggled, it is deactivated and the supplied layer is toggled + instead. Otherwise, the active layer is deactivated and the supplied + layer remains active for the duration of the depression of the + activating key. ``` [control] @@ -635,6 +637,13 @@ A key may optionally be bound to an _action_ which accepts zero or more argument b = S-insert ``` + NOTE: + + You probably don't need to use this unless you are trying to do something quite + involved. Think hard about whether or not what you are trying to achieve + can be done by other means, as it is easy to end up in states which + are impossible to exit. + *setlayout()* Set the current layout. diff --git a/src/keyboard.c b/src/keyboard.c index 9168c7b..3a698ce 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -709,28 +709,44 @@ static long process_descriptor(struct keyboard *kbd, uint8_t code, size_t i; struct cache_entry *ce = NULL; - for (i = 0; i < CACHE_SIZE; i++) { - uint8_t code = kbd->cache[i].code; - int layer = kbd->cache[i].layer; - int type = kbd->config.layers[layer].type; - - if (code && layer == dl && type == LT_NORMAL && layer != 0) { - ce = &kbd->cache[i]; - break; + if (kbd->layer_state[dl].toggled) { + deactivate_layer(kbd, dl); + kbd->layer_state[dl].toggled = 0; + + activate_layer(kbd, 0, idx); + kbd->layer_state[idx].toggled = 1; + update_mods(kbd, -1, 0); + } else if (kbd->layer_state[dl].oneshot) { + deactivate_layer(kbd, dl); + kbd->layer_state[dl].oneshot = 0; + + activate_layer(kbd, 0, idx); + kbd->layer_state[idx].oneshot = 1; + update_mods(kbd, -1, 0); + } else { + for (i = 0; i < CACHE_SIZE; i++) { + uint8_t code = kbd->cache[i].code; + int layer = kbd->cache[i].layer; + int type = kbd->config.layers[layer].type; + + if (code && layer == dl && type == LT_NORMAL && layer != 0) { + ce = &kbd->cache[i]; + break; + } } - } - if (ce) { - ce->d.op = OP_LAYER; - ce->d.args[0].idx = idx; + if (ce) { + ce->d.op = OP_LAYER; + ce->d.args[0].idx = idx; - deactivate_layer(kbd, dl); - activate_layer(kbd, ce->code, idx); + deactivate_layer(kbd, dl); + activate_layer(kbd, ce->code, idx); - if (macro) - execute_macro(kbd, dl, macro); + if (macro) + execute_macro(kbd, dl, macro); - update_mods(kbd, -1, 0); + update_mods(kbd, -1, 0); + } } } else { if (macro && diff --git a/t/swap-oneshot.t b/t/swap-oneshot.t new file mode 100644 index 0000000..eab3c0c --- /dev/null +++ b/t/swap-oneshot.t @@ -0,0 +1,10 @@ +1 down +2 down +300ms +1 up +2 up +a down +a up + +b down +b up diff --git a/t/swap-toggle.t b/t/swap-toggle.t new file mode 100644 index 0000000..8b09918 --- /dev/null +++ b/t/swap-toggle.t @@ -0,0 +1,15 @@ +4 down +4 up +s down +s up +s down +s up +x down +x up +s down +s up + +a down +a up +shift down +shift up diff --git a/t/test.conf b/t/test.conf index af38603..a8ed1e8 100644 --- a/t/test.conf +++ b/t/test.conf @@ -31,6 +31,7 @@ p = layerm(shift, macro(on)) 7 = overload(meta, oneshot(control)) 8 = timeout(overload(control, a), 1, b) 9 = M-C-S-x +1+2 = oneshot(test) l = layer(test) m = macro(C-h one) c = oneshot(control) @@ -69,11 +70,17 @@ b = macro(leftcontrol+n) c = macro(leftcontrol n) x = overload(meta, swap(shift)) +[test2] + +s = a +x = toggle(test2) + [test] o = oneshot(o) a = b b = toggle(test) +s = swap(test2) c = clear() [o:C]