From 84aae7bcddeb45da3b52e8c8fe61a3544bff9152 Mon Sep 17 00:00:00 2001 From: Cagebreak Signing Key 7 Date: Wed, 30 Jun 2021 13:00:40 +0200 Subject: [PATCH 01/19] Release 1.7.3 - Adjust to wlroots 0.14.0 - Update build dependencies --- README.md | 22 ++++++++++++++++++++++ man/cagebreak-config.5.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 14 +++++++------- message.c | 10 ++++++++-- signatures/1.7.1-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.7.1-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.7.1.sig | Bin 0 -> 566 bytes signatures/1.7.2-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.7.2-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.7.2.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes view.c | 8 +++++++- 15 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 signatures/1.7.1-cagebreak-config.5.sig create mode 100644 signatures/1.7.1-cagebreak.1.sig create mode 100644 signatures/1.7.1.sig create mode 100644 signatures/1.7.2-cagebreak-config.5.sig create mode 100644 signatures/1.7.2-cagebreak.1.sig create mode 100644 signatures/1.7.2.sig diff --git a/README.md b/README.md index 7b722f4..169431b 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,21 @@ For every release after 1.0.5, hashes will be provided. For every release after 1.7.0, hashes will be provided for man pages too. +1.7.3 cagebreak + + * sha 256: 8adb4911d9603fec5b8eb4f67a09be95b8f0b37e50d4ab579191da78df18f70b + * sha 512: eddaecd7b577b9fe77b1ed4d341074f7f860967568392d0479543ea8860b4289df3eb5645885e18e35260b14843663ae50f98103f8016e857237a397632322a6 + +1.7.3 cagebreak.1 + + * sha 256: bcc623e42c86ab65bc2f8cb7e4377ca0d816ddc281527b7caeded62753e943b8 + * sha 512: b4290e1040bd6a299d478ad6b695de75cf030d0d274340b43d3ed4382cf6877f824cd4ed9d7020bfb55afe276c62de7fc07c3fbee6f6485c6440a024115afe12 + +1.7.3 cagebreak-config.5 + + * sha 256: b9789b6abd473e9afb33d4e2c7822f7d8f3c10e9eb3fb70c47b713f6331c626a + * sha 512: c49e01cfc4a4ed272f054bea8f2845f0e3f1609cf85d1a0ce14c1b67dc207df153b11bc20ceef09c855d467f0e013e54623ce9f70c217c4278607fc54d0e3206 + 1.7.2 cagebreak * sha 256: 40f4642e8e8caee338055079b046f6e0b790c87226ee307b27a64fcb2a6c6472 @@ -331,6 +346,13 @@ For every release after 1.0.5, a GPG signature will be provided in `signatures`. The current signature is called `cagebreak.sig`, whereas all older signatures will be named after their release version. +Due to errors in the release process, the releases 1.7.1 and 1.7.2 did not include the release +signatures in the appropriate folder of the git repository. However, signatures were provided +as release-artefacts at the time of release. The signatures were introduced into the +repository with 1.7.3. The integrity of cagebreak is still the same because the signatures were +provided as release-artefacts (which were themselves signed) and the hashes in README.md +are part of a signed release tag. + #### Signing Keys All releases are signed by at least one of the following collection of diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 557cbac..c3447fd 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(1) "Version 1.7.2" "Cagebreak Manual" +cagebreak-config(1) "Version 1.7.3" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index d0e67db..2b4514f 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.7.2" "Cagebreak Manual" +cagebreak(1) "Version 1.7.3" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index 2e5c248..9e73902 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.7.2', + version: '1.7.3', license: 'MIT', default_options: [ 'c_std=c11', @@ -53,7 +53,7 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: ['>=0.13.0', '< 0.14.0']) +wlroots = dependency('wlroots', version: ['>=0.14.0', '< 0.15.0']) wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') @@ -198,13 +198,13 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.19.0', 'wayland_cursor': '1.19.0', - 'wlroots': '0.13.0', + 'wlroots': '0.14.0', 'xkbcommon': '1.3.0', 'fontconfig': '2.13.93', 'pixman': '0.40.0', - 'pango': '1.48.4', + 'pango': '1.48.5', 'cairo': '1.17.4', - 'pangocairo': '1.48.4', + 'pangocairo': '1.48.5', 'math': '-1' } @@ -257,7 +257,7 @@ if get_option('man-pages') output : 'cagebreak.1', input : 'man/cagebreak.1.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1621324686 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1624989203 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir1 ) @@ -266,7 +266,7 @@ if get_option('man-pages') output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1621324686 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1624989203 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir5 ) diff --git a/message.c b/message.c index acf1ffc..2ff2075 100644 --- a/message.c +++ b/message.c @@ -108,11 +108,17 @@ message_set_output(struct cg_output *output, const char *string, return; } message->message = create_message_texture(string, output); + if(!message->message) { + wlr_log(WLR_ERROR, "Could not create message texture"); + free(box); + free(message); + return; + } message->position = box; wl_list_insert(&output->messages, &message->link); - int width, height; - wlr_texture_get_size(message->message, &width, &height); + int width = message->message->width; + int height = message->message->height; message->position->width = width; message->position->height = height; switch(align) { diff --git a/signatures/1.7.1-cagebreak-config.5.sig b/signatures/1.7.1-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..048473eac0b262e824d8812c1ca7fa06c0184947 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0$`Kfg8&K%5b{@R z(`FTGx&0px|9>xu{GD6iVTW~8P}kb-3=HX+F>p!hKhFT!))}4xau~K zT4#YLj}p1#D_6m2=IPtYIg)=hpY7D7xVvX3`&b><{U46v=4a4!biL@jlMtsfUQiTc z_?bfpxdQHcPHJgR=C_wsx)V9{!nh>)d1v_ZgNgcQBFvz=mwB-c`fon$Rt6Z!X*8uQ zk(Mz*S575beXXj$DB;i*CDcDFCB|;Dsw;-&{8ZZbMDH@EW6J0T_D3u9=6KPtM_svzoY#;Dl$kf=`U_7w^Uhj`f^Z;x z4#=u9k}uPLN|hb`ZH=p`pl(($A=WiHo9FO5YBfx>h>;SN@W&v{wYB{vikZiLbFpUC zwYM)&N;~Dt6pVE{jn<99T48fc|C?%kU5W;E-()!@6N6&O(KNJ*-c{Dxdml7&6PuC~ z%%LAx8(=i97k+_qwzc7>d=Mq$dK|<-XD8=;xHvCjHZs&mCR)gH!6zG6ta0Z0fa6$| zX;9IS2{!Vo4AdRvexpx(3x*;3U2`ykvKA)f`LdZ{@mOvAyihx6ZqQ2=((Wn2dqUf* Ekg-4*JOBUy literal 0 HcmV?d00001 diff --git a/signatures/1.7.1-cagebreak.1.sig b/signatures/1.7.1-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..35c9e1fff161db252d357169221ca1efb27a12fb GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0$`KffB*^!5b{@R z(`FTGxzhI!|6I&i))J**1ZIN%ZT$C`Pe^XB>9;7-8;jFX;e_Lgogk%{BEu%Q4Eddxm-XfW+ zUBYl-ZM)m5J41j*57;YPIu_+r<_1IeEJc{Va5cX6RV`qB(DK$B2%f-S2a zOY&9eNicETY&M38E?(T+I%Z@|XGL4E-$C)}KLq5D@rNr_&qE#-9G)9iFqiSjzcCU2`JZpQc;c|m6;-uJXi@dKV)Ya_ zf5*;o$ru<~#T9==&E{}M8OtM({rcF80@WaCq$Gay6x|o E1;scJBme*a literal 0 HcmV?d00001 diff --git a/signatures/1.7.1.sig b/signatures/1.7.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..e54765f6c6c28bb2ed7051dae7aa3969664c8233 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0$`KfY5)oe5b{@R z(`FTGxeCD#|4k*{A>dJ^GyMV&@)`PVzMF((5;{)zxmH|Mk-jQkg!M5f#|GIF55dwnY9$2(~}XIG>sxz z#5Zy8t>xiRR!JYD_}J>Nv3P_R}I^?#FiXb&ApO$1@g3HjuMI zv&{N3ckF)SoN!86Z-3Ti#cyzTcs5S@0qMci_m_OlK^qR-Ykxf`uN{NUVHv;l^V1>i zNB+V=6AhDE%d5~qCkmv%s4^8sd%hU+a}El^dIP(!*6YnJN#*UpiY@JLVDsDB7SgYD znBo&Tb~nW1iQ_Q@aU4iRa$2^!vVqc#Nq0BtY1(OUGFVz8&9AZ|H=dJ<|N1QbyV%gl z7sLGt)QkG&JJ?C Ey)k$iFaQ7m literal 0 HcmV?d00001 diff --git a/signatures/1.7.2-cagebreak-config.5.sig b/signatures/1.7.2-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..a6facb1580b1819d97dd3764826ac1821d2886ea GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0$`(gq5ujB5b{@R z(`FTGxlm&e0Ezk^P>5zd!hf!r@yeS>jieWac0Cpb-e<~&!YgQ{AI?`Cxg*T7SamE( zz=7VpF$v=?t$}oh4>7A?y2WYhYIL91sR6gggb4t|cDvVmUo_YB^fIgCky6KtC;l{W zeJZ?)Qc0H%$C&F;23Wd|X^}+KxHFJ_B^kwhZ4|#GDiJ>UzLZx+ZG>Qu zuyxXEsl!t@NLVWhMT~7XP?$N0G-rW{a6e&;ysNtFY6?+HedUnl zQWS?63ER;{6IFN2AmeSmYH`^l4&(f>9mCHWUg38vLRo)CY(b^`+eht4UbKbeuMAeS za)BVfo-rgu-nh=+8bB%DSKWy&sNRHIk|}BnbM~y>H8^jEbQb1UO^nO#@EHmx7CJoo z!XP1{tdOtB{tG{irLN%Wf?47gm~}bOE#@8}Ec{d8cdr=SO3U-4YviD!i`X%dXjF(OTWxqo5S8LN|6>GT#0$`(goB#?55b{@R z(`FTGxvZZM0G`i<*@2H29JpiDa!$T^9&?k!H^);7OCy066oXxO`fv<|0-=!!@L8qi zeLi)AJd#_1)1!bd+Tnwwu?qi**Ah(V_dEv!WFOW0e+RYF0X+qg^I~jZTc{SIg7l~k zHfypOXIMD|{!$96w*tjwySsy-7uuJMSLeIW@6_ zT;b&7NdXgwRb?f%z>N``JQ_vHjlsy~2L|%IF9fw>DlPEc_yCuxD_vfUIN4Z8`t)Fz zI$dt`1F+Y8nh7tv1_zjQ%>SGY$deoJom6Cl9@Y!T6oX#mUn8Wt8{~|YrC-=dzy)k$ zJkro^)_zT`tRpu3MnqO+W{Z`Ea>GMc_8k+7%lSc_hk?VQkJixK@M|E)sD+`pyJ`74 zOvPmb{_}g4ao9qe=`<|uM{p7m$X0uo9Kj-Yxl61F<1K+aOeBoV+`^C z^t=vAHkU_P2#8n3*bk|{gG@TqaQ~2@2A(8MnBGNtT^!ho@~;C2lKp7BobEu~5FXkL E`MM7eg#Z8m literal 0 HcmV?d00001 diff --git a/signatures/1.7.2.sig b/signatures/1.7.2.sig new file mode 100644 index 0000000000000000000000000000000000000000..5fd3ee9f60a885a1a5422ca86c7945f77100e011 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0$`(gm;ee15b{@R z(`FTGxpxW={yodLLp2tJkG}*QcXVHQU?pSP#N@hP(M_C(waaF}hk4>#h&O>`Du)l) zOPkaqvom1YM4_yW;uvV+t>I9&KOU+CeYW)C(`i?UVF3$yKNkkrel|6yo2z^B%Kve_ z`!99pAjXuJ*!rh8zqikuzjko3W~gjzoiRZ{;To78K$Y4P^A3!h+}{iuz$Uy~BKqrK zya!2(gCaG8*(OIw8({X-YAA_Ieay-PF^_6GPJw~az@>d40bG{?#H(rltYrSsZ9{2bBD&LVtycZRPAYP7TmN8KOMvoS&;miVwfN*Tl z3hQrl z&kaPdq7u={qyatc>B&BhFGfd1AErIrkc!6Sgpks@A5wd2`~MYS{Rlr$J+$T1yK0KP~j$ zUGDT35`DJ7s@Rq%2x6I5Gd&taKauLKVCWC=&W`odo>gC4FS%@;2l-1`hkf~1Wq>ut E4Bc!HX8-^I literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index a6facb1580b1819d97dd3764826ac1821d2886ea..7461360a82d12acd110d6d03098aac099701a629 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY)gY<^T!_5b{@R(`FTGxkif*|8cRnxlLWoTBuYIvXLKuJ`Xb2 z)%D9#d}?NDFgUNM5`PaO`LIV_Bt}EvB+6A@qBCQ(WJ`tuw2nD0apV0URS@Qs*~7Tb z<(CzOOtj(g6r~&lX-&;b^~y87)%kDx*xSrkcn&^Y=>Y)Cz<>XamlCKamD3x^To2K` zK;+A>BKKNznWSdR$NyOth{<(qX$a~DLfVHW3sTE*QHEiP>%ltJ#!{>FoloRFV2~7V z>#n~CDzt43>@Dj*O07Jm+|im_L!_Xodz?n}gJ!=Y^(j^fM3uteGm992En$0kk1?Cx zf*Ey5KKym&<9~M_m;M1MQc}T6K4Rdl)CIuog^Hc}L4Sml>yRAUq6PvZo^HuUczUoK zdiT<(w(vQrmoepf&l*N)XpZ5jsx1ONh_Hk4bS0&5eVP=K$e`zr1rscP{4Fbpoa2iK z3S;2)RwiLQ5A2TAUgJRc$n7&m6~V(_JK3Mlq9j*c z81bb{N8YGAFPW}?T>4Op3Sgx#Fuvp*5S<-34K)6_p$Bb#1h=X8A3gNZ5zd!hf!r@yeS>jieWa zc0Cpb-e<~&!YgQ{AI?`Cxg*T7SamE(z=7VpF$v=?t$}oh4>7A?y2WYhYIL91sR6gg zgb4t|cDvVmUo_YB^fIgCky6KtC;l{WeJZ?)QcqYN^9hH%M433Pp@4h%{$`iE^`~ zSOYIEzkLrk3y`Bf*C592JRJ z^->cF(CT;>htKJkn1j5ly6b8RQA>U0kmXVohZqUl(M1zgcg!H;ZN6%8*(46*{IMOw z&l+CgcPv6#e@1LUrTp7R?MPmhI$bve*2 z<{lv|{8Qj}uNd4)%k!jb_hiL~|X}bvo89oyq9)G+5pmky=?L09D{<(>P zxxYs@s(6DAJkW3)Y&m9_GGd`g$gv=`mXTuOFXJwC{Iky3Ai8sRthY553fn0SgZgfP zuw-VHSvUrgE=3w1VuLqjY}#1E{P$Ean%#mc;fx(;f|W7BBM^Q6TYAPLvmzBg$cZK6 z93Na8G`bAMqJJUU0b8=l*fFth4{Tfb2CebqMO-z2D>4bS>ch4dzH~`UyBW*xXn%CY z=Q8VKSGHQ;89}+$L=FvOGYQREDsX{!opqu8Dd9cSfPkVmVe?dRe^Lo2hj^nXT7;Erz3$a zIEa0F+uNVpX!;)H)ao8rvL8H2YtMgJj}T33w6$q=nsmtriu6$lma#3ioXrdY8_4PJ zGQr>_j&D4~8RjaSxjuCYswzdmM_l&8C+9b8@~M<-{CUjbYo@!aRN-b(8ZQtXO5J`y g3uGysD;KCA6dhOYmOJkr-Z?d~gk0g|<4FM%hgD@Iw!n=Mn>-pt%8kLu<_8Ay zye|Z`Vk#~0-S_~Psw-Vyj5yg?Nc!|(mpWZ;^aHThe3}U_y9NiCbj<&p4#<-m@SRj- zgC5ok#}tEJ1 zDU<@2NL8E}uRYf5i16?+SNj)m=lk7b4DtW;ybek>mq%F$h*!nf52?R{OghwX|B#^u go+M3}-WNrBT^!ho@~;C2lKp7BobEu~5FXkL`FO+#kN^Mx diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 5fd3ee9f60a885a1a5422ca86c7945f77100e011..c0e34973f2a7c6665db0a15fb578d8fa37356ac2 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY)gY;Q$H=5b{@R(`FTGx#c_${0PT^F-8b3g<0mOdZRIjg9K|t zDqfG?knfmy80O3&MD{o&rQ2Tt^In&nzEu4ePNT~VFve;cWJ8Y84b!2Tf{O3}Fm7$1 zjFWkQ%mCaS4EPICsEeo-vki<69JCmnUy@=iQ0o#XAPpw}1b-#ar+}z+jh9fUG2I9+ zxAT}4%4JtS#6TqNQa@IQ{b3>m-ro;gevq=+MgtFz)voM+Oz{UotiHdRA+OSLE6+t; z3OcL!_Kg0Z3n3*lzR5z+Ox!>I3(7XLD>a`jkpW{0HY?pT0V|cs^rPnuCD;PZZ9{B{ z%)A+<7~W*9C4XYNVbqrAp3|f+e&8nFr+}#wyECVN1$zsSYLb4;?H@hA_Siv=<{SQ7 zHNArT{4;o@_~n#H`lahzM1$yo)H2e=y&K?c0@8@MLv76~!w*S5;b79q)Qw7bd%vu# zYQmNplt0o&97Vtsd)UnPSnfN*{LEEKE2XEnxH#h&O>`Du)l)OPkaqvom1YM4_yW;uvV+t>I9&KOU+CeYW)C z(`i?UVF3$yKNkkrel|6yo2z^B%Kve_`!99pAjXuJ*!rh8zkj#So4WPbH`Jlc0X

gC4FS%@;2l-1`hkf~1Wq>ut45xqzasU7T diff --git a/view.c b/view.c index 410a746..19ae2ad 100644 --- a/view.c +++ b/view.c @@ -337,7 +337,13 @@ view_map(struct cg_view *view, struct wlr_surface *surface, view->wlr_surface = surface; struct wlr_subsurface *subsurface; - wl_list_for_each(subsurface, &view->wlr_surface->subsurfaces, parent_link) { + wl_list_for_each(subsurface, &view->wlr_surface->subsurfaces_above, + parent_link) { + subsurface_create(NULL, view, subsurface); + } + + wl_list_for_each(subsurface, &view->wlr_surface->subsurfaces_below, + parent_link) { subsurface_create(NULL, view, subsurface); } From 18f45aba3774e521500be9f9df73538ad2b00466 Mon Sep 17 00:00:00 2001 From: Cagebreak Signing Key 7 Date: Wed, 30 Jun 2021 18:00:10 +0200 Subject: [PATCH 02/19] Release 1.7.4 - Update build dependencies --- README.md | 15 +++++++++++++++ man/cagebreak-config.5.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 12 ++++++------ signatures/1.7.3-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.7.3-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.7.3.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 10 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 signatures/1.7.3-cagebreak-config.5.sig create mode 100644 signatures/1.7.3-cagebreak.1.sig create mode 100644 signatures/1.7.3.sig diff --git a/README.md b/README.md index 169431b..1e86164 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,21 @@ For every release after 1.0.5, hashes will be provided. For every release after 1.7.0, hashes will be provided for man pages too. +1.7.4 cagebreak + + * sha 256: c7442db906239b13f8d09e91cbe01f9e47b2a2c75bbb4b52adefd15dfbfa820f + * sha 512: 9c36ce706f31e1b8afacd8f9cd216c460d66030e0b2736a3dd929902b0d5fc52c5e69dbf6787205b8c495d960e00b6e7f633da86ab6e31613f1b4a9fd47c9f0e + +1.7.4 cagebreak.1 + + * sha 256: 3dacc521e5e9b963cceeefeed6a10104c7c415d86826a72788aba5b33ce320f1 + * sha 512: 0a4c4fbff09dd403fed61056ae3211ad2b4370b4e9ed07806fc22624e5312b4a25e469dc0eef1ca4556cbb8efabb0127e7519df79852e110faa98fb17ca377de + +1.7.4 cagebreak-config.5 + + * sha 256: ed22fed1818172f31d3fb3efbe5e66b49f135cb2367b1c85209fd880ff7532ab + * sha 512: cc634c63962ae50b4de20a3aad8ca0970175b53156690d69e6a69fd8f370ad20d84db783cc7e94c61d4d4d89f1205d43622690e58afba549ed57ddad009e3bac + 1.7.3 cagebreak * sha 256: 8adb4911d9603fec5b8eb4f67a09be95b8f0b37e50d4ab579191da78df18f70b diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index c3447fd..a4a1049 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(1) "Version 1.7.3" "Cagebreak Manual" +cagebreak-config(1) "Version 1.7.4" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 2b4514f..aa66b7e 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.7.3" "Cagebreak Manual" +cagebreak(1) "Version 1.7.4" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index 9e73902..4f76677 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.7.3', + version: '1.7.4', license: 'MIT', default_options: [ 'c_std=c11', @@ -200,11 +200,11 @@ reproducible_build_versions = { 'wayland_cursor': '1.19.0', 'wlroots': '0.14.0', 'xkbcommon': '1.3.0', - 'fontconfig': '2.13.93', + 'fontconfig': '2.13.94', 'pixman': '0.40.0', - 'pango': '1.48.5', + 'pango': '1.48.6', 'cairo': '1.17.4', - 'pangocairo': '1.48.5', + 'pangocairo': '1.48.6', 'math': '-1' } @@ -257,7 +257,7 @@ if get_option('man-pages') output : 'cagebreak.1', input : 'man/cagebreak.1.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1624989203 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1625064321 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir1 ) @@ -266,7 +266,7 @@ if get_option('man-pages') output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1624989203 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1625064321 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir5 ) diff --git a/signatures/1.7.3-cagebreak-config.5.sig b/signatures/1.7.3-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..7461360a82d12acd110d6d03098aac099701a629 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0$|)t<^T!_5b{@R z(`FTGxkif*|8cRnxlLWoTBuYIvXLKuJ`Xb2)%D9#d}?NDFgUNM5`PaO`LIV_Bt}Ev zB+6A@qBCQ(WJ`tuw2nD0apV0URS@Qs*~7Tb<(CzOOtj(g6r~&lX-&;b^~y87)%kDx z*xSrkcn&^Y=>Y)C!2gby5~wGY(;LZL57E6qtHNDD5y9D%!ih8i%-eeO_f^|VYhQy?>_NGh_+U`77 zy3Di;*=y_=3&`y=Mis%sUpv{K&!Qw(T^RADOh?|RJ1?28e_Z-diwa<+FEGC391xuy zI1M!ZxuFMbegwCv_a8m<(d9^k2=ebn0ve$|pq;C>^o-3LJECY#Qje+-+|;+(qXdLz Ekw7dHhyVZp literal 0 HcmV?d00001 diff --git a/signatures/1.7.3-cagebreak.1.sig b/signatures/1.7.3-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..95b9fadb791d1760f961274cc0c80b6599482ff6 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0$|)t;{XZ?5b{@R z(`FTGxino5{U5IssK#MSGkCUk+ER0)cXy}hse(%Q^QOG*-`xiR5VW7n3WW)#haR~) z@fnpjaKmxLl&OJn7wNqxNOv0Z)<$t?v+`q10EDEb#DafwNNjqfE$px_CsL7y$4i>_ zhiL~|X}bvo89oyq9=rgcbz&#&JTV9Uxru?fzehK!c!Lf+&~O}VIcAtLVxdXMu^_dU zkz(R6<1Tglv(DHcx^s7|w>1_D+bIo$`fh=+WM-9FI0lj~MH(JrgEwVt+E~N<_f#;N z-GVFOj2&l!l`+915Pkn!dd4HOA{9T#i6!G4A6y$Wx(vmlA=&|3vdY*ov2PD-Tlfa8 z@#95YHGnHJ3AO6Owimv1Nld#L%kOA^bj9Z~>tk28THhH#xzjNfp?vC zq5Uf(`;&K5=PVxe4xAqRBsAhL$m&;eVUVpaSq@K6Ler9GL^JLZ$1>Ddds9~*d*QSk zs;XF_h)0&(eaJO|MWO=rEiFQ+4cEjWmMd)wQe+i3b8XjF(OTWxqo5S8LN|6>GT#0$|)t;Q$H=5b{@R z(`FTGx#c_${0PT^F-8b3g<0mOdZRIjg9K|tDqfG?knfmy80O3&MD{o&rQ2Tt^In&n zzEu4ePNT~VFve;cWJ8Y84b!2Tf{O3}Fm7$1jFWkQ%mCaS4EPICsEeo-vki<69JCmn zUy@=iQ0o#XAPpw}1SQa?fT(qimr$rN-3TwY^OzONWmiAMKqT!_KURnRVIle!0b>d_E8Q~zE0xLgqvs7J*aFRMLu`r6ycwn#-ej#MV!C0}mgk<+q%VHpCf=uj zsS~?1r+@`}3y^A(e$4G3J-_zYL5}7d{#!M@g8ck5c%=B{lt}ue>sv&F=z-KS(#5?S z;A{fYh`2*-%`3wXNj~9V(#h0~N_cy}tgPhv&i!{3m0TC&rWTwULJHV&2cL~V^iFYY zxj%M;n?}PgRJrv^nii+gG7nt>L;mPBLd-PckLsLhCZKHXH_fkH2&s7dyiU~1(%GpZ z6F$AtKboLEuRp;>1{)ORVgrqW)*9>h4c^rw5&3o(3W@TM1O^U#nOs#Z4k6y_JHP% z@I_d%p_@Am-W4D(hQ?=PCPEOIy#BS~WXMn5ccPfHLP|lTa|0+izsqSs!aZWILo{&5 z!On0$mHsmWmhV9xb;C>4-}u&)x+S4?TkG_>z$JH|k`POdCKWaV#nU{VjP6Ve9J=4e zvlME8%NIw0-+y@ix)HLEJ%JjK0oAf`#Iygp`6^3!fuE}9_aP7?2s!_u!;s!*wX#Iv z+Q9N@=+B}BwbIEn*6MO9#RWZ3r>ubD^#j)4CUeHI80cq@_F?xaDJ%zxfWMr#p=b#Kw01jLm=U(!!n zq?FJ*!+CS;Px7JV#!FiB&`DMhG0R11g2H?-O+l`l*$Iw?-WE-YxgA}ktAHOG^z$n| zmoD^paKeeS6k#AQ>xw083*@h2+2n2d{&vRR^voB8itKIS+|pFxS2@z_PDMsdhpIMJ fuE85hMi$;;&p;`>c7+@7LPVhY^4;0Z)r%k${O=t= delta 541 zcmV+&0^grqW)*9>MvD*sak03$OH%) z^~+LxYG!IMIIpM@e-9%0ut!}aMnm8v%2i&XGh?)5ONIipjyW!I=+Bk?K4Id!NXrW*`Lp%Bv)M+ z@uf^h-l#h-nXZ3a`cR7sV5KiGzT_MbogFw0H2%4v2W@@?x2g9ZJ@nD#NP`IS??wU| fp+BIVs}{EOjLjQ6qG(Q1kE#&d)VJBA1cYXhLgrqW)*9>NT?71nD8zX76D8h6K>W6FeLo1P1ShO zODVty7lTGUW(dbT^#OGvH>m2u*Ellt`_H7;TIpvEVxoUiPu=dLW8f{A-jj@?x`%ar z68j84BVj9c`6z&*axk#8z2<{a;NqnnkgwlB%uXnGdIxn=mwy4wj_&rcUVv^{N%47Q zyj4u(92)s0N(CMFHei`htmn)#1&)tvHJ^SwDgR{X*h?KY{E3;F@3pF@cn)HLdcEyW zf>4j=h?MY^`0*1(l$Xd?Jmqa4JM&hFVDbag=E>so4D`CAkHS?;>8CX6w+v{mo={ZC}!~rR$+EGRBShN%l9S&YQ7rRF@#8CY?;<8)V zYVMf#20>qY`QXX!IqJrXwt$9k5pHeme8)MveWHb426mB6cR5@#_oWa>Ee_U?Qr1V1 z=WiK1h)oT5#UptvrTP*Sl~*J*O}gAK?d)qb@m$Qh?SHxP(N0naD}a5etTVZ-55_B> z5|wPzXRHEAmxLwfM0(T#oV<8$>6&$fnxUZ%Hv$+4rb%)LTy2l&VS#9CoCv< f1?p(M8y3Bl*VmTh4D4@+uDNRfG{Ljh#C^LFTj2*m delta 541 zcmV+&0^grqW)*9>G+htw4clhg$bsI9=SU48I?D1!*Rrvsey49>AfdNcN+87MsaAf@?%T@ zgrug#f`4;JY1_D+bIo$`fh=+ zWM-9FI0lj~MH(JrgEwVt+E~N<_f#;N-GVFOj2&l!l`+915Pkn!dd4HOA{9T#i6!G4 zA6y$Wx(vmlA%EHdTe8a7F|ltCY+LvSt?}bUTs43zG6}Wn!?qW`bV*FR8O!fze{{v? zGV5bkwp!mALAlmM4h>^73C&q5aDjK7b)o$$Bm0wgQ|Bxm^$wgK{3JBuFUaawa$%6I zFIf&xPeRj@XGAmZ62~&sSbI}fAA8}n9IC2Vp@>J8;(snxfpk0v(F;vyy}2)^BY`bA zh<$t8+n?KL`X1!e>K<3JA3RBG&wp5t5KU{ewP|*mbjb&b^ic_xu`RZo%?tq>$m#Dg z!Qds1Z#={q<|>@IK6MJJDn-CYT=v2z=QnKfsg!H{dCcK!rn{?D;bu`9FAyC{-F`p| fWGS61s1_d-9arw<9m2ZOSUr1G6JUZ+@ypxr0Vn+~ diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index c0e34973f2a7c6665db0a15fb578d8fa37356ac2..22e1818ab09d095c08f005169e584fd605ad2096 100644 GIT binary patch delta 541 zcmV+&0^grqW)*9>q!bVSJPrRo74-4*Q*!-sjk>5vgYGj0 z@#<3&P~=G)f6X!8LQ3QJCCThea;I335TFrnvQ37fDG%zf+sv{MkPE1q_1(bO2#~mW zj}6vV!9m46^tk~#$ijr6+dG+n3yzDtpMO<0T^AJ86UH zlABr!X(sFbCBjOCn4vGN13r%PM5k>ZM6tKYvC`qL5>SaHu>R9}Gsy>)anS^cafQ1Q zh_iJc$P^$)j}b72?!?}&)DIO;i-}tX4RSC5bYYAI%#ntf2km57LDlelrU91B8rpyt z94ETUyCy$J7=L-@Rk?z{wpgEJC=6Lt-P`(}3ZlTE6O8rkW+242pjLS7Mrg*WEr4NO z-AnbJ!|g+o5;x~KTJ{O#_1mCyU3lXCf$&j;f@_%62|xs{=JwILb?*}I{hRD-lC@Tu zeaY``RcJ2DBatHUHuNdgSacvV-J$3*Bl|{}`NSaNSAR|*Cm7I=Z{-VOyZ=;Ia*;@Ut(K4D59Rn-FI9fgC%!5*2OdZX%kLsN+5!Pp=Hv fM6q01R2KR?q0kp6@`ZYt)kb(I+{_g)O1Ph9`iKla delta 541 zcmV+&0^grqW)*9>~sDqcMns1ZzYp zUXR|8@0fTP=FA~P_BbS^+g}0mUYDG{RQ(rDqst61#%da5Lypl6)1jJzitqq1Zf&28 zlX-y50Nfo6_zO{}i>MW|4U7&Pv>2UVl431T>k=p+4JQ8tC4bPTfT(qimr$rN-3TwY z^OzONWmiAMKqT!_KURnRVIle!0b>d_E8Q~zE0xLgqvs7J*aFRMLu`r6 zycwn#-ej#MVt=|})RyO-)1)tc;3nRufTogPTUfFMm|I^-7u+r_nMGT>?Y?=ruyj zG~$oyoM|SYZ0$GAuUrVJc>KIh)XUP@sUj0Tz0yCLpgylZ!9@le6y;+hDZKACBlFF4 z>Dhawyf-5kNes#e7LaaRa#HoxJOxY2L> fhjyG|W)`t%0nr#kczRA&^)HBDmK-f6&gk+xojnO! From df167f28396fe68729857cb349c8899deaa0084e Mon Sep 17 00:00:00 2001 From: Cagebreak Signing Key 7 Date: Sun, 26 Sep 2021 21:25:46 +0200 Subject: [PATCH 03/19] Release 1.8.0 - Add libinput configuration - Add virtual keyboard and pointer support --- README.md | 21 +- cagebreak.c | 32 +- examples/config | 8 + fuzz/fuzz-lib.c | 40 +-- input.h | 22 ++ input_manager.c | 271 +++++++++++++++ input_manager.h | 111 ++++++ keybinding.c | 43 +++ keybinding.h | 5 + libinput.c | 442 ++++++++++++++++++++++++ man/cagebreak-config.5.md | 75 +++- man/cagebreak.1.md | 5 +- meson.build | 27 +- message.c | 25 +- pango.c | 2 +- parse.c | 310 +++++++++++++++-- parse.h | 6 + seat.c | 145 ++++---- seat.h | 20 +- server.c | 38 ++ server.h | 5 + signatures/1.7.4-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.7.4-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.7.4.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes util.c | 20 ++ util.h | 7 + 29 files changed, 1530 insertions(+), 150 deletions(-) create mode 100644 input.h create mode 100644 input_manager.c create mode 100644 input_manager.h create mode 100644 libinput.c create mode 100644 signatures/1.7.4-cagebreak-config.5.sig create mode 100644 signatures/1.7.4-cagebreak.1.sig create mode 100644 signatures/1.7.4.sig diff --git a/README.md b/README.md index 1e86164..3008d93 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ for this to work. #### Man Pages Cagebreak has man pages. To use them, make sure that you have `pandoc` -installed. Then, add `-Dman-pages=true to the `meson` command. +installed. Then, add `-Dman-pages=true` to the `meson` command. ### Running Cagebreak @@ -204,6 +204,21 @@ For every release after 1.0.5, hashes will be provided. For every release after 1.7.0, hashes will be provided for man pages too. +1.8.0 cagebreak + + * sha 256: ac84aa4a08c311da79ca29d92eef4254cb625674b255dbb75621ee6b171a1d79 + * sha 512: c047bb1986fd1d444547e4d64aa7ef9138b3d30327ac3ad9b4c6976e8df6638bae07c39293b5bc9c20e959c0a22b0e40eb2b23b4766d9a5531377ff954b16229 + +1.8.0 cagebreak.1 + + * sha 256: 4de43de7bde67d6d806d206dffc34389f0b5c3ba648bfef673b7bc0adeb29202 + * sha 512: 72aac9a2e9a47f2f85949222d5944dc293332a616e3b961c625fe876172f66638038057c30aa18904d6d969451f468b4fe45e918c0b204cf6952d58ea4c69c33 + +1.8.0 cagebreak-config.5 + + * sha 256: 678aadde06b5ff6bfbd9bc9460423210f9599bcaa0e50c2eae076dc6d6852781 + * sha 512: 72056018fc1c559f26bd7e007b3f1db7d478cec7ec9337620e03a1e3d06910e244a52e8f655ea4f5d73669ffe064bbd23506005d9a6c06764b0f820d7a1df43f + 1.7.4 cagebreak * sha 256: c7442db906239b13f8d09e91cbe01f9e47b2a2c75bbb4b52adefd15dfbfa820f @@ -512,6 +527,10 @@ Adds support for non-build dependencies and an option for builds without pandoc. Improve window ordering. +### Release 1.8.0 + +Adds libinput configuration and virtual keyboard and pointer support. + ## Contributors * Aisha Tammy diff --git a/cagebreak.c b/cagebreak.c index 6e16dc2..0738b67 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -44,6 +44,7 @@ #endif #include "idle_inhibit_v1.h" +#include "input_manager.h" #include "ipc_server.h" #include "keybinding.h" #include "message.h" @@ -60,6 +61,8 @@ #define WAIT_ANY -1 #endif +bool show_info = false; + void set_sig_handler(int sig, void (*action)(int)) { struct sigaction act; @@ -133,7 +136,8 @@ usage(FILE *file, const char *const cage) { " -D\t Turn on damage tracking debugging\n" #endif " -h\t Display this help message\n" - " -v\t Show the version number and exit\n", + " -v\t Show the version number and exit\n" + " -s\t Show information about the current setup and exit\n", cage); } @@ -141,9 +145,9 @@ static bool parse_args(struct cg_server *server, int argc, char *argv[]) { int c; #ifdef DEBUG - while((c = getopt(argc, argv, "rDhv")) != -1) { + while((c = getopt(argc, argv, "rDhvs")) != -1) { #else - while((c = getopt(argc, argv, "rhv")) != -1) { + while((c = getopt(argc, argv, "rhvs")) != -1) { #endif switch(c) { case 'r': @@ -163,6 +167,9 @@ parse_args(struct cg_server *server, int argc, char *argv[]) { case 'v': fprintf(stdout, "Cagebreak version " CG_VERSION "\n"); exit(0); + case 's': + show_info = true; + break; default: usage(stderr, argv[0]); return false; @@ -264,6 +271,9 @@ main(int argc, char *argv[]) { wlr_log_init(WLR_ERROR, NULL); #endif + wl_list_init(&server.input_config); + wl_list_init(&server.output_config); + server.modes = malloc(4 * sizeof(char *)); if(!server.modes) { wlr_log(WLR_ERROR, "Error allocating mode array"); @@ -328,8 +338,6 @@ main(int argc, char *argv[]) { goto end; } - wl_list_init(&server.output_config); - renderer = wlr_backend_get_renderer(backend); wlr_renderer_init_wl_display(renderer, server.wl_display); @@ -358,6 +366,8 @@ main(int argc, char *argv[]) { goto end; } + server.input = input_manager_create(&server); + data_control_manager = wlr_data_control_manager_v1_create(server.wl_display); if(!data_control_manager) { @@ -523,6 +533,17 @@ main(int argc, char *argv[]) { wlr_xwayland_set_seat(xwayland, server.seat->seat); #endif + if(show_info) { + char *msg = server_show_info(&server); + if(msg != NULL) { + fprintf(stderr, "%s", msg); + free(msg); + } else { + wlr_log(WLR_ERROR, "Failed to get info on cagebreak setup\n"); + } + exit(0); + } + if(ipc_init(&server) != 0) { wlr_log(WLR_ERROR, "Failed to initialize IPC"); ret = 1; @@ -592,6 +613,7 @@ end: wl_display_destroy(server.wl_display); wlr_output_layout_destroy(server.output_layout); + free(server.input); pango_cairo_font_map_set_default(NULL); cairo_debug_reset_static_data(); FcFini(); diff --git a/examples/config b/examples/config index b6a3ca2..0ecf20b 100644 --- a/examples/config +++ b/examples/config @@ -78,3 +78,11 @@ definekey top XF86MonBrightnessUp exec xbacklight -inc 1 output eDP-1 pos 0 0 res 1366x768 rate 60 output eDP-1 disable output eDP-1 enable + +##################### +#Input configuration +##################### + +input 1234:0:Device_Ident click_method clickfinger +input type:pointer scroll_method two_finger +input * calibration_matrix 1 2 3 4 5 6 diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index cc7b6a4..7f9eb78 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #endif #include "../idle_inhibit_v1.h" +#include "../input_manager.h" #include "../keybinding.h" #include "../output.h" #include "../parse.h" @@ -132,6 +134,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager = NULL; struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager = NULL; struct wlr_screencopy_manager_v1 *screencopy_manager = NULL; + struct wlr_data_control_manager_v1 *data_control_manager = NULL; struct wlr_xdg_output_manager_v1 *output_manager = NULL; struct wlr_gamma_control_manager_v1 *gamma_control_manager = NULL; int ret = 0; @@ -146,6 +149,8 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { wlr_log_init(WLR_ERROR, NULL); #endif + wl_list_init(&server.input_config); + /* Wayland requires XDG_RUNTIME_DIR to be set. */ if(!getenv("XDG_RUNTIME_DIR")) { wlr_log(WLR_ERROR, "XDG_RUNTIME_DIR is not set in the environment"); @@ -235,6 +240,16 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; } + server.input = input_manager_create(&server); + + data_control_manager = + wlr_data_control_manager_v1_create(server.wl_display); + if(!data_control_manager) { + wlr_log(WLR_ERROR, "Unable to create the data control manager"); + ret = 1; + goto end; + } + /* Configure a listener to be notified when new outputs are * available on the backend. We use this only to detect the * first output and ignore subsequent outputs. */ @@ -509,29 +524,14 @@ destroy_input_device(char *line, struct cg_server *server) { --devn; } } else if(strncmp(line, "p", 1) == 0) { - if(wl_list_empty(&server->seat->pointers)) { + if(wl_list_empty(&server->input->devices)) { return; } - devn = devn % wl_list_length(&server->seat->pointers); - struct cg_pointer *pointer, *pointer_tmp; - wl_list_for_each_safe(pointer, pointer_tmp, &server->seat->pointers, - link) { + devn = devn % wl_list_length(&server->input->devices); + struct cg_input_device *dev, *dev_tmp; + wl_list_for_each_safe(dev, dev_tmp, &server->input->devices, link) { if(devn == 0) { - pointer->destroy.notify(&pointer->destroy, NULL); - break; - } - --devn; - } - } else if(strncmp(line, "t", 1) == 0) { - if(wl_list_empty(&server->seat->touch)) { - return; - } - devn = devn % wl_list_length(&server->seat->touch); - struct cg_touch *touch, *touch_tmp; - wl_list_for_each_safe(touch, touch_tmp, &server->seat->touch, - link) { - if(devn == 0) { - touch->destroy.notify(&touch->destroy, NULL); + dev->device_destroy.notify(&dev->device_destroy, NULL); break; } --devn; diff --git a/input.h b/input.h new file mode 100644 index 0000000..7cec2ca --- /dev/null +++ b/input.h @@ -0,0 +1,22 @@ +#ifndef _CG_INPUT_H +#define _CG_INPUT_H + +#include + +struct cg_input_device; +struct cg_input_config; +struct cg_server; + +void +cg_input_configure_libinput_device(struct cg_input_device *device); + +void +cg_input_apply_config(struct cg_input_config *config, struct cg_server *server); + +void +cg_input_reset_libinput_device(struct cg_input_device *device); + +bool +cg_libinput_device_is_builtin(struct cg_input_device *device); + +#endif diff --git a/input_manager.c b/input_manager.c new file mode 100644 index 0000000..10f94fa --- /dev/null +++ b/input_manager.c @@ -0,0 +1,271 @@ +/* + * Cagebreak: A Wayland tiling compositor. + * + * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2018-2020 Jente Hidskes + * + * See the LICENSE file accompanying this file. + */ + +#define _POSIX_C_SOURCE 200812L + +#include "input_manager.h" +#include "config.h" +#include "input.h" +#include "seat.h" +#include "server.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +strip_whitespace(char *str) { + static const char whitespace[] = " \f\n\r\t\v"; + size_t len = strlen(str); + size_t start = strspn(str, whitespace); + memmove(str, &str[start], len + 1 - start); + + if(*str) { + for(len -= start + 1; isspace(str[len]); --len) { + } + str[len + 1] = '\0'; + } +} + +char * +input_device_get_identifier(struct wlr_input_device *device) { + int vendor = device->vendor; + int product = device->product; + char *name = strdup(device->name ? device->name : ""); + strip_whitespace(name); + + char *p = name; + for(; *p; ++p) { + // There are in fact input devices with unprintable characters in its + // name + if(*p == ' ' || !isprint(*p)) { + *p = '_'; + } + } + + const char *fmt = "%d:%d:%s"; + int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1; + char *identifier = malloc(len); + if(!identifier) { + wlr_log(WLR_ERROR, "Unable to allocate unique input device name"); + return NULL; + } + + snprintf(identifier, len, fmt, vendor, product, name); + free(name); + return identifier; +} + +void +input_manager_handle_device_destroy(struct wl_listener *listener, void *data) { + struct cg_input_device *input_device = + wl_container_of(listener, input_device, device_destroy); + + if(!input_device) { + wlr_log(WLR_ERROR, "Could not find cagebreak input device to destroy"); + return; + } + + seat_remove_device(input_device->server->seat, input_device); + + wl_list_remove(&input_device->link); + wl_list_remove(&input_device->device_destroy.link); + free(input_device->identifier); + free(input_device); +} + +static void +handle_new_input(struct wl_listener *listener, void *data) { + struct cg_input_manager *input = + wl_container_of(listener, input, new_input); + struct cg_server *server = input->server; + struct wlr_input_device *device = data; + + struct cg_input_device *input_device = + calloc(1, sizeof(struct cg_input_device)); + if(!input_device) { + wlr_log(WLR_ERROR, "Could not allocate input device"); + return; + } + device->data = input_device; + + input_device->wlr_device = device; + input_device->identifier = input_device_get_identifier(device); + input_device->server = server; + input_device->pointer = NULL; + input_device->touch = NULL; + + wl_list_insert(&input->devices, &input_device->link); + + cg_input_configure_libinput_device(input_device); + + wl_signal_add(&device->events.destroy, &input_device->device_destroy); + input_device->device_destroy.notify = input_manager_handle_device_destroy; + + struct cg_seat *seat = server->seat; + seat_add_device(seat, input_device); +} + +void +handle_virtual_keyboard(struct wl_listener *listener, void *data) { + struct cg_input_manager *input_manager = + wl_container_of(listener, input_manager, virtual_keyboard_new); + struct wlr_virtual_keyboard_v1 *keyboard = data; + struct wlr_input_device *device = &keyboard->input_device; + + struct cg_seat *seat = input_manager->server->seat; + + struct cg_input_device *input_device = + calloc(1, sizeof(struct cg_input_device)); + if(!input_device) { + wlr_log(WLR_ERROR, "could not allocate input device"); + return; + } + device->data = input_device; + + input_device->is_virtual = true; + input_device->wlr_device = device; + input_device->identifier = input_device_get_identifier(device); + wl_list_insert(&input_manager->devices, &input_device->link); + input_device->server = input_manager->server; + input_device->pointer = NULL; + input_device->touch = NULL; + + wl_signal_add(&device->events.destroy, &input_device->device_destroy); + input_device->device_destroy.notify = input_manager_handle_device_destroy; + + seat_add_device(seat, input_device); +} + +void +handle_virtual_pointer(struct wl_listener *listener, void *data) { + struct cg_input_manager *input_manager = + wl_container_of(listener, input_manager, virtual_pointer_new); + struct wlr_virtual_pointer_v1_new_pointer_event *event = data; + struct wlr_virtual_pointer_v1 *pointer = event->new_pointer; + struct wlr_input_device *device = &pointer->input_device; + + struct cg_seat *seat = input_manager->server->seat; + + struct cg_input_device *input_device = + calloc(1, sizeof(struct cg_input_device)); + if(!input_device) { + wlr_log(WLR_ERROR, "could not allocate input device"); + return; + } + device->data = input_device; + + input_device->is_virtual = true; + input_device->wlr_device = device; + input_device->identifier = input_device_get_identifier(device); + wl_list_insert(&input_manager->devices, &input_device->link); + input_device->server = input_manager->server; + input_device->pointer = NULL; + input_device->touch = NULL; + + wl_signal_add(&device->events.destroy, &input_device->device_destroy); + input_device->device_destroy.notify = input_manager_handle_device_destroy; + + seat_add_device(seat, input_device); + + if(event->suggested_output) { + wlr_cursor_map_input_to_output(seat->cursor, device, + event->suggested_output); + } +} + +struct cg_input_manager * +input_manager_create(struct cg_server *server) { + struct cg_input_manager *input = calloc(1, sizeof(struct cg_input_manager)); + if(!input) { + return NULL; + } + + wl_list_init(&input->devices); + input->server = server; + + input->new_input.notify = handle_new_input; + wl_signal_add(&server->backend->events.new_input, &input->new_input); + + input->virtual_keyboard = + wlr_virtual_keyboard_manager_v1_create(server->wl_display); + wl_signal_add(&input->virtual_keyboard->events.new_virtual_keyboard, + &input->virtual_keyboard_new); + input->virtual_keyboard_new.notify = handle_virtual_keyboard; + + input->virtual_pointer = + wlr_virtual_pointer_manager_v1_create(server->wl_display); + wl_signal_add(&input->virtual_pointer->events.new_virtual_pointer, + &input->virtual_pointer_new); + input->virtual_pointer_new.notify = handle_virtual_pointer; + + return input; +} + +uint32_t +get_mouse_bindsym(const char *name, char **error) { + // Get event code from name + int code = libevdev_event_code_from_name(EV_KEY, name); + if(code == -1) { + size_t len = snprintf(NULL, 0, "Unknown event %s", name) + 1; + *error = malloc(len); + if(*error) { + snprintf(*error, len, "Unknown event %s", name); + } + return 0; + } + return code; +} + +uint32_t +get_mouse_bindcode(const char *name, char **error) { + // Validate event code + errno = 0; + char *endptr; + int code = strtol(name, &endptr, 10); + if(endptr == name && code <= 0) { + *error = strdup("Button event code must be a positive integer."); + return 0; + } else if(errno == ERANGE) { + *error = strdup("Button event code out of range."); + return 0; + } + const char *event = libevdev_event_code_get_name(EV_KEY, code); + if(!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) { + size_t len = snprintf(NULL, 0, "Event code %d (%s) is not a button", + code, event ? event : "(null)") + + 1; + *error = malloc(len); + if(*error) { + snprintf(*error, len, "Event code %d (%s) is not a button", code, + event ? event : "(null)"); + } + return 0; + } + return code; +} + +uint32_t +input_manager_get_mouse_button(const char *name, char **error) { + uint32_t button = get_mouse_bindsym(name, error); + if(!button && !*error) { + button = get_mouse_bindcode(name, error); + } + return button; +} diff --git a/input_manager.h b/input_manager.h new file mode 100644 index 0000000..6a2cdc3 --- /dev/null +++ b/input_manager.h @@ -0,0 +1,111 @@ +#ifndef CG_INPUT_MANAGER_H +#define CG_INPUT_MANAGER_H + +#include "seat.h" +#include "server.h" +#include +#include + +struct cg_input_manager * +input_manager_create(struct cg_server *server); +struct cg_input_config * +input_device_get_config(struct cg_input_device *device); +void +input_manager_handle_device_destroy(struct wl_listener *listener, void *data); +uint32_t +input_manager_get_mouse_button(const char *name, char **error); + +struct cg_input_manager { + struct wl_list devices; + struct cg_server *server; + + struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard; + struct wlr_virtual_pointer_manager_v1 *virtual_pointer; + + struct wl_listener new_input; + struct wl_listener virtual_keyboard_new; + struct wl_listener virtual_pointer_new; +}; + +struct cg_input_config_mapped_from_region { + double x1, y1; + double x2, y2; + bool mm; +}; + +struct calibration_matrix { + bool configured; + float matrix[6]; +}; + +enum cg_input_config_mapped_to { + MAPPED_TO_DEFAULT, + MAPPED_TO_OUTPUT, + MAPPED_TO_REGION, +}; + +/** + * options for input devices + */ +struct cg_input_config { + char *identifier; + + int accel_profile; + struct calibration_matrix calibration_matrix; + int click_method; + int drag; + int drag_lock; + int dwt; + int left_handed; + int middle_emulation; + int natural_scroll; + float pointer_accel; + float scroll_factor; + /*int repeat_delay; + int repeat_rate;*/ + int scroll_button; + int scroll_method; + int send_events; + int tap; + int tap_button_map; + + /*char *xkb_layout; + char *xkb_model; + char *xkb_options; + char *xkb_rules; + char *xkb_variant; + char *xkb_file; + + bool xkb_file_is_set; + + int xkb_numlock; + int xkb_capslock;*/ + + struct wl_list link; + struct cg_input_config_mapped_from_region *mapped_from_region; + + enum cg_input_config_mapped_to mapped_to; + char *mapped_to_output; + /*struct wlr_box *mapped_to_region;*/ + + /*struct wl_list tools;*/ + + bool capturable; + struct wlr_box region; +}; + +struct cg_input_device { + char *identifier; + struct cg_server *server; + struct wlr_input_device *wlr_device; + struct wl_list link; + struct wl_listener device_destroy; + bool is_virtual; + + /* Only one of the following is non-NULL depending on the type of the input + * device */ + struct cg_pointer *pointer; + struct cg_touch *touch; +}; + +#endif diff --git a/keybinding.c b/keybinding.c index 005b87a..5d802fe 100644 --- a/keybinding.c +++ b/keybinding.c @@ -9,6 +9,8 @@ #include #include +#include "input.h" +#include "input_manager.h" #include "keybinding.h" #include "message.h" #include "output.h" @@ -63,6 +65,16 @@ keybinding_free(struct keybinding *keybinding, bool recursive) { case KEYBINDING_CONFIGURE_OUTPUT: free(keybinding->data.o_cfg->output_name); free(keybinding->data.o_cfg); + break; + case KEYBINDING_CONFIGURE_INPUT: + free(keybinding->data.i_cfg->identifier); + if(keybinding->data.i_cfg->mapped_from_region) { + free(keybinding->data.i_cfg->mapped_from_region); + } + if(keybinding->data.i_cfg->mapped_to_output) { + free(keybinding->data.i_cfg->mapped_to_output); + } + free(keybinding->data.o_cfg); default: break; } @@ -103,6 +115,9 @@ keybinding_list_init() { void keybinding_list_free(struct keybinding_list *list) { + if(!list) { + return; + } for(unsigned int i = 0; i < list->length; ++i) { keybinding_free(list->keybindings[i], true); } @@ -689,6 +704,18 @@ keybinding_show_time(struct cg_server *server) { free(msg); } +void +keybinding_show_info(struct cg_server *server) { + char *msg = server_show_info(server); + + if(!msg) { + return; + } + + message_printf(server->curr_output, "%s", msg); + free(msg); +} + void keybinding_move_view_to_next_output(struct cg_server *server) { if(wl_list_length(&server->outputs) <= 1) { @@ -870,6 +897,16 @@ keybinding_configure_output(struct cg_server *server, } } +void +keybinding_configure_input(struct cg_server *server, + struct cg_input_config *cfg) { + cg_input_apply_config(cfg, server); +} + +void +keybinding_configure_input_dev(struct cg_server *server, + struct cg_input_config *cfg) {} + /* Hint: see keybinding.h for details on "data" */ int run_action(enum keybinding_action action, struct cg_server *server, @@ -918,6 +955,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_SHOW_TIME: keybinding_show_time(server); break; + case KEYBINDING_SHOW_INFO: + keybinding_show_info(server); + break; case KEYBINDING_RESIZE_TILE_HORIZONTAL: resize_tile(server, data.i, 0); break; @@ -995,6 +1035,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_CONFIGURE_OUTPUT: keybinding_configure_output(server, data.o_cfg); break; + case KEYBINDING_CONFIGURE_INPUT: + keybinding_configure_input(server, data.i_cfg); + break; case KEYBINDING_CLOSE_VIEW: keybinding_close_view( server->curr_output->workspaces[server->curr_output->curr_workspace] diff --git a/keybinding.h b/keybinding.h index 705a4ab..4cd0e87 100644 --- a/keybinding.h +++ b/keybinding.h @@ -4,6 +4,7 @@ #include "config.h" +#include #include #include @@ -24,6 +25,8 @@ enum keybinding_action { KEYBINDING_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if reverse KEYBINDING_CONFIGURE_OUTPUT, // data.o_cfg is the desired output // configuration + KEYBINDING_CONFIGURE_INPUT, // data.i_cfg is the desired input + // configuration KEYBINDING_QUIT, KEYBINDING_NOOP, KEYBINDING_SWITCH_WORKSPACE, // data.u is the desired workspace @@ -36,6 +39,7 @@ enum keybinding_action { KEYBINDING_MOVE_VIEW_TO_WORKSPACE, // data.u is the desired workspace KEYBINDING_MOVE_VIEW_TO_NEXT_OUTPUT, KEYBINDING_SHOW_TIME, + KEYBINDING_SHOW_INFO, KEYBINDING_SWAP_LEFT, KEYBINDING_SWAP_RIGHT, @@ -61,6 +65,7 @@ union keybinding_params { float color[3]; struct keybinding *kb; struct cg_output_config *o_cfg; + struct cg_input_config *i_cfg; }; struct keybinding { diff --git a/libinput.c b/libinput.c new file mode 100644 index 0000000..f6dd957 --- /dev/null +++ b/libinput.c @@ -0,0 +1,442 @@ +#include "input.h" +#include "input_manager.h" +#include "output.h" +#include +#include +#include +#include +#include +#include +#include + +static void +log_status(enum libinput_config_status status) { + if(status != LIBINPUT_CONFIG_STATUS_SUCCESS) { + wlr_log(WLR_ERROR, "Failed to apply libinput config: %s", + libinput_config_status_to_str(status)); + } +} + +static bool +set_send_events(struct libinput_device *device, uint32_t mode) { + if(libinput_device_config_send_events_get_mode(device) == mode) { + return false; + } + wlr_log(WLR_DEBUG, "send_events_set_mode(%" PRIu32 ")", mode); + log_status(libinput_device_config_send_events_set_mode(device, mode)); + return true; +} + +static bool +set_tap(struct libinput_device *device, enum libinput_config_tap_state tap) { + if(libinput_device_config_tap_get_finger_count(device) <= 0 || + libinput_device_config_tap_get_enabled(device) == tap) { + return false; + } + wlr_log(WLR_DEBUG, "tap_set_enabled(%d)", tap); + log_status(libinput_device_config_tap_set_enabled(device, tap)); + return true; +} + +static bool +set_tap_button_map(struct libinput_device *device, + enum libinput_config_tap_button_map map) { + if(libinput_device_config_tap_get_finger_count(device) <= 0 || + libinput_device_config_tap_get_button_map(device) == map) { + return false; + } + wlr_log(WLR_DEBUG, "tap_set_button_map(%d)", map); + log_status(libinput_device_config_tap_set_button_map(device, map)); + return true; +} + +static bool +set_tap_drag(struct libinput_device *device, + enum libinput_config_drag_state drag) { + if(libinput_device_config_tap_get_finger_count(device) <= 0 || + libinput_device_config_tap_get_drag_enabled(device) == drag) { + return false; + } + wlr_log(WLR_DEBUG, "tap_set_drag_enabled(%d)", drag); + log_status(libinput_device_config_tap_set_drag_enabled(device, drag)); + return true; +} + +static bool +set_tap_drag_lock(struct libinput_device *device, + enum libinput_config_drag_lock_state lock) { + if(libinput_device_config_tap_get_finger_count(device) <= 0 || + libinput_device_config_tap_get_drag_lock_enabled(device) == lock) { + return false; + } + wlr_log(WLR_DEBUG, "tap_set_drag_lock_enabled(%d)", lock); + log_status(libinput_device_config_tap_set_drag_lock_enabled(device, lock)); + return true; +} + +static bool +set_accel_speed(struct libinput_device *device, double speed) { + if(!libinput_device_config_accel_is_available(device) || + libinput_device_config_accel_get_speed(device) == speed) { + return false; + } + wlr_log(WLR_DEBUG, "accel_set_speed(%f)", speed); + log_status(libinput_device_config_accel_set_speed(device, speed)); + return true; +} + +static bool +set_accel_profile(struct libinput_device *device, + enum libinput_config_accel_profile profile) { + if(!libinput_device_config_accel_is_available(device) || + libinput_device_config_accel_get_profile(device) == profile) { + return false; + } + wlr_log(WLR_DEBUG, "accel_set_profile(%d)", profile); + log_status(libinput_device_config_accel_set_profile(device, profile)); + return true; +} + +static bool +set_natural_scroll(struct libinput_device *d, bool n) { + if(!libinput_device_config_scroll_has_natural_scroll(d) || + libinput_device_config_scroll_get_natural_scroll_enabled(d) == n) { + return false; + } + wlr_log(WLR_DEBUG, "scroll_set_natural_scroll(%d)", n); + log_status(libinput_device_config_scroll_set_natural_scroll_enabled(d, n)); + return true; +} + +static bool +set_left_handed(struct libinput_device *device, bool left) { + if(!libinput_device_config_left_handed_is_available(device) || + libinput_device_config_left_handed_get(device) == left) { + return false; + } + wlr_log(WLR_DEBUG, "left_handed_set(%d)", left); + log_status(libinput_device_config_left_handed_set(device, left)); + return true; +} + +static bool +set_click_method(struct libinput_device *device, + enum libinput_config_click_method method) { + uint32_t click = libinput_device_config_click_get_methods(device); + if((click & ~LIBINPUT_CONFIG_CLICK_METHOD_NONE) == 0 || + libinput_device_config_click_get_method(device) == method) { + return false; + } + wlr_log(WLR_DEBUG, "click_set_method(%d)", method); + log_status(libinput_device_config_click_set_method(device, method)); + return true; +} + +static bool +set_middle_emulation(struct libinput_device *dev, + enum libinput_config_middle_emulation_state mid) { + if(!libinput_device_config_middle_emulation_is_available(dev) || + libinput_device_config_middle_emulation_get_enabled(dev) == mid) { + return false; + } + wlr_log(WLR_DEBUG, "middle_emulation_set_enabled(%d)", mid); + log_status(libinput_device_config_middle_emulation_set_enabled(dev, mid)); + return true; +} + +static bool +set_scroll_method(struct libinput_device *device, + enum libinput_config_scroll_method method) { + uint32_t scroll = libinput_device_config_scroll_get_methods(device); + if((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0 || + libinput_device_config_scroll_get_method(device) == method) { + return false; + } + wlr_log(WLR_DEBUG, "scroll_set_method(%d)", method); + log_status(libinput_device_config_scroll_set_method(device, method)); + return true; +} + +static bool +set_scroll_button(struct libinput_device *dev, uint32_t button) { + uint32_t scroll = libinput_device_config_scroll_get_methods(dev); + if((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0 || + libinput_device_config_scroll_get_button(dev) == button) { + return false; + } + wlr_log(WLR_DEBUG, "scroll_set_button(%" PRIu32 ")", button); + log_status(libinput_device_config_scroll_set_button(dev, button)); + return true; +} + +static bool +set_dwt(struct libinput_device *device, bool dwt) { + if(!libinput_device_config_dwt_is_available(device) || + libinput_device_config_dwt_get_enabled(device) == dwt) { + return false; + } + wlr_log(WLR_DEBUG, "dwt_set_enabled(%d)", dwt); + log_status(libinput_device_config_dwt_set_enabled(device, dwt)); + return true; +} + +static bool +set_calibration_matrix(struct libinput_device *dev, float mat[6]) { + if(!libinput_device_config_calibration_has_matrix(dev)) { + return false; + } + bool changed = false; + float current[6]; + libinput_device_config_calibration_get_matrix(dev, current); + for(int i = 0; i < 6; i++) { + if(current[i] != mat[i]) { + changed = true; + break; + } + } + if(changed) { + wlr_log(WLR_DEBUG, "calibration_set_matrix(%f, %f, %f, %f, %f, %f)", + mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); + log_status(libinput_device_config_calibration_set_matrix(dev, mat)); + } + return changed; +} + +void +output_get_identifier(char *identifier, size_t len, struct cg_output *output) { + struct wlr_output *wlr_output = output->wlr_output; + snprintf(identifier, len, "%s %s %s", wlr_output->make, wlr_output->model, + wlr_output->serial); +} + +struct cg_output * +output_by_name_or_id(const char *name_or_id, struct cg_server *server) { + struct cg_output *output = NULL; + wl_list_for_each(output, &server->outputs, link) { + char identifier[128]; + output_get_identifier(identifier, sizeof(identifier), output); + if(strcasecmp(identifier, name_or_id) == 0 || + strcasecmp(output->wlr_output->name, name_or_id) == 0) { + return output; + } + } + return NULL; +} + +static bool +device_is_touchpad(struct cg_input_device *device) { + if(device->wlr_device->type != WLR_INPUT_DEVICE_POINTER || + !wlr_input_device_is_libinput(device->wlr_device)) { + return false; + } + + struct libinput_device *libinput_device = + wlr_libinput_get_device_handle(device->wlr_device); + + return libinput_device_config_tap_get_finger_count(libinput_device) > 0; +} + +const char * +input_device_get_type(struct cg_input_device *device) { + switch(device->wlr_device->type) { + case WLR_INPUT_DEVICE_POINTER: + if(device_is_touchpad(device)) { + return "touchpad"; + } else { + return "pointer"; + } + case WLR_INPUT_DEVICE_KEYBOARD: + return "keyboard"; + case WLR_INPUT_DEVICE_TOUCH: + return "touch"; + case WLR_INPUT_DEVICE_TABLET_TOOL: + return "tablet_tool"; + case WLR_INPUT_DEVICE_TABLET_PAD: + return "tablet_pad"; + case WLR_INPUT_DEVICE_SWITCH: + return "switch"; + } + return "unknown"; +} + +void +apply_config_to_device(struct cg_input_config *config, + struct cg_input_device *input_device) { + if(!wlr_input_device_is_libinput(input_device->wlr_device)) { + return; + } + + struct libinput_device *device = + wlr_libinput_get_device_handle(input_device->wlr_device); + if(config->mapped_to_output && + !output_by_name_or_id(config->mapped_to_output, input_device->server)) { + wlr_log(WLR_DEBUG, + "'%s' is mapped to offline output '%s'; disabling input", + config->identifier, config->mapped_to_output); + set_send_events(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); + } else if(config->send_events != INT_MIN) { + set_send_events(device, config->send_events); + } else { + // Have to reset to the default mode here, otherwise if ic->send_events + // is unset and a mapped output just came online after being disabled, + // we'd remain stuck sending no events. + set_send_events( + device, + libinput_device_config_send_events_get_default_mode(device)); + } + + if(config->tap != INT_MIN) { + set_tap(device, config->tap); + } + if(config->tap_button_map != INT_MIN) { + set_tap_button_map(device, config->tap_button_map); + } + if(config->drag != INT_MIN) { + set_tap_drag(device, config->drag); + } + if(config->drag_lock != INT_MIN) { + set_tap_drag_lock(device, config->drag_lock); + } + if(config->pointer_accel != FLT_MIN) { + set_accel_speed(device, config->pointer_accel); + } + if(config->accel_profile != INT_MIN) { + set_accel_profile(device, config->accel_profile); + } + if(config->natural_scroll != INT_MIN) { + set_natural_scroll(device, config->natural_scroll); + } + if(config->left_handed != INT_MIN) { + set_left_handed(device, config->left_handed); + } + if(config->click_method != INT_MIN) { + set_click_method(device, config->click_method); + } + if(config->middle_emulation != INT_MIN) { + set_middle_emulation(device, config->middle_emulation); + } + if(config->scroll_method != INT_MIN) { + set_scroll_method(device, config->scroll_method); + } + if(config->scroll_button != INT_MIN) { + set_scroll_button(device, config->scroll_button); + } + if(config->dwt != INT_MIN) { + set_dwt(device, config->dwt); + } + if(config->calibration_matrix.configured) { + set_calibration_matrix(device, config->calibration_matrix.matrix); + } +} + +void +cg_input_apply_config(struct cg_input_config *config, + struct cg_server *server) { + struct cg_input_device *device = NULL; + wl_list_for_each(device, &server->input->devices, link) { + if(strcmp(config->identifier, device->identifier) != 0 && + strcmp(config->identifier, "*") != 0) { + continue; + } + + const char *device_type = input_device_get_type(device); + if(strncmp(config->identifier, "type:", 5) == 0 && + strcmp(config->identifier + 5, device_type) != 0) { + continue; + } + apply_config_to_device(config, device); + } +} + +void +cg_input_configure_libinput_device(struct cg_input_device *input_device) { + struct cg_server *server = input_device->server; + struct cg_input_config *config = NULL; + + wl_list_for_each(config, &server->input_config, link) { + if(strcmp(config->identifier, input_device->identifier) != 0 && + strcmp(config->identifier, "*") != 0) { + continue; + } + + const char *device_type = input_device_get_type(input_device); + if(!(strncmp(config->identifier, "type:", 5) && + strcmp(config->identifier + 5, device_type) == 0)) { + continue; + } + apply_config_to_device(config, input_device); + } +} + +void +cg_input_reset_libinput_device(struct cg_input_device *input_device) { + if(!wlr_input_device_is_libinput(input_device->wlr_device)) { + return; + } + + struct libinput_device *device = + wlr_libinput_get_device_handle(input_device->wlr_device); + wlr_log(WLR_DEBUG, "cg_input_reset_libinput_device(%s)", + input_device->identifier); + bool changed = false; + + changed |= set_send_events( + device, libinput_device_config_send_events_get_default_mode(device)); + changed |= + set_tap(device, libinput_device_config_tap_get_default_enabled(device)); + changed |= set_tap_button_map( + device, libinput_device_config_tap_get_default_button_map(device)); + changed |= set_tap_drag( + device, libinput_device_config_tap_get_default_drag_enabled(device)); + changed |= set_tap_drag_lock( + device, + libinput_device_config_tap_get_default_drag_lock_enabled(device)); + changed |= set_accel_speed( + device, libinput_device_config_accel_get_default_speed(device)); + changed |= set_accel_profile( + device, libinput_device_config_accel_get_default_profile(device)); + changed |= set_natural_scroll( + device, + libinput_device_config_scroll_get_default_natural_scroll_enabled( + device)); + changed |= set_left_handed( + device, libinput_device_config_left_handed_get_default(device)); + changed |= set_click_method( + device, libinput_device_config_click_get_default_method(device)); + changed |= set_middle_emulation( + device, + libinput_device_config_middle_emulation_get_default_enabled(device)); + changed |= set_scroll_method( + device, libinput_device_config_scroll_get_default_method(device)); + changed |= set_scroll_button( + device, libinput_device_config_scroll_get_default_button(device)); + changed |= + set_dwt(device, libinput_device_config_dwt_get_default_enabled(device)); + + float matrix[6]; + libinput_device_config_calibration_get_default_matrix(device, matrix); + changed |= set_calibration_matrix(device, matrix); +} + +bool +cg_libinput_device_is_builtin(struct cg_input_device *cg_device) { + if(!wlr_input_device_is_libinput(cg_device->wlr_device)) { + return false; + } + + struct libinput_device *device = + wlr_libinput_get_device_handle(cg_device->wlr_device); + struct udev_device *udev_device = libinput_device_get_udev_device(device); + if(!udev_device) { + return false; + } + + const char *id_path = + udev_device_get_property_value(udev_device, "ID_PATH"); + if(!id_path) { + return false; + } + + const char prefix[] = "platform-"; + return strncmp(id_path, prefix, strlen(prefix)) == 0; +} diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index a4a1049..321d6bf 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(1) "Version 1.7.4" "Cagebreak Manual" +cagebreak-config(1) "Version 1.8.0" "Cagebreak Manual" # NAME @@ -93,6 +93,75 @@ by prepending a line with the # symbol. *hsplit* Split current tile horizontally +*input * + Set the setting "" to "" for device "". The identifier can either be "\*" (wildcard), of the form "type:" or the identifier of the device as printed for example by *cagebreak -s*. The supported input types are + - touchpad + - pointer + - keyboard + - touch + - tablet_tool + - tablet_pad + - switch + + Configurations are applied sequentially. Currently, only libinput devices may be configured. The available settings and their corresponding values are as follows: + + *accel_profile adaptive|flat* + Sets the pointer acceleration profile for the specified input device. + + *calibration_matrix <6 space-separated floating point values>* + Sets the calibration matrix. + + *click_method none|button_areas|clickfinger* + Changes the click method for the specified device. + + *drag enabled|disabled* + Enables or disables tap-and-drag for specified input device. + + *drag_lock enabled|disabled* + Enables or disables drag lock for specified input device. + + *dwt enabled|disabled* + Enables or disables disable-while-typing for the specified input device. + + *enabled|disabled|disabled_on_external_mouse* + Enables or disables send_events for specified input device. Disabling + send_events disables the input device. + + *left_handed enabled|disabled* + Enables or disables left handed mode for specified input device. + + *middle_emulation enabled|disabled* + Enables or disables middle click emulation. + + *natural_scroll enabled|disabled* + Enables or disables natural (inverted) scrolling for the specified input + device. + + *pointer_accel [<-1|1>]* + Changes the pointer acceleration for the specified input device. + + *scroll_button disable|* + Sets the button used for scroll_method on_button_down. The button can + be given as an event name or code, which can be obtained from *libinput + debug-events*. If set to + _disable_, it disables the scroll_method on_button_down. + + *scroll_factor * + Changes the scroll factor for the specified input device. Scroll speed will + be scaled by the given value, which must be non-negative. + + *scroll_method none|two_finger|edge|on_button_down* + Changes the scroll method for the specified input device. + + *tap enabled|disabled* + Enables or disables tap for specified input device. + + *tap_button_map lrm|lmr* + Specifies which button mapping to use for tapping. _lrm_ treats 1 finger as + left click, 2 fingers as right click, and 3 fingers as middle click. _lmr_ + treats 1 finger as left click, 2 fingers as middle click, and 3 fingers as + right click. + *mode * Enter mode "". After a keybinding is processed, return to default mode @@ -140,6 +209,10 @@ by prepending a line with the # symbol. *resizeup* Resize the current tile towards the top +*show_info* + Display info about the current setup. In particular, print the identifiers + of the available inputs and outputs. + *setmode * Set the default mode to diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index aa66b7e..309be7c 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.7.4" "Cagebreak Manual" +cagebreak(1) "Version 1.8.0" "Cagebreak Manual" # NAME @@ -38,6 +38,9 @@ are displayed in a message box at the top right of the screen. *-r* Rotate the output 90 degrees clockwise, can be specified up to three times +*-s* + Show all available inputs and outputs + *-v* Show version number and exit diff --git a/meson.build b/meson.build index 4f76677..e8a2cfd 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.7.4', + version: '1.8.0', license: 'MIT', default_options: [ 'c_std=c11', @@ -53,7 +53,7 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: ['>=0.14.0', '< 0.15.0']) +wlroots = dependency('wlroots', version: ['>=0.14.1', '< 0.15.0']) wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') @@ -64,6 +64,9 @@ cairo = dependency('cairo') pango = dependency('pango') pangocairo = dependency('pangocairo') fontconfig = dependency('fontconfig') +libinput = dependency('libinput') +libevdev = dependency('libevdev') +libudev = dependency('libudev') math = cc.find_library('m') wl_protocol_dir = wayland_protos.get_pkgconfig_variable('pkgdatadir') @@ -123,6 +126,7 @@ conf_data.set_quoted('CG_VERSION', version) cagebreak_main_file = [ 'cagebreak.c', ] cagebreak_source_strings = [ 'idle_inhibit_v1.c', + 'input_manager.c', 'ipc_server.c', 'keybinding.c', 'workspace.c', @@ -133,6 +137,7 @@ cagebreak_source_strings = [ 'util.c', 'view.c', 'xdg_shell.c', + 'libinput.c', 'server.c', 'message.c', 'pango.c', @@ -186,6 +191,9 @@ cagebreak_dependencies_dict = { 'wlroots': [wlroots,true], 'xkbcommon': [xkbcommon,true], 'fontconfig': [fontconfig,true], + 'libinput': [libinput,true], + 'libevdev': [libevdev,true], + 'libudev': [libudev,true], 'pixman': [pixman,true], 'pango': [pango,true], 'cairo': [cairo,true], @@ -198,13 +206,16 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.19.0', 'wayland_cursor': '1.19.0', - 'wlroots': '0.14.0', - 'xkbcommon': '1.3.0', + 'wlroots': '0.14.1', + 'xkbcommon': '1.3.1', 'fontconfig': '2.13.94', + 'libinput': '1.19.0', + 'libevdev': '1.11.0', + 'libudev': '249', 'pixman': '0.40.0', - 'pango': '1.48.6', + 'pango': '1.48.10', 'cairo': '1.17.4', - 'pangocairo': '1.48.6', + 'pangocairo': '1.48.10', 'math': '-1' } @@ -257,7 +268,7 @@ if get_option('man-pages') output : 'cagebreak.1', input : 'man/cagebreak.1.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1625064321 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1632645085 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir1 ) @@ -266,7 +277,7 @@ if get_option('man-pages') output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1625064321 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1632645085 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir5 ) diff --git a/message.c b/message.c index 2ff2075..f05b175 100644 --- a/message.c +++ b/message.c @@ -12,6 +12,7 @@ #include "output.h" #include "pango.h" #include "server.h" +#include "util.h" cairo_subpixel_order_t to_cairo_subpixel_order(const enum wl_output_subpixel subpixel) { @@ -32,14 +33,14 @@ to_cairo_subpixel_order(const enum wl_output_subpixel subpixel) { struct wlr_texture * create_message_texture(const char *string, const struct cg_output *output) { - const int PADDING = 2; - const int MESSAGE_HEIGHT = 17 + 2 * PADDING; + const int WIDTH_PADDING = 8; + const int HEIGHT_PADDING = 2; const char *font = "pango:Monospace 10"; struct wlr_texture *texture; double scale = output->wlr_output->scale; int width = 0; - int height = MESSAGE_HEIGHT * scale; + int height = 0; // We must use a non-nil cairo_t for cairo_set_font_options to work. // Therefore, we cannot use cairo_create(NULL). @@ -59,8 +60,9 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_font_options_set_subpixel_order( fo, to_cairo_subpixel_order(output->wlr_output->subpixel)); cairo_set_font_options(c, fo); - get_text_size(c, font, &width, NULL, NULL, scale, "%s", string); - width += 2 * PADDING; + get_text_size(c, font, &width, &height, NULL, scale, "%s", string); + width += 2 * WIDTH_PADDING; + height += 2 * HEIGHT_PADDING; cairo_surface_destroy(dummy_surface); cairo_destroy(c); @@ -77,7 +79,7 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_set_line_width(cairo, 2); cairo_rectangle(cairo, 0, 0, width, height); cairo_stroke(cairo); - cairo_move_to(cairo, PADDING, PADDING); + cairo_move_to(cairo, WIDTH_PADDING, HEIGHT_PADDING); pango_printf(cairo, font, scale, "%s", string); @@ -149,17 +151,14 @@ message_set_output(struct cg_output *output, const char *string, void message_printf(struct cg_output *output, const char *fmt, ...) { - uint16_t buf_len = 256; - char *buffer = (char *)malloc(buf_len * sizeof(char)); + va_list ap; + va_start(ap, fmt); + char *buffer = malloc_vsprintf_va_list(fmt, ap); + va_end(ap); if(buffer == NULL) { wlr_log(WLR_ERROR, "Failed to allocate buffer in message_printf"); return; } - va_list ap; - - va_start(ap, fmt); - vsnprintf(buffer, buf_len, fmt, ap); - va_end(ap); struct wlr_box *box = malloc(sizeof(struct wlr_box)); if(box == NULL) { diff --git a/pango.c b/pango.c index c1ca414..e9d04d3 100644 --- a/pango.c +++ b/pango.c @@ -25,7 +25,7 @@ get_pango_layout(cairo_t *cairo, const char *font, const char *text, pango_attr_list_insert(attrs, pango_attr_scale_new(scale)); PangoFontDescription *desc = pango_font_description_from_string(font); pango_layout_set_font_description(layout, desc); - pango_layout_set_single_paragraph_mode(layout, 1); + pango_layout_set_single_paragraph_mode(layout, false); pango_layout_set_attributes(layout, attrs); pango_attr_list_unref(attrs); pango_font_description_free(desc); diff --git a/parse.c b/parse.c index 46b275a..4bbf72d 100644 --- a/parse.c +++ b/parse.c @@ -1,30 +1,23 @@ #define _POSIX_C_SOURCE 200812L +#include +#include #include #include #include +#include "input_manager.h" #include "keybinding.h" #include "output.h" #include "parse.h" #include "server.h" - -char * -malloc_vsprintf(const char *fmt, va_list ap) { - va_list ap2; - va_copy(ap2, ap); - int len = vsnprintf(NULL, 0, fmt, ap); - char *ret = malloc(sizeof(char) * (len + 1)); - vsnprintf(ret, len + 1, fmt, ap2); - va_end(ap2); - return ret; -} +#include "util.h" char * log_error(const char *fmt, ...) { va_list args; va_start(args, fmt); - char *ret = malloc_vsprintf(fmt, args); + char *ret = malloc_vsprintf_va_list(fmt, args); if(ret != NULL) { wlr_log(WLR_ERROR, "%s", ret); } @@ -106,6 +99,267 @@ parse_keybinding(struct cg_server *server, char **saveptr, char **errstr) { return keybinding; } +float +parse_float(char **saveptr, const char *delim) { + char *uint_str = strtok_r(NULL, delim, saveptr); + if(uint_str == NULL) { + wlr_log(WLR_ERROR, "Expected a float, got nothing"); + return -1; + } + float ufloat = strtof(uint_str, NULL); + if(ufloat != NAN && ufloat != INFINITY && errno != ERANGE) { + return ufloat; + } else { + wlr_log(WLR_ERROR, "Error parsing float"); + return FLT_MIN; + } +} + +struct cg_input_config * +parse_input_config(char **saveptr, char **errstr) { + struct cg_input_config *cfg = calloc(1, sizeof(struct cg_input_config)); + char *value = NULL; + char *ident = NULL; + if(cfg == NULL) { + *errstr = + log_error("Failed to allocate memory for output configuration"); + goto error; + } + + cfg->tap = INT_MIN; + cfg->tap_button_map = INT_MIN; + cfg->drag = INT_MIN; + cfg->drag_lock = INT_MIN; + cfg->dwt = INT_MIN; + cfg->send_events = INT_MIN; + cfg->click_method = INT_MIN; + cfg->middle_emulation = INT_MIN; + cfg->natural_scroll = INT_MIN; + cfg->accel_profile = INT_MIN; + cfg->pointer_accel = FLT_MIN; + cfg->scroll_factor = FLT_MIN; + cfg->scroll_button = INT_MIN; + cfg->scroll_method = INT_MIN; + cfg->left_handed = INT_MIN; + /*cfg->repeat_delay = INT_MIN; + cfg->repeat_rate = INT_MIN; + cfg->xkb_numlock = INT_MIN; + cfg->xkb_capslock = INT_MIN; + cfg->xkb_file_is_set = false; + wl_list_init(&cfg->tools);*/ + + ident = strtok_r(NULL, " ", saveptr); + + if(ident == NULL) { + *errstr = log_error( + "Expected identifier of input device to configure, got none"); + goto error; + } + cfg->identifier = strdup(ident); + + char *setting = strtok_r(NULL, " ", saveptr); + if(setting == NULL) { + *errstr = + log_error("Expected setting to be set on input device, got none"); + goto error; + } + + value = strdup(*saveptr); + + if(value == NULL) { + *errstr = log_error("Failed to obtain value for input device " + "configuration of device \"%s\"", + ident); + goto error; + } + + if(strcmp(setting, "accel_profile") == 0) { + if(strcmp(value, "adaptive") == 0) { + cfg->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; + } else if(strcmp(value, "flat") == 0) { + cfg->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; + } else { + *errstr = log_error( + "Invalid profile \"%s\" for accel_profile configuration", + value); + goto error; + } + } else if(strcmp(setting, "calibration_matrix") == 0) { + cfg->calibration_matrix.configured = true; + for(int i = 0; i < 6; ++i) { + cfg->calibration_matrix.matrix[i] = parse_float(saveptr, " "); + if(cfg->calibration_matrix.matrix[i] == FLT_MIN) { + *errstr = + log_error("Failed to read calibration matrix, expected 6 " + "floating point values separated by spaces"); + goto error; + } + } + } else if(strcmp(setting, "click_method") == 0) { + if(strcmp(value, "none")) { + cfg->click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE; + } else if(strcmp(value, "button_areas")) { + cfg->click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; + } else if(strcmp(value, "clickfinger")) { + cfg->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; + } else { + *errstr = log_error( + "Invalid method \"%s\" for click_method configuration", value); + goto error; + } + } else if(strcmp(setting, "drag") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->drag = LIBINPUT_CONFIG_DRAG_ENABLED; + } else if(strcmp(value, "disabled") == 0) { + cfg->drag = LIBINPUT_CONFIG_DRAG_DISABLED; + } else { + *errstr = + log_error("Invalid option \"%s\" to setting \"drag\"", value); + goto error; + } + } else if(strcmp(setting, "drag_lock") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_ENABLED; + } else if(strcmp(value, "disabled") == 0) { + cfg->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; + } else { + *errstr = log_error( + "Invalid option \"%s\" to setting \"drag_lock\"", value); + goto error; + } + } else if(strcmp(setting, "dwt") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->dwt = LIBINPUT_CONFIG_DWT_ENABLED; + } else if(strcmp(value, "disabled") == 0) { + cfg->dwt = LIBINPUT_CONFIG_DWT_DISABLED; + } else { + *errstr = + log_error("Invalid option \"%s\" to setting \"dwt\"", value); + goto error; + } + } else if(strcmp(setting, "events") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->send_events = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; + } else if(strcmp(value, "disabled") == 0) { + cfg->send_events = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED; + } else if(strcmp(value, "disabled_on_external_mouse") == 0) { + cfg->send_events = + LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; + } else { + *errstr = + log_error("Invalid option \"%s\" to setting \"events\"", value); + goto error; + } + } else if(strcmp(setting, "left_handed") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->left_handed = true; + } else if(strcmp(value, "disabled") == 0) { + cfg->left_handed = false; + } else { + *errstr = log_error( + "Invalid option \"%s\" to setting \"left_handed\"", value); + goto error; + } + } else if(strcmp(setting, "middle_emulation") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->middle_emulation = LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED; + } else if(strcmp(value, "disabled") == 0) { + cfg->middle_emulation = LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; + } else { + *errstr = log_error( + "Invalid option \"%s\" to setting \"middle_emulation\"", value); + goto error; + } + } else if(strcmp(setting, "natural_scroll") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->natural_scroll = true; + } else if(strcmp(value, "disabled") == 0) { + cfg->natural_scroll = false; + } else { + *errstr = log_error( + "Invalid option \"%s\" to setting \"natural_scroll\"", value); + goto error; + } + } else if(strcmp(setting, "pointer_accel") == 0) { + cfg->pointer_accel = parse_float(saveptr, " "); + if(cfg->pointer_accel == FLT_MIN) { + *errstr = log_error("Invalid option \"%s\" to setting " + "\"pointer_accel\", expected float value", + value); + goto error; + } + } else if(strcmp(setting, "scroll_button") == 0) { + char *err = NULL; + cfg->scroll_button = input_manager_get_mouse_button(value, &err); + if(err) { + *errstr = log_error("Error parsing button for \"scroll_button\" " + "setting. Returned error \"%s\"", + err); + free(err); + goto error; + } + } else if(strcmp(setting, "scroll_factor") == 0) { + cfg->scroll_factor = parse_float(saveptr, " "); + if(cfg->scroll_factor == FLT_MIN) { + *errstr = log_error("Invalid option \"%s\" to setting " + "\"scroll_factor\", expected float value", + value); + goto error; + } + } else if(strcmp(setting, "scroll_method") == 0) { + if(strcmp(value, "none") == 0) { + cfg->scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL; + } else if(strcmp(value, "two_finger") == 0) { + cfg->scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; + } else if(strcmp(value, "edge") == 0) { + cfg->scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE; + } else if(strcmp(value, "on_button_down") == 0) { + cfg->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; + } else { + *errstr = log_error( + "Invalid option \"%s\" to setting \"scroll_method\"", value); + goto error; + } + } else if(strcmp(setting, "tap") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->tap = LIBINPUT_CONFIG_TAP_ENABLED; + } else if(strcmp(value, "disabled") == 0) { + cfg->tap = LIBINPUT_CONFIG_TAP_DISABLED; + } else { + *errstr = + log_error("Invalid option \"%s\" to setting \"tap\"", value); + goto error; + } + } else if(strcmp(setting, "tap_button_map") == 0) { + if(strcmp(value, "lrm") == 0) { + cfg->tap = LIBINPUT_CONFIG_TAP_MAP_LRM; + } else if(strcmp(value, "lmr") == 0) { + cfg->tap = LIBINPUT_CONFIG_TAP_MAP_LMR; + } else { + *errstr = log_error( + "Invalid option \"%s\" to setting \"tap_button_map\"", value); + goto error; + } + } + + free(value); + return cfg; + +error: + if(cfg) { + if(cfg->identifier) { + free(cfg->identifier); + } + free(cfg); + } + if(value) { + free(value); + } + wlr_log(WLR_ERROR, "Input configuration must be of the form 'input " + "\"\" '"); + return NULL; +} + struct keybinding * parse_bind(struct cg_server *server, char **saveptr, char **errstr) { struct keybinding *keybinding = parse_keybinding(server, saveptr, errstr); @@ -242,23 +496,6 @@ parse_uint(char **saveptr, const char *delim) { } } -float -parse_float(char **saveptr, const char *delim) { - char *uint_str = strtok_r(NULL, delim, saveptr); - if(uint_str == NULL) { - wlr_log(WLR_ERROR, "Expected a non-negative float, got nothing"); - return -1; - } - float ufloat = strtof(uint_str, NULL); - if(ufloat >= 0) { - return ufloat; - } else { - wlr_log(WLR_ERROR, "Error parsing non-negative float. Must be a number " - "larger or equal to 0"); - return -1; - } -} - int parse_output_config_keyword(char *key_str, enum output_status *status) { if(key_str == NULL) { @@ -352,9 +589,10 @@ parse_output_config(char **saveptr, char **errstr) { cfg->refresh_rate = parse_float(saveptr, " "); if(cfg->refresh_rate <= 0.0) { - *errstr = log_error( - "Error parsing refresh rate of output configuration for output %s", - name); + *errstr = + log_error("Error parsing refresh rate of output configuration for " + "output %s, expected positive float", + name); goto error; } @@ -383,6 +621,8 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, keybinding->action = KEYBINDING_SPLIT_HORIZONTAL; } else if(strcmp(action, "quit") == 0) { keybinding->action = KEYBINDING_QUIT; + } else if(strcmp(action, "show_info") == 0) { + keybinding->action = KEYBINDING_SHOW_INFO; } else if(strcmp(action, "close") == 0) { keybinding->action = KEYBINDING_CLOSE_VIEW; } else if(strcmp(action, "focus") == 0) { @@ -562,6 +802,12 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, if(keybinding->data.o_cfg == NULL) { return -1; } + } else if(strcmp(action, "input") == 0) { + keybinding->action = KEYBINDING_CONFIGURE_INPUT; + keybinding->data.i_cfg = parse_input_config(&saveptr, errstr); + if(keybinding->data.i_cfg == NULL) { + return -1; + } } else { *errstr = log_error("Error, unsupported action \"%s\".", action); return -1; diff --git a/parse.h b/parse.h index ba1b2e8..798d732 100644 --- a/parse.h +++ b/parse.h @@ -4,9 +4,15 @@ #define MAX_LINE_SIZE 256 +#include + struct cg_server; int parse_rc_line(struct cg_server *server, char *line, char **errstr); +char * +parse_malloc_vsprintf(const char *fmt, ...); +char * +parse_malloc_vsprintf_va_list(const char *fmt, va_list list); #endif /* end of include guard PARSE_H */ diff --git a/seat.c b/seat.c index 51450ac..91ab374 100644 --- a/seat.c +++ b/seat.c @@ -31,6 +31,7 @@ #include #endif +#include "input_manager.h" #include "keybinding.h" #include "message.h" #include "output.h" @@ -112,13 +113,13 @@ static void update_capabilities(const struct cg_seat *seat) { uint32_t caps = 0; - if(!wl_list_empty(&seat->keyboard_groups)) { + if(seat->num_keyboards > 0) { caps |= WL_SEAT_CAPABILITY_KEYBOARD; } - if(!wl_list_empty(&seat->pointers)) { + if(seat->num_pointers > 0) { caps |= WL_SEAT_CAPABILITY_POINTER; } - if(!wl_list_empty(&seat->touch)) { + if(seat->num_touch > 0) { caps |= WL_SEAT_CAPABILITY_TOUCH; } wlr_seat_set_capabilities(seat->seat, caps); @@ -133,20 +134,21 @@ update_capabilities(const struct cg_seat *seat) { } static void -handle_touch_destroy(struct wl_listener *listener, void *_data) { - struct cg_touch *touch = wl_container_of(listener, touch, destroy); - struct cg_seat *seat = touch->seat; - +remove_touch(struct cg_seat *seat, struct cg_touch *touch) { + if(!touch) { + return; + } wl_list_remove(&touch->link); - wlr_cursor_detach_input_device(seat->cursor, touch->device); - wl_list_remove(&touch->destroy.link); + wlr_cursor_detach_input_device(seat->cursor, touch->device->wlr_device); + --seat->num_touch; free(touch); update_capabilities(seat); } static void -handle_new_touch(struct cg_seat *seat, struct wlr_input_device *device) { +new_touch(struct cg_seat *seat, struct cg_input_device *input_device) { + struct wlr_input_device *device = input_device->wlr_device; struct cg_touch *touch = calloc(1, sizeof(struct cg_touch)); if(!touch) { wlr_log(WLR_ERROR, "Cannot allocate touch"); @@ -154,12 +156,10 @@ handle_new_touch(struct cg_seat *seat, struct wlr_input_device *device) { } touch->seat = seat; - touch->device = device; + touch->device = input_device; wlr_cursor_attach_input_device(seat->cursor, device); - - wl_list_insert(&seat->touch, &touch->link); - touch->destroy.notify = handle_touch_destroy; - wl_signal_add(&touch->device->events.destroy, &touch->destroy); + input_device->touch = touch; + ++seat->num_touch; if(device->output_name != NULL) { struct cg_output *output; @@ -174,20 +174,20 @@ handle_new_touch(struct cg_seat *seat, struct wlr_input_device *device) { } static void -handle_pointer_destroy(struct wl_listener *listener, void *_data) { - struct cg_pointer *pointer = wl_container_of(listener, pointer, destroy); - struct cg_seat *seat = pointer->seat; - - wl_list_remove(&pointer->link); - wlr_cursor_detach_input_device(seat->cursor, pointer->device); - wl_list_remove(&pointer->destroy.link); +remove_pointer(struct cg_seat *seat, struct cg_pointer *pointer) { + if(!pointer) { + return; + } + wlr_cursor_detach_input_device(seat->cursor, pointer->device->wlr_device); + --seat->num_pointers; free(pointer); update_capabilities(seat); } static void -handle_new_pointer(struct cg_seat *seat, struct wlr_input_device *device) { +new_pointer(struct cg_seat *seat, struct cg_input_device *input_device) { + struct wlr_input_device *device = input_device->wlr_device; struct cg_pointer *pointer = calloc(1, sizeof(struct cg_pointer)); if(!pointer) { wlr_log(WLR_ERROR, "Cannot allocate pointer"); @@ -195,12 +195,10 @@ handle_new_pointer(struct cg_seat *seat, struct wlr_input_device *device) { } pointer->seat = seat; - pointer->device = device; + pointer->device = input_device; wlr_cursor_attach_input_device(seat->cursor, device); - - wl_list_insert(&seat->pointers, &pointer->link); - pointer->destroy.notify = handle_pointer_destroy; - wl_signal_add(&device->events.destroy, &pointer->destroy); + input_device->pointer = pointer; + ++seat->num_pointers; if(device->output_name != NULL) { struct cg_output *output; @@ -431,21 +429,16 @@ cleanup: } static void -handle_new_keyboard(struct cg_seat *seat, struct wlr_input_device *device) { +new_keyboard(struct cg_seat *seat, struct cg_input_device *input_device) { + struct wlr_input_device *device = input_device->wlr_device; struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if(!context) { - wlr_log(WLR_ERROR, "Unable to create XBK context"); + wlr_log(WLR_ERROR, "Unable to create XKB context"); return; } - struct xkb_rule_names rules = {0}; - rules.rules = getenv("XKB_DEFAULT_RULES"); - rules.model = getenv("XKB_DEFAULT_MODEL"); - rules.layout = getenv("XKB_DEFAULT_LAYOUT"); - rules.variant = getenv("XKB_DEFAULT_VARIANT"); - rules.options = getenv("XKB_DEFAULT_OPTIONS"); struct xkb_keymap *keymap = - xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + xkb_map_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS); if(!keymap) { wlr_log(WLR_ERROR, "Unable to configure keyboard: keymap does not exist"); @@ -460,24 +453,64 @@ handle_new_keyboard(struct cg_seat *seat, struct wlr_input_device *device) { wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); cg_keyboard_group_add(device, seat); + ++seat->num_keyboards; wlr_seat_set_keyboard(seat->seat, device); } -static void -handle_new_input(struct wl_listener *listener, void *data) { - struct cg_seat *seat = wl_container_of(listener, seat, new_input); - struct wlr_input_device *device = data; - - switch(device->type) { +void +seat_add_device(struct cg_seat *seat, struct cg_input_device *device) { + switch(device->wlr_device->type) { case WLR_INPUT_DEVICE_KEYBOARD: - handle_new_keyboard(seat, device); + new_keyboard(seat, device); break; case WLR_INPUT_DEVICE_POINTER: - handle_new_pointer(seat, device); + new_pointer(seat, device); break; case WLR_INPUT_DEVICE_TOUCH: - handle_new_touch(seat, device); + new_touch(seat, device); + break; + case WLR_INPUT_DEVICE_SWITCH: + wlr_log(WLR_DEBUG, "Switch input is not implemented"); + return; + case WLR_INPUT_DEVICE_TABLET_TOOL: + case WLR_INPUT_DEVICE_TABLET_PAD: + wlr_log(WLR_DEBUG, "Tablet input is not implemented"); + return; + } + + update_capabilities(seat); +} + +void +remove_keyboard(struct cg_seat *seat, struct cg_input_device *keyboard) { + if(!keyboard) { + return; + } + struct wlr_seat *wlr_seat = seat->seat; + struct wlr_keyboard *wlr_keyboard = keyboard->wlr_device->keyboard; + if(keyboard->wlr_device->keyboard->group) { + wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard); + } + if(wlr_seat_get_keyboard(wlr_seat) == wlr_keyboard) { + wlr_seat_set_keyboard(wlr_seat, NULL); + } + --seat->num_keyboards; +} + +void +seat_remove_device(struct cg_seat *seat, struct cg_input_device *device) { + switch(device->wlr_device->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + remove_keyboard(seat, device); + break; + case WLR_INPUT_DEVICE_POINTER: + remove_pointer(seat, device->pointer); + device->pointer = NULL; + break; + case WLR_INPUT_DEVICE_TOUCH: + remove_touch(seat, device->touch); + device->touch = NULL; break; case WLR_INPUT_DEVICE_SWITCH: wlr_log(WLR_DEBUG, "Switch input is not implemented"); @@ -801,15 +834,11 @@ handle_destroy(struct wl_listener *listener, void *_data) { wl_event_source_remove(group->key_repeat_timer); free(group); } - struct cg_pointer *pointer, *pointer_tmp; - wl_list_for_each_safe(pointer, pointer_tmp, &seat->pointers, link) { - handle_pointer_destroy(&pointer->destroy, NULL); + + struct cg_input_device *it, *it_tmp; + wl_list_for_each_safe(it, it_tmp, &seat->server->input->devices, link) { + input_manager_handle_device_destroy(&it->device_destroy, NULL); } - struct cg_touch *touch, *touch_tmp; - wl_list_for_each_safe(touch, touch_tmp, &seat->touch, link) { - handle_touch_destroy(&touch->destroy, NULL); - } - wl_list_remove(&seat->new_input.link); wlr_xcursor_manager_destroy(seat->xcursor_manager); if(seat->cursor) { @@ -898,11 +927,9 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) { &seat->request_set_primary_selection); wl_list_init(&seat->keyboard_groups); - wl_list_init(&seat->pointers); - wl_list_init(&seat->touch); - - seat->new_input.notify = handle_new_input; - wl_signal_add(&backend->events.new_input, &seat->new_input); + seat->num_keyboards = 0; + seat->num_pointers = 0; + seat->num_touch = 0; wl_list_init(&seat->drag_icons); seat->request_start_drag.notify = handle_request_start_drag; diff --git a/seat.h b/seat.h index a7632d7..9331042 100644 --- a/seat.h +++ b/seat.h @@ -7,6 +7,7 @@ struct cg_server; struct cg_view; struct wlr_cursor; struct wlr_input_device; +struct cg_input_device; struct wlr_seat; struct wlr_xcursor_manager; struct wlr_backend; @@ -20,9 +21,10 @@ struct cg_seat { struct wl_listener destroy; struct wl_list keyboard_groups; - struct wl_list pointers; - struct wl_list touch; - struct wl_listener new_input; + + uint16_t num_keyboards; + uint16_t num_pointers; + uint16_t num_touch; struct wlr_cursor *cursor; struct wlr_xcursor_manager *xcursor_manager; @@ -70,17 +72,13 @@ struct cg_keyboard_group { struct cg_pointer { struct wl_list link; // seat::pointers struct cg_seat *seat; - struct wlr_input_device *device; - - struct wl_listener destroy; + struct cg_input_device *device; }; struct cg_touch { struct wl_list link; // seat::touch struct cg_seat *seat; - struct wlr_input_device *device; - - struct wl_listener destroy; + struct cg_input_device *device; }; struct cg_drag_icon { @@ -102,5 +100,9 @@ struct cg_view * seat_get_focus(const struct cg_seat *seat); void seat_set_focus(struct cg_seat *seat, struct cg_view *view); +void +seat_add_device(struct cg_seat *seat, struct cg_input_device *device); +void +seat_remove_device(struct cg_seat *seat, struct cg_input_device *device); #endif diff --git a/server.c b/server.c index c82296f..1ad23e6 100644 --- a/server.c +++ b/server.c @@ -9,11 +9,16 @@ #define _POSIX_C_SOURCE 200809L +#include #include #include #include +#include +#include "input_manager.h" +#include "output.h" #include "server.h" +#include "util.h" void display_terminate(struct cg_server *server) { @@ -35,3 +40,36 @@ get_mode_index_from_name(char *const *modes, const char *mode_name) { } return -1; } + +char * +server_show_info(struct cg_server *server) { + char *output_str = strdup(""), *output_str_tmp; + struct cg_output *output; + wl_list_for_each(output, &server->outputs, link) { + if(!output_str) { + return NULL; + } + output_str_tmp = output_str; + output_str = malloc_vsprintf("%s\t * %s\n", output_str, + output->wlr_output->name); + free(output_str_tmp); + } + char *input_str = strdup(""), *input_str_tmp; + struct cg_input_device *input; + wl_list_for_each(input, &server->input->devices, link) { + if(!input_str) { + return NULL; + } + input_str_tmp = input_str; + if(strcmp(input->identifier, "") != 0) { + input_str = + malloc_vsprintf("%s\t * %s\n", input_str, input->identifier); + } + free(input_str_tmp); + } + char *ret = + malloc_vsprintf("Outputs:\n%sInputs:\n%s", output_str, input_str); + free(output_str); + free(input_str); + return ret; +} diff --git a/server.h b/server.h index 4e594b9..9ee21e1 100644 --- a/server.h +++ b/server.h @@ -13,12 +13,14 @@ struct keybinding_list; struct wlr_output_layout; struct wlr_idle_inhibit_manager_v1; struct cg_output_config; +struct cg_input_manager; struct cg_server { struct wl_display *wl_display; struct wl_event_loop *event_loop; struct cg_seat *seat; + struct cg_input_manager *input; struct wlr_backend *backend; struct wlr_idle *idle; struct wlr_idle_inhibit_manager_v1 *idle_inhibit_v1; @@ -39,6 +41,7 @@ struct cg_server { struct keybinding_list *keybindings; struct wl_list output_config; + struct wl_list input_config; enum wl_output_transform output_transform; @@ -58,5 +61,7 @@ void display_terminate(struct cg_server *server); int get_mode_index_from_name(char *const *modes, const char *mode_name); +char * +server_show_info(struct cg_server *server); #endif diff --git a/signatures/1.7.4-cagebreak-config.5.sig b/signatures/1.7.4-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..0fa98a3b5e3730da2324fb1b7cdc2142ad58171e GIT binary patch literal 566 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 delta 543 zcmV+)0^t3&1hxc_B7b1qlfM882@vvEYtv>GYq?0M5CE9)E)*64OdS($)&npk{I5;b zc+pEKzy}wDMm=T-$2|1`bs{&Y>cZDJGW7e;q}N*MXANSae^O7~?xSPiEtuYujH0@S zb$t^13_l}bD|Y!PfTD6Ru(ZAAgHhn(r5%v3-$2YxD0g}Xb$?Tr0nCo>_OV`oZdpn3 zd1bs+OynFI`6WsP9rre1nNY0f%rga!k83rbemp7vWa!vS9X9-lnVIjks;77kVu5Ff=L_x#>DW=*{MebO%6b>B@UON}NM>E7w{W;>Y zTi9yunD+)jUwirB$?iGo#*4OqhHw#XZS8!=IlFzLgwm diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 22e1818ab09d095c08f005169e584fd605ad2096..a7634a92693b30deb71ef71ca850c6d5cee432f8 100644 GIT binary patch delta 543 zcmV+)0^t3&1hxc_B7b2}$W8zX2@vvEYtv>GYq@KD5C42M41b8lDa1hwp}r$*6mfYIB?xP9hm$L{d+4`+61fy$ha_yf(-u; zOaD|8D6IreUw@pEQcm$JdR}-FdOa!?sBGUlHeF@5>JEKB=OV2~-Iuz0Af)-!8b+;) ziv25Ro?Rw<@n)Rf^)`SS_>l{RD?CrEKTsW1@KGl-8(gt_c1jHGSF@93g>#}VFCxHe zVj~d)1Rdu|p&j}{SE2~TE6f-C9cP`0IG^ z%aDQz5{Sd++aJk?eibqa^NK+47`5T@1;;FbQ;Y`F=+^-+GYq_Kp5B@w2|2`G;@$*x1{c?@Es7QnE zGX?SLQxZ_*NgIF7G2TK-`Zc}Sdb8)5pS|hhN3AC>ag3)vJj99sG9ZNz}N_o zxOtBa)>gqm#Xa=70XoRSgrM6ynScw9i@cwIRW@Ae_f>RiB7b#CjW1@>8=mFN=fpc{ zgXof*S_^3=>;5IeN`#o9FRcSUj`KvPZ68Fjx5=^6;jR);i6yZ9(|R+>2bFQr1c`Bl zyAp`AbsxwSAV-f8Foy2L-mlaT6;F$aTLuksFaUI6j0Mb*hM5QLWLQDf@O-8LmdqO3 zfEOGmy2`sIKYvFUdFEBQg1@#{pJXTuSybKI`ko4+z@QV1_3dUL#I~STc}!&> zR+)Xt?`~CSF3Tg4BJno#Db-kXATr&d=rSYwMwt1;Ab;XlP9P^3(2sBB3u3$fRE{nI zP{j=)THh7UgY;@giKJ|4kaSPon`d9o+kP(IC=$(Kx #include "util.h" +#include int scale_length(int length, int offset, double scale) { @@ -33,3 +34,22 @@ scale_box(struct wlr_box *box, double scale) { box->x = (int)round(box->x * scale); box->y = (int)round(box->y * scale); } + +char * +malloc_vsprintf_va_list(const char *fmt, va_list ap) { + va_list ap2; + va_copy(ap2, ap); + int len = vsnprintf(NULL, 0, fmt, ap); + char *ret = malloc(sizeof(char) * (len + 1)); + vsnprintf(ret, len + 1, fmt, ap2); + va_end(ap2); + return ret; +} + +char * +malloc_vsprintf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + char *ret = malloc_vsprintf_va_list(fmt, args); + return ret; +} diff --git a/util.h b/util.h index 8ddc7be..01e403e 100644 --- a/util.h +++ b/util.h @@ -1,6 +1,8 @@ #ifndef CG_UTIL_H #define CG_UTIL_H +#include + struct wlr_box; /** Apply scale to a width or height. */ @@ -10,4 +12,9 @@ scale_length(int length, int offset, double scale); void scale_box(struct wlr_box *box, double scale); +char * +malloc_vsprintf(const char *fmt, ...); +char * +malloc_vsprintf_va_list(const char *fmt, va_list list); + #endif From f31509f4dfc851ac928fd4a3c2d7240f82c94afe Mon Sep 17 00:00:00 2001 From: Cagebreak Signing Key 7 Date: Fri, 12 Nov 2021 18:12:10 +0100 Subject: [PATCH 04/19] Release 1.8.1 - Fix Issue 27 (Add default config) --- Bugs.md | 11 +++++++++++ README.md | 15 +++++++++++++++ cagebreak.c | 14 ++++++++++++-- examples/config | 12 ++++++------ keybinding.c | 3 ++- man/cagebreak-config.5.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 12 +++++++----- signatures/1.8.0-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.8.0-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.8.0.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 14 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 signatures/1.8.0-cagebreak-config.5.sig create mode 100644 signatures/1.8.0-cagebreak.1.sig create mode 100644 signatures/1.8.0.sig diff --git a/Bugs.md b/Bugs.md index c9d9197..244056d 100644 --- a/Bugs.md +++ b/Bugs.md @@ -341,3 +341,14 @@ The advantages are: Cagebreak has always used pandoc to compile man pages. Cagebreak now uses scdoc instead. +### Issue 27 + + * github issue number: #8 + * Fixed: 1.8.1 + +``` +Apologies for opening two tickets instead of one, but I thought that these two suggestions are different enought they merit their own "issue". + +Would replicating the behaviour in ratpoison (if no config file is found, load predefined defaults) something you would be interested in? I personally found confusing when I first tried cagebreak that it wouldn't start without a config file, coming from ratpoison. Of course, other people's experience might be different. +``` + diff --git a/README.md b/README.md index 3008d93..a99d6fe 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,21 @@ For every release after 1.0.5, hashes will be provided. For every release after 1.7.0, hashes will be provided for man pages too. +1.8.1 cagebreak + + * sha 256: e3247281d21525413790e3feceae129d9b0559497615d3fdd64ec2fc4ab9ab3d + * sha 512: 8c7c2820be9d7c74e3f9e239c7da740ff41d7f11cd40953dbfbc59c04942077f08625f6d7ec37e6037fd9c4b6950fc4f9af23478080665fdda867c65e0a187bf + +1.8.1 cagebreak.1 + + * sha 256: 96997afdfde9c2719533799aa48c8f036610bb04bc719130d2ab3a3617b072ee + * sha 512: 0831f5d2e3b4f23fd5775df2b7f6486099d64962567222a8fb49e6a40e7d29ed36a7c2c16201bbdcc985ac74f1d0e034b530afbe0ce58d6a0c53d467cff0a6a0 + +1.8.1 cagebreak-config.5 + + * sha 256: bd0e2eb02ba28ec1c8f2bd0fd5cd4c84af24b615fcc477414e49e68e1963cf1b + * sha 512: 7135a2b371294bfdc759a393c13fa0225f1789dba94bb09e96ae689796215b8030280d6cc09c9d1fe139f000f5a4748efd16bb3e5d3b9fcc74a19259802f20ef + 1.8.0 cagebreak * sha 256: ac84aa4a08c311da79ca29d92eef4254cb625674b255dbb75621ee6b171a1d79 diff --git a/cagebreak.c b/cagebreak.c index 0738b67..838078f 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -192,7 +192,7 @@ set_configuration(struct cg_server *server, if(config_file == NULL) { wlr_log(WLR_ERROR, "Could not open config file \"%s\"", config_file_path); - return -1; + return 1; } char line[MAX_LINE_SIZE * sizeof(char)]; for(unsigned int line_num = 1; @@ -557,7 +557,17 @@ main(int argc, char *argv[]) { ret = 1; goto end; } - if(set_configuration(&server, config_file) != 0) { + int conf_ret = set_configuration(&server, config_file); + + // Configurtion file not found + if(conf_ret == 1) { + char *default_conf = "/etc/xdg/cagebreak/config"; + wlr_log(WLR_ERROR, "Loading default configuration file: \"%s\"", + default_conf); + conf_ret = set_configuration(&server, default_conf); + } + + if(conf_ret != 0) { free(config_file); ret = 1; goto end; diff --git a/examples/config b/examples/config index 0ecf20b..f701684 100644 --- a/examples/config +++ b/examples/config @@ -75,14 +75,14 @@ definekey top XF86MonBrightnessUp exec xbacklight -inc 1 ###################### #Output configuration ###################### -output eDP-1 pos 0 0 res 1366x768 rate 60 -output eDP-1 disable -output eDP-1 enable +#output eDP-1 pos 0 0 res 1366x768 rate 60 +#output eDP-1 disable +#output eDP-1 enable ##################### #Input configuration ##################### -input 1234:0:Device_Ident click_method clickfinger -input type:pointer scroll_method two_finger -input * calibration_matrix 1 2 3 4 5 6 +#input 1234:0:Device_Ident click_method clickfinger +#input type:pointer scroll_method two_finger +#input * calibration_matrix 1 2 3 4 5 6 diff --git a/keybinding.c b/keybinding.c index 5d802fe..f7761cd 100644 --- a/keybinding.c +++ b/keybinding.c @@ -201,7 +201,8 @@ swap_tile(struct cg_tile *tile, view_maximize(swap_tile->view, swap_tile); view_damage_whole(swap_tile->view); } else { - wlr_output_damage_add_box(tile->workspace->output->damage, &tile->tile); + wlr_output_damage_add_box(tile->workspace->output->damage, + &swap_tile->tile); } seat_set_focus(server->seat, swap_tile->view); diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 321d6bf..4bffac7 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(1) "Version 1.8.0" "Cagebreak Manual" +cagebreak-config(1) "Version 1.8.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 309be7c..ccbe02f 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.8.0" "Cagebreak Manual" +cagebreak(1) "Version 1.8.1" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index e8a2cfd..15806f5 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.8.0', + version: '1.8.1', license: 'MIT', default_options: [ 'c_std=c11', @@ -209,8 +209,8 @@ reproducible_build_versions = { 'wlroots': '0.14.1', 'xkbcommon': '1.3.1', 'fontconfig': '2.13.94', - 'libinput': '1.19.0', - 'libevdev': '1.11.0', + 'libinput': '1.19.2', + 'libevdev': '1.12.0', 'libudev': '249', 'pixman': '0.40.0', 'pango': '1.48.10', @@ -258,6 +258,8 @@ executable( c_args: fuzz_compile_args, ) +install_data('examples/config', install_dir : '/etc/xdg/cagebreak') + if get_option('man-pages') scdoc = find_program('scdoc') sh = find_program('sh') @@ -268,7 +270,7 @@ if get_option('man-pages') output : 'cagebreak.1', input : 'man/cagebreak.1.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1632645085 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1636733005 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir1 ) @@ -277,7 +279,7 @@ if get_option('man-pages') output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1632645085 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1636733005 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir5 ) diff --git a/signatures/1.8.0-cagebreak-config.5.sig b/signatures/1.8.0-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..c33bf84d9accbd04cca9426eac3d91dc33604f84 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%1_dRR9VJ5b{@R z(`FTGxwqsH0JD;Fcemn6^SY>!r!$^IcZ_7=!le3F%&GbQ@i{az=tMD zp0SVH&aNKOu4vh~w+HyO|LJ6;!6ep8!5T2W%CS-pVG&<45g@Dgu36Z`!6ax|+Sw^&vpLKAM-l>lECW+VQ=3yjFGgPnb zJ9`P;qSVd&JSZHXjF(OTWxqo5S8LN|6>GT#0%1_dQ2+`F5b{@R z(`FTGxi-cR{TEiiucp;EP3jEprrM$ZM_fZqrWPN&0K?en`1W=d0HPQr+LjgYjRm)# zn>t#2X0)c6XWbU@j;R)2lF9uepP9e;&hHRy!exjIQwN4F!1c{>Hv+5 zE#_`|Y~aw@>Bk6o%i{QGF2QH%LBODOPiszs`!h1O1ZhsbE2gNBg|nEtNKdhQk{AHy&-O$yQfSiOhJCYRE3n-fU39%A>Z&%k;; zqXXK*ytgCS1_rm3xIvF^j}z8#zpwOC8V;_D@?z!80yNMwG0i9SPcYeIWJ;zw zUCh%`GQ2@JqH3=HY%;Ji9U;)p)uAcA+OILn88ma38x%Af>BTT_F$}3c3AVL_g9sMS Ex@pE2H2?qr literal 0 HcmV?d00001 diff --git a/signatures/1.8.0.sig b/signatures/1.8.0.sig new file mode 100644 index 0000000000000000000000000000000000000000..a7634a92693b30deb71ef71ca850c6d5cee432f8 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%1_dP5=rC5b{@R z(`FTGxodn6|9my%M3BiqldlUGnKP0S5JEIrZ%!Df&_|c^VtW@N1YPd_I$3t?X|pw2cSK4Ku>dJMllkR^pua z6fp!g+MDg3K>kL0!r?wG#X)#VgDg{2gbVh&Z2L z9NWkx{%nb>_!3(ia^Nt&y;@Dxx1^bXnc)5aVFW7=PMAq0+TbtQRiKw_sv&1VtI51n z#wNSeWlkz!vMj1Rwo(mJIP%iP+Sf>^%aDQz5{Sd++aJk?eibqa^NK+47`5T@1;;Fb zQ;Y`F=+^-+sO#lD@ literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index c33bf84d9accbd04cca9426eac3d91dc33604f84..a8dcddbb8fac719c3a8dff1262b4491f841c1ee0 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY%#cegFyy5b{@R(`FTGxuLEP|4`&cLypF@_=!^Y6WMzO^hgwA z?*+8@Dy$)Vm7@m96jT!h<2A#{CdXKtCE&242O$oniCtN3j3GAMKT;B$q&Qezo5Yn5 z2spXjB*>uXpqJP-M(16>8#AO?SAj$3QII~;WVL(+CiHR&0)PJfyLDc)$(^)>9H3f7 zt{rsgg-xH5tbjLI?~rbC5d6p5sI|I|)bT0BeKq?t#4eQnVG9X1IgO?ds()us%+I9L z^aL?jSz*Qo7GFHZel4)s@T~XN1+QVEk~qx^kAhrGi_f(OL6Jg0P$H*9&T3aEv;-s( zp|gYna(I$~%YU$cPIP!s@*=(8uk!%;r#Ci%I;>{%OGVBm3d!dGrRQ#)GPlCjku4a} zDFCWtwo{IbIG<5x65psrCdQ{C@t&&ucUJIP-bIzy)g z8Hs>*40KYYafLPC78eBs_5BPtj7lb1upEYxDQ3Ekn%2C$g?z%6Y+-Z2%&v<%Z|5N6 gmC4hyQ5Sq0Et2JhKu>mS;VGKHgY`=1R+}^5Af~trk^lez delta 542 zcmV+(0^$9(1hxc_BY#lHRR9VJ5b{@R(`FTGxwqsH0JD;Fcemn6^SY>!r!$^IcZ_7= z!le3F%&GbQ@i{az=tMDp0SVH&aNKOu4vh~w|@utwg2g4q`@TCOTij2 zzRIyu4`C5sG7%uG7Iq-<*N8x#`QGPg9ul8Cqa9ZI6H7MR1B#NP>G&PHXA@Aq062&w z;B_7dTSVc+(f2WRaw!CaR@)@?%#&IAh0Ybb&y)-G2Snnlo;f;?P!W+3l8>LEze59- zKQMuXLJ{<@_^*f=du&kSN-vBb@^T2D^)1b=;>BP@Bs;tzB&{G z5*=Aaw2z;4aFE`qj`k*r*XQP8Buz6^ukAZ~3EiU9&42tnC>+RQJfnZ+Bn4plhoZU+ zXiwXCi%a@G{9%)9%ra%%Gv8cr|L zfDe+&7^=n^u5yVqlAyb7r@X0S;f)P=Fqtrz6u=FMJjQmdtug?^Y8WY0&Hq>S!YUs0 g6m&6}r5ExQ&{h`!RhS9E21%TB0Egqg8Ks!Q-o+IV6#xJL diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 5b92ae876f29b78f3eb76342734bcb65cd350051..1ded6a279c2371a23ec98a1686c1f19371049416 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY%#cc>oFt5b{@R(`FTGx!orZ|7$1CSrns?s|bmbwH!qeK~h#H zaMK7TOE7h-v3JIpA7XFy4;OdZ14yKN(!xZNltcN>5hx<08>j_3lK3O|qemqvQR|c5 z^4T6pg8i4vVl$}}KpqyzJ&*^xnT5>cS!`sN6;Fvq_@|AW1b>IWn@K@DAG>_L8my0; zKVuID&;`q+-Qed$;9y2Y4Y0t=n!YE#Xn^q3L3zKYlddGkNc(m{rZY?ovHt#2X0)c6XWbU@j;R)2lF9uepP94yWy9A{(nTc{K~cSzV<{86Jyai?it8=>1HMY!}s{0{Pl(>$!1lBPNY zoU>$PB!3>mT2?zDh~-LI+q_6BRe~q-8&xe|sZd;ytyK#kR??D9>cO5`0m}(#egMX= zy5F}HzYxRz$$!~R|HtM1Bh|#Z^mKt7_>?^B?AvZlMA5zfe#Qi|7^nWksr)8T7yOvCt{;th>?iME> z!!R^W3eo>qy@$#sm(p^Z6G*lmV)v@gzBTT_F$}3c3AVL_g9sMSx=5`MKL7v# diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index a7634a92693b30deb71ef71ca850c6d5cee432f8..ecd7a2566e766615ecc9c10e737a02ac53bfdfae 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY%#cYyb)g5b{@R(`FTGx!T(h0H){{?qPG=ZpU$mlpWat9^EbI z{c8Lyy;kt1*rm4`Zn-JdM*sf#Fi(%sPDmIpoyiay;`|OpiqTRlr;+8wBa}3SO8i75 zFYA;Yv7K+zvGnd{dMA$AeU1kS*z!7IzR4+K>}FuDI`$qP<$sD2}UJ z2Js4GuBT(6UVnsCOT#w1Ype`|bR%gmg`DuLr_Yv#el*ExyIUy`ev2w}lt$9;g;7sb zAciNblts)Fq<97>)8tv%i*ie%B02-# znnn_On;KMEmO_cb>!nXJIa5&bmzSP4*-GFt3o3*kMSmPI{gB}NqDi3r)S$J;23Unt zp#K%^Iy8#TXKrSu2MIS+*|iqZrFKbQQXID!Hq)H!tUa-iIed|s`{`WgrFS{wA ggsG0*DHqv!$eYA*GQJEM60Wwi`us@?n#+x}kVpj(MgRZ+ delta 542 zcmV+(0^$9(1hxc_BY#lHP5=rC5b{@R(`FTGxodn6|9my%M3BiqldlUGnKP0S5JEIr zZ%!Df&_|c^VtWi+%BXvc%;fP@*6x+e^_T`{HB?NzckaNRu}nEVa>dn;Dj1gr+gxG;)>4F3;H z|5OtwtprYAoPUy1PVp;xUU(CFJt`HbY~MOIU1hfF4t+o8BCSW=m%4f&r1{huMy-pA z{VQjlT_$|-W}M#jHh>!Vkqd<@JWs4YP#sk8Q71DST(Nt0N(}8+vy)_nbD}OUBEV~6 zBM}1x9p_1*9r{97q6oz+%oqF}XPt;RpI;o?$R+-4iGQp35?dQ`;4r?uT20lrq?v%3 z;Qjz%1S=0tm`Nqt;4j%#pqFf_A!k9W$-Gp?CcD&SPAXusEUG-VQVmi#^3uiH*GQ<# zkb(&kh{NaGAIXP)6*39)ia_rewc+vw$1H(Uj0V%_*8wl(OTN08VdC$VE%0I^x;dpu g&h!776BlC8jPbp}Oi&ASE5p)mU^LXm{;@b8inmw+R{#J2 From a0ef72c6eb0ef432b6ad768d8a03423b6f581611 Mon Sep 17 00:00:00 2001 From: Cagebreak Signing Key 7 Date: Mon, 6 Dec 2021 21:16:22 +0100 Subject: [PATCH 05/19] Release 1.8.2 - Fix Issue 28 - Update year in copyright notices --- Bugs.md | 12 +++++++ LICENSE | 2 +- README.md | 15 ++++++++ idle_inhibit_v1.c | 2 +- input_manager.c | 2 +- ipc_server.c | 2 +- man/cagebreak-config.5.md | 4 +-- man/cagebreak.1.md | 4 +-- meson.build | 10 +++--- output.c | 2 +- render.c | 2 +- seat.c | 2 +- server.c | 2 +- signatures/1.8.1-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.8.1-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.8.2.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes util.c | 2 +- view.c | 44 +++++------------------- view.h | 1 - workspace.c | 2 +- xdg_shell.c | 19 +--------- xwayland.c | 2 +- 25 files changed, 57 insertions(+), 74 deletions(-) create mode 100644 signatures/1.8.1-cagebreak-config.5.sig create mode 100644 signatures/1.8.1-cagebreak.1.sig create mode 100644 signatures/1.8.2.sig diff --git a/Bugs.md b/Bugs.md index 244056d..328450d 100644 --- a/Bugs.md +++ b/Bugs.md @@ -352,3 +352,15 @@ Apologies for opening two tickets instead of one, but I thought that these two s Would replicating the behaviour in ratpoison (if no config file is found, load predefined defaults) something you would be interested in? I personally found confusing when I first tried cagebreak that it wouldn't start without a config file, coming from ratpoison. Of course, other people's experience might be different. ``` +### Issue 28 + + * github issue number: #10 + * Fixed: 1.8.2 + +``` +I'm using v. 1.8.1 and am experiencing a screen refresh lag, particularly on Firefox: + +When I type in anything, the text is refreshed and becomes visible only following mouse movement. I don't experience this with the same setup when I use Sway as the compositor. +``` + +Cagebreak had an error with damage tracking. diff --git a/LICENSE b/LICENSE index bd31b7d..538d78c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2021 The Cagebreak authors +Copyright (c) 2020-2022 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes Copyright (c) 2019 The Sway authors diff --git a/README.md b/README.md index a99d6fe..ef88746 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,21 @@ For every release after 1.0.5, hashes will be provided. For every release after 1.7.0, hashes will be provided for man pages too. +1.8.2 cagebreak + + * sha 256: f4d275d48ba3d999969f8cb3c8142d27aa8e8d362106ee7575e4b13c02173b2a + * sha 512: 72b11cb966b0978133b9848c2a7f57574c599c7fe895ca9f1cba16930216e1ac8aeae86d976593fc01b15e94ecc1430666f474654cf2fe41eda8c1181bf03f3d + +1.8.2 cagebreak.1 + + * sha 256: 51ee97a7c0b86268cf7622f84f7b1813df8e4a7838c00aae412a611d3693e87a + * sha 512: 5ce826afbee9cbc1129f37463f5b6d4dfc060583f6f7816dd5039b18d66a2b7e22f7293a4aa03acc4e6c690886d0297fef5b9f85d720a4467becfd833b59a160 + +1.8.2 cagebreak-config.5 + + * sha 256: 7c780ba85211ba40c7535b3f10f12312f9edeaa10030228ba21a96724469a325 + * sha 512: 9a56ba16c2aed6f17d4098e54900a5d25602f986e3606dd6ed26563c1920c66404b210dbca9f41bfcc3284bf5a42b750263bcaa2317320f8725e8f9c66e8b893 + 1.8.1 cagebreak * sha 256: e3247281d21525413790e3feceae129d9b0559497615d3fdd64ec2fc4ab9ab3d diff --git a/idle_inhibit_v1.c b/idle_inhibit_v1.c index 7da2dd7..8ebc768 100644 --- a/idle_inhibit_v1.c +++ b/idle_inhibit_v1.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2019 Jente Hidskes * * See the LICENSE file accompanying this file. diff --git a/input_manager.c b/input_manager.c index 10f94fa..2157b43 100644 --- a/input_manager.c +++ b/input_manager.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2020 Jente Hidskes * * See the LICENSE file accompanying this file. diff --git a/ipc_server.c b/ipc_server.c index a7c6f21..7301867 100644 --- a/ipc_server.c +++ b/ipc_server.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2020 Jente Hidskes * * See the LICENSE file accompanying this file. diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 4bffac7..670c58e 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(1) "Version 1.8.1" "Cagebreak Manual" +cagebreak-config(1) "Version 1.8.2" "Cagebreak Manual" # NAME @@ -286,7 +286,7 @@ See GitHub Issues: # LICENSE -Copyright (c) 2020-2021 The Cagebreak authors +Copyright (c) 2020-2022 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes Copyright (c) 2019 The Sway authors diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index ccbe02f..cfb0a22 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.8.1" "Cagebreak Manual" +cagebreak(1) "Version 1.8.2" "Cagebreak Manual" # NAME @@ -75,7 +75,7 @@ See GitHub Issues: # LICENSE -Copyright (c) 2020-2021 The Cagebreak authors +Copyright (c) 2020-2022 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes Copyright (c) 2019 The Sway authors diff --git a/meson.build b/meson.build index 15806f5..b81b261 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.8.1', + version: '1.8.2', license: 'MIT', default_options: [ 'c_std=c11', @@ -213,9 +213,9 @@ reproducible_build_versions = { 'libevdev': '1.12.0', 'libudev': '249', 'pixman': '0.40.0', - 'pango': '1.48.10', + 'pango': '1.50.0', 'cairo': '1.17.4', - 'pangocairo': '1.48.10', + 'pangocairo': '1.50.0', 'math': '-1' } @@ -270,7 +270,7 @@ if get_option('man-pages') output : 'cagebreak.1', input : 'man/cagebreak.1.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1636733005 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1638785664 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir1 ) @@ -279,7 +279,7 @@ if get_option('man-pages') output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1636733005 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1638785664 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir5 ) diff --git a/output.c b/output.c index 028f8b8..8feaec9 100644 --- a/output.c +++ b/output.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2020 Jente Hidskes * Copyright (C) 2019 The Sway authors * diff --git a/render.c b/render.c index 80c769b..ca4a2d2 100644 --- a/render.c +++ b/render.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2020 Jente Hidskes * Copyright (C) 2019 The Sway authors * diff --git a/seat.c b/seat.c index 91ab374..280b3ea 100644 --- a/seat.c +++ b/seat.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2020 Jente Hidskes * * See the LICENSE file accompanying this file. diff --git a/server.c b/server.c index 1ad23e6..e5b6137 100644 --- a/server.c +++ b/server.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2019 Jente Hidskes * * See the LICENSE file accompanying this file. diff --git a/signatures/1.8.1-cagebreak-config.5.sig b/signatures/1.8.1-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..a8dcddbb8fac719c3a8dff1262b4491f841c1ee0 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%4AyegFyy5b{@R z(`FTGxuLEP|4`&cLypF@_=!^Y6WMzO^hgwA?*+8@Dy$)Vm7@m96jT!h<2A#{CdXKt zCE&242O$oniCtN3j3GAMKT;B$q&Qezo5Yn52spXjB*>uXpqJP-M(16>8#AO?SAj$3 zQII~;WVL(+CiHR&0{;EGbzZc|owS4;pjt()9dzl1O`npifHzq0kZy7i{Kwj;wYrYf z@hQc9HTyHfE|mUZ3kfzkjiwK(e`in3&!p4z1Tk1yVa5g)Up&TsEwI_}toPOhuVJE+ zIL!->f?Q0C&$S0ZkwQRFBBw;oYF8+<1SAomvxEY2c#?t3uzyZ;cu?{pz2C3%0Qsjk zHi0^!qt&27||&Js$;fOj*K{;QD@{!*~33EnKO%z=+q3h z=<;@2iHE?l?eu)Iq-mFx2X8NBr5CHy{-@oa+{IByh1^*m-;Cg@InL8E@^t#X`?F2F zfJA^EjI)FUIxvvAhS>|h+F3Y4As=!-6G^9u*u6-ob5>KHNuOlCIxQN6L=3t4 z6{K0vi=eJiF;m^|YtPE(@H@$07CJ+x1sREecMNn=q;Z8c-xe1I1oiz4H;hUqS+E?2 zk|}1oj+)lIyoG$imTX~jz|5|TI&bG7mS;VGKHgY`=1R+}^5 EAl|$ZhyVZp literal 0 HcmV?d00001 diff --git a/signatures/1.8.1-cagebreak.1.sig b/signatures/1.8.1-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..1ded6a279c2371a23ec98a1686c1f19371049416 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%4Ayc>oFt5b{@R z(`FTGx!orZ|7$1CSrns?s|bmbwH!qeK~h#HaMK7TOE7h-v3JIpA7XFy4;OdZ14yKN z(!xZNltcN>5hx<08>j_3lK3O|qemqvQR|c5^4T6pg8i4vVl$}}KpqyzJ&*^xnT5>c zS!`sN6;Fvq_@|AW1c$$yNkKdxyL`PGtdE>OV-E(<2slS_DSo7^Ge%s(6ed^5$aFsiw}q zPDcJkDxN6RHR$etsF1I|1Z;Qt;!#qi4i}O$oQ)WMae=#nlYbLm?sp^~-=-6tCLvGS zpMPpZ#U5IgJd*DCr;aJUtb}sE3h>$uM@Gv^Eo>zof0Nc>V|x252492nB1J2U0I%=s zGH8>Z+zs%+B#?`GR3?egEw|(hX^t#2EUIGi9=xS5VrSzB) zxxR|n1$py7&eB1Kh-{Z*{^NowXjF(OTWxqo5S8LN|6>GT#0%4AyYyb)g5b{@R z(`FTGx!T(h0H){{?qPG=ZpU$mlpWat9^EbI{c8Lyy;kt1*rm4`Zn-JdM*sf#Fi(%s zPDmIpoyiay;`|OpiqTRlr;+8wBa}3SO8i75FYA;Yv7K+zvGnd{dMA$AeU1kS*z!7I zzR4+K>}FuDI`$qP<(@8+d}cU=>Sfo6PU6J9)4CN$b)+);f3gf0KQJKEAT3wWwjBfifp5G6cfrxDu zeigvv$zH8E2x=;*YN|pzK=FKpfazQ)j;mV+@d{(Er(>aBgj7qzHoI%A41;tdX)lGG z@T{lLmWF;b$!WV=DG+{(Ds+@a((i>)PgEd=C#;l3%oC(|1}1p&cgQ7gTYrJbvb3pr zwd*U^2n-gn=2x#p?!43FS=oznOQIq=1K*lP5_+2&R9TiniNfopPck`EQ1X|To;KM^ z;4%v;gdas5G5wI>{Gv&q{nVhf#|Bu1Q=tD9?K(7y&S!3BrUwZ(RN1u_(xrAuUs4>m z7&gKOJ|^7+8)ACXIIcGymF{E5h>ReJ}Q!NQlav`zPR` zt{A@OUb0ec*j}*6kA3S-L;m+WSTDONpoFQ8-6`35$eYA*GQJEM60Wwi`us@?n#+x} EkZ=JPJOBUy literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index a8dcddbb8fac719c3a8dff1262b4491f841c1ee0..ee831f34180a3a1a6e550daa8af0771ea5b7043d 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY&=KtpExM5b{@R(`FTGxgfO=0ItNOUOYhumTMlu%Hu1cO*sO@ zH7RNJ9K5<%$u6D_`7J(o%ztq0pi0^6pn8wU3aWTLvC9h_mRaeoa#FegPZg%6{ppB8 zGjHXnL>6)*YM@7Xh2~8OplT6&-^m%;g-|wDJs+S;I>9p}segsh6pMqEUygy9;(0d- zYm6_MCj#+uHwJor0E=6&%_1dsIPC*5?*zD4`Z@rx-%NZ2WHv-;j1TPG6%&bA)j0PV z2a>)&bY7%^t}6zg9dX?F%||@kIA6;iidBk0hF~V_r8D2l4lffhr7}3w>zi&*7(bBl z`%mnhMG~8v4}Yj|^n#dGR7){#zuo&`GupJ6au&A)kS8IP>-sb#4~!y2Yea-&>u2Z{ zMa=2nt~b8&r~ct`om=iO@bn%BQ6|%(~Q4P6Pim+tK!LXBA)RlR?5mI9{M>K$H09%Xir7BV_}sX9K&RC4F)l5<*#Ksts_z?P_P gW{BxssuvGhg*M#2j#Vb`3CA}nCd%RcX-?0WmTW8sqW}N^ delta 542 zcmV+(0^$9(1hxc_BY%#cegFyy5b{@R(`FTGxuLEP|4`&cLypF@_=!^Y6WMzO^hgwA z?*+8@Dy$)Vm7@m96jT!h<2A#{CdXKtCE&242O$oniCtN3j3GAMKT;B$q&Qezo5Yn5 z2spXjB*>uXpqJP-M(16>8#AO?SAj$3QII~;WVL(+CiHR&0)PJfyLDc)$(^)>9H3f7 zt{rsgg-xH5tbjLI?~rbC5d6p5sI|I|)bT0BeKq?t#4eQnVG9X1IgO?ds()us%+I9L z^aL?jSz*Qo7GFHZel4)s@T~XN1+QVEk~qx^kAhrGi_f(OL6Jg0P$H*9&T3aEv;-s( zp|gYna(I$~%YU$cPIP!s@*=(8uk!%;r#Ci%I;>{%OGVBm3d!dGrRQ#)GPlCjku4a} zDFCWtwo{IbIG<5x65psrCdQ{C@t&&ucUJIP-bIzy)g z8Hs>*40KYYafLPC78eBs_5BPtj7lb1upEYxDQ3Ekn%2C$g?z%6Y+-Z2%&v<%Z|5N6 gmC4hyQ5Sq0Et2JhKu>mS;VGKHgY`=1R+}^5Af~trk^lez diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 1ded6a279c2371a23ec98a1686c1f19371049416..e4133eb28d3b10e4f566ea58267ec02a7b7976dd 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY&=KssIWJ5b{@R(`FTGxq+Dv{yDkmKMvV5FYPhA3d4w~)7M2! zE0{DSNr!&NBv`?VAVXx0`;nkfXnCD{TJQGKtaLN1dkGQ=I@yUw|_-Z9o$sW*OjjhQ~&?~ delta 542 zcmV+(0^$9(1hxc_BY%#cc>oFt5b{@R(`FTGx!orZ|7$1CSrns?s|bmbwH!qeK~h#H zaMK7TOE7h-v3JIpA7XFy4;OdZ14yKN(!xZNltcN>5hx<08>j_3lK3O|qemqvQR|c5 z^4T6pg8i4vVl$}}KpqyzJ&*^xnT5>cS!`sN6;Fvq_@|AW1b>IWn@K@DAG>_L8my0; zKVuID&;`q+-Qed$;9y2Y4Y0t=n!YE#Xn^q3L3zKYlddGkNc(m{rZY?ovHt4sIdQZ1dh*xOcYCpyBO$2&yGw39yS9g5I&=TCPPJ{@=#* zdKHwc>aSS1sQENv0{MIO|2Ana3kNmtjT{qHGicfMUf0E47k^K?iF2bFJM#vnv7Xxn z#e3xuGU`^-V|r|C!uBT60+8qrz9$6G4UsA=M?Kk;#r_stB_K(^)emvrm-8K^wr_Rg zf@@bC4k~WoQ-A5C6VmRT?A>vcY>S%puddg)AM@rZ%(R%wyPU3w%4!B84Aw)drM2v# zlV=s6S-#0l?0<0>0~QlML+{HHSP5kMt;+sLO92P%cOrO%=GPUPeyXnMYS}%_Q`;z6 zlCY|iSl1&UO0v9QVH&%a5qJ5=#14u0(eHVvSplw^;R4n~`+Lw0Quh2BkbDsmxZPwKh=Kufz delta 542 zcmV+(0^$9(1hxc_BY%#cYyb)g5b{@R(`FTGx!T(h0H){{?qPG=ZpU$mlpWat9^EbI z{c8Lyy;kt1*rm4`Zn-JdM*sf#Fi(%sPDmIpoyiay;`|OpiqTRlr;+8wBa}3SO8i75 zFYA;Yv7K+zvGnd{dMA$AeU1kS*z!7IzR4+K>}FuDI`$qP<$sD2}UJ z2Js4GuBT(6UVnsCOT#w1Ype`|bR%gmg`DuLr_Yv#el*ExyIUy`ev2w}lt$9;g;7sb zAciNblts)Fq<97>)8tv%i*ie%B02-# znnn_On;KMEmO_cb>!nXJIa5&bmzSP4*-GFt3o3*kMSmPI{gB}NqDi3r)S$J;23Unt zp#K%^Iy8#TXKrSu2MIS+*|iqZrFKbQQXID!Hq)H!tUa-iIed|s`{`WgrFS{wA ggsG0*DHqv!$eYA*GQJEM60Wwi`us@?n#+x}kVpj(MgRZ+ diff --git a/util.c b/util.c index 83b7e66..1e7fa7c 100644 --- a/util.c +++ b/util.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2019 The Sway authors * * See the LICENSE file accompanying this file. diff --git a/view.c b/view.c index 19ae2ad..09fc463 100644 --- a/view.c +++ b/view.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2020 Jente Hidskes * * See the LICENSE file accompanying this file. @@ -51,10 +51,9 @@ view_get_prev_view(struct cg_view *view) { void view_damage_child(struct cg_view_child *child, bool whole) { - int x, y; - child->get_coords(child, &x, &y); - output_damage_surface(child->view->workspace->output, child->wlr_surface, - x + child->view->ox, y + child->view->oy, whole); + if(child->view != NULL) { + view_damage_part(child->view); + } } static void @@ -138,30 +137,6 @@ subsurface_handle_destroy(struct wl_listener *listener, void *_data) { subsurface_destroy(view_child); } -static void -subsurface_get_coords(struct cg_view_child *child, int *x, int *y) { - struct wlr_surface *surface = child->wlr_surface; - *x = *y = 0; - - if(child->parent && child->parent->get_coords) { - int sx, sy; - child->parent->get_coords(child->parent, &sx, &sy); - *x += sx; - *y += sy; - } else { - while(surface && wlr_surface_is_subsurface(surface)) { - struct wlr_subsurface *subsurface = - wlr_subsurface_from_wlr_surface(surface); - if(subsurface == NULL) { - break; - } - *x += subsurface->current.x; - *y += subsurface->current.y; - surface = subsurface->parent; - } - } -} - static void subsurface_create(struct cg_view_child *parent, struct cg_view *view, struct wlr_subsurface *wlr_subsurface) { @@ -173,7 +148,6 @@ subsurface_create(struct cg_view_child *parent, struct cg_view *view, view_child_init(&subsurface->view_child, parent, view, wlr_subsurface->surface); subsurface->view_child.destroy = subsurface_destroy; - subsurface->view_child.get_coords = subsurface_get_coords; subsurface->wlr_subsurface = wlr_subsurface; subsurface->destroy.notify = subsurface_handle_destroy; @@ -279,6 +253,11 @@ view_unmap(struct cg_view *view) { if(view->wlr_surface == NULL) { return; } + + struct cg_view_child *child, *tmp; + wl_list_for_each_safe(child, tmp, &view->children, link) { + child->destroy(child); + } #if CG_HAS_XWAYLAND if((view->type != CG_XWAYLAND_VIEW || xwayland_view_should_manage(view))) #endif @@ -323,11 +302,6 @@ view_unmap(struct cg_view *view) { wl_list_remove(&view->new_subsurface.link); view->wlr_surface = NULL; - - struct cg_view_child *child, *tmp; - wl_list_for_each_safe(child, tmp, &view->children, link) { - child->destroy(child); - } } void diff --git a/view.h b/view.h index add26b0..62a1f32 100644 --- a/view.h +++ b/view.h @@ -62,7 +62,6 @@ struct cg_view_child { struct wl_listener new_subsurface; void (*destroy)(struct cg_view_child *child); - void (*get_coords)(struct cg_view_child *child, int *x, int *y); }; struct cg_subsurface { diff --git a/workspace.c b/workspace.c index 36bea40..1b701e8 100644 --- a/workspace.c +++ b/workspace.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2019 Jente Hidskes * * See the LICENSE file accompanying this file. diff --git a/xdg_shell.c b/xdg_shell.c index 0e76dc4..7972b5f 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2019 Jente Hidskes * * See the LICENSE file accompanying this file. @@ -119,22 +119,6 @@ popup_unconstrain(struct cg_xdg_popup *popup) { wlr_xdg_popup_unconstrain_from_box(popup->wlr_popup, &output_toplevel_box); } -static void -xdg_popup_get_coords(struct cg_view_child *child, int *x, int *y) { - if(!child) { - return; - } - struct cg_xdg_popup *popup = (struct cg_xdg_popup *)child; - struct wlr_xdg_surface *surface = popup->wlr_popup->base; - - int x_offset = -surface->geometry.x; - int y_offset = -surface->geometry.y; - - wlr_xdg_popup_get_toplevel_coords( - surface->popup, x_offset + surface->popup->geometry.x, - y_offset + surface->popup->geometry.y, x, y); -} - static void xdg_popup_create(struct cg_view *view, struct wlr_xdg_popup *wlr_popup) { struct cg_xdg_popup *popup = calloc(1, sizeof(struct cg_xdg_popup)); @@ -143,7 +127,6 @@ xdg_popup_create(struct cg_view *view, struct wlr_xdg_popup *wlr_popup) { } popup->wlr_popup = wlr_popup; - popup->view_child.get_coords = xdg_popup_get_coords; view_child_init(&popup->view_child, NULL, view, wlr_popup->base->surface); popup->view_child.destroy = xdg_popup_destroy; popup->destroy.notify = handle_xdg_popup_destroy; diff --git a/xwayland.c b/xwayland.c index b790527..daf3658 100644 --- a/xwayland.c +++ b/xwayland.c @@ -1,7 +1,7 @@ /* * Cagebreak: A Wayland tiling compositor. * - * Copyright (C) 2020 The Cagebreak Authors + * Copyright (C) 2020-2022 The Cagebreak Authors * Copyright (C) 2018-2020 Jente Hidskes * * See the LICENSE file accompanying this file. From 35dbe7cd907b89a047a4a4a5e8c55b1628215786 Mon Sep 17 00:00:00 2001 From: Cagebreak Signing Key 7 Date: Wed, 26 Jan 2022 22:45:41 +0100 Subject: [PATCH 06/19] Release 1.8.3 * Adapt cagebreak to wlroots 0.15 --- README.md | 15 +++++++++++++++ cagebreak.c | 20 ++++++++++++++++---- fuzz/fuzz-lib.c | 20 ++++++++++++++++---- input.h | 2 +- input_manager.h | 2 +- libinput.c | 5 +++-- man/cagebreak-config.5.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 18 +++++++++--------- message.c | 7 +++---- output.c | 6 ++++++ output.h | 2 +- render.c | 23 ++++++++++------------- server.c | 2 +- server.h | 2 ++ signatures/1.8.1.sig | Bin 0 -> 566 bytes signatures/1.8.2-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.8.2-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.8.2.sig | Bin 566 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes util.c | 2 +- view.c | 10 +++++----- workspace.h | 2 +- xdg_shell.c | 2 +- xwayland.c | 2 +- 27 files changed, 95 insertions(+), 51 deletions(-) create mode 100644 signatures/1.8.1.sig create mode 100644 signatures/1.8.2-cagebreak-config.5.sig create mode 100644 signatures/1.8.2-cagebreak.1.sig diff --git a/README.md b/README.md index ef88746..939a682 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,21 @@ For every release after 1.0.5, hashes will be provided. For every release after 1.7.0, hashes will be provided for man pages too. +1.8.3 cagebreak + + * sha 256: 85803b75b1be0d9bf600175ce6aa981a1632768872e5afddea7569f825c1f7c3 + * sha 512: 96c9b33804bbd7c652e32556d5001e12c2b07ab7127118a050be513bd6e0d6241fb78c80d9cce50447ae32a7b33c5c6a6cf1def36efaf3d8e8ddb028bcd769df + +1.8.3 cagebreak.1 + + * sha 256: e583f818d73484cbcae65dbe6ffc226ea58fdad87363213ea5b1059d866216e4 + * sha 512: b96d8f9308d31bb1faa346267136fd7a53caed95065e7da09713b5f64addb42c835b27cd6cfa6bcf8c5b5d572a73b1e828f47b14e06a00b0871a77a25a286597 + +1.8.3 cagebreak-config.5 + + * sha 256: d0be008e0e5d47b876ccfb8cf70967097673b81fa93718838db45f4056b76bc0 + * sha 512: 42f8d25eb89219aebd00e927627a51fd8b7f6fda6f7c6147abbc0e4fae5de1ceb5827b79a814127a0706cc213d7717733e02cfa5275960cb0cce23eb54493b1e + 1.8.2 cagebreak * sha 256: f4d275d48ba3d999969f8cb3c8142d27aa8e8d362106ee7575e4b13c02173b2a diff --git a/cagebreak.c b/cagebreak.c index 838078f..b6fbcab 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -244,7 +245,6 @@ main(int argc, char *argv[]) { struct wl_event_source *sigterm_source = NULL; struct wl_event_source *sigalrm_source = NULL; struct wlr_backend *backend = NULL; - struct wlr_renderer *renderer = NULL; struct wlr_compositor *compositor = NULL; struct wlr_data_device_manager *data_device_manager = NULL; struct wlr_server_decoration_manager *server_decoration_manager = NULL; @@ -338,8 +338,20 @@ main(int argc, char *argv[]) { goto end; } - renderer = wlr_backend_get_renderer(backend); - wlr_renderer_init_wl_display(renderer, server.wl_display); + server.renderer = wlr_renderer_autocreate(backend); + if(!server.renderer) { + wlr_log(WLR_ERROR, "Unable to create the wlroots renderer"); + ret = 1; + goto end; + } + server.allocator = + wlr_allocator_autocreate(server.backend, server.renderer); + if(!server.allocator) { + wlr_log(WLR_ERROR, "Unable to create the wlroots allocator"); + ret = 1; + goto end; + } + wlr_renderer_init_wl_display(server.renderer, server.wl_display); server.bg_color = (float[4]){0, 0, 0, 1}; wl_list_init(&server.outputs); @@ -352,7 +364,7 @@ main(int argc, char *argv[]) { goto end; } - compositor = wlr_compositor_create(server.wl_display, renderer); + compositor = wlr_compositor_create(server.wl_display, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); ret = 1; diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index 7f9eb78..c94dd8b 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -127,7 +128,6 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { struct wl_event_loop *event_loop = NULL; struct wlr_backend *backend = NULL; - struct wlr_renderer *renderer = NULL; struct wlr_compositor *compositor = NULL; struct wlr_data_device_manager *data_device_manager = NULL; struct wlr_server_decoration_manager *server_decoration_manager = NULL; @@ -215,8 +215,20 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { wl_list_init(&server.output_config); - renderer = wlr_backend_get_renderer(backend); - wlr_renderer_init_wl_display(renderer, server.wl_display); + server.renderer = wlr_renderer_autocreate(backend); + if(!server.renderer) { + wlr_log(WLR_ERROR, "Unable to create the wlroots renderer"); + ret = 1; + goto end; + } + server.allocator = + wlr_allocator_autocreate(server.backend, server.renderer); + if(!server.allocator) { + wlr_log(WLR_ERROR, "Unable to create the wlroots allocator"); + ret = 1; + goto end; + } + wlr_renderer_init_wl_display(server.renderer, server.wl_display); server.bg_color = malloc(4 * sizeof(float)); server.bg_color[0] = 0; @@ -343,7 +355,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; } - compositor = wlr_compositor_create(server.wl_display, renderer); + compositor = wlr_compositor_create(server.wl_display, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); ret = 1; diff --git a/input.h b/input.h index 7cec2ca..0b6eb7e 100644 --- a/input.h +++ b/input.h @@ -13,7 +13,7 @@ cg_input_configure_libinput_device(struct cg_input_device *device); void cg_input_apply_config(struct cg_input_config *config, struct cg_server *server); -void +bool cg_input_reset_libinput_device(struct cg_input_device *device); bool diff --git a/input_manager.h b/input_manager.h index 6a2cdc3..35318f6 100644 --- a/input_manager.h +++ b/input_manager.h @@ -4,7 +4,7 @@ #include "seat.h" #include "server.h" #include -#include +#include struct cg_input_manager * input_manager_create(struct cg_server *server); diff --git a/libinput.c b/libinput.c index f6dd957..2510857 100644 --- a/libinput.c +++ b/libinput.c @@ -368,10 +368,10 @@ cg_input_configure_libinput_device(struct cg_input_device *input_device) { } } -void +bool cg_input_reset_libinput_device(struct cg_input_device *input_device) { if(!wlr_input_device_is_libinput(input_device->wlr_device)) { - return; + return false; } struct libinput_device *device = @@ -416,6 +416,7 @@ cg_input_reset_libinput_device(struct cg_input_device *input_device) { float matrix[6]; libinput_device_config_calibration_get_default_matrix(device, matrix); changed |= set_calibration_matrix(device, matrix); + return changed; } bool diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 670c58e..4eea4c5 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(1) "Version 1.8.2" "Cagebreak Manual" +cagebreak-config(1) "Version 1.8.3" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index cfb0a22..4fe5c6c 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.8.2" "Cagebreak Manual" +cagebreak(1) "Version 1.8.3" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index b81b261..10afb69 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.8.2', + version: '1.8.3', license: 'MIT', default_options: [ 'c_std=c11', @@ -53,7 +53,7 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: ['>=0.14.1', '< 0.15.0']) +wlroots = dependency('wlroots', version: ['>=0.14.1', '< 0.16.0']) wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') @@ -204,18 +204,18 @@ cagebreak_dependencies_dict = { reproducible_build_versions = { 'server_protos': '-1', 'wayland_server': '1.19.0', - 'wayland_client': '1.19.0', - 'wayland_cursor': '1.19.0', - 'wlroots': '0.14.1', + 'wayland_client': '1.20.0', + 'wayland_cursor': '1.20.0', + 'wlroots': '0.15.0', 'xkbcommon': '1.3.1', 'fontconfig': '2.13.94', - 'libinput': '1.19.2', + 'libinput': '1.19.3', 'libevdev': '1.12.0', - 'libudev': '249', + 'libudev': '250', 'pixman': '0.40.0', - 'pango': '1.50.0', + 'pango': '1.50.3', 'cairo': '1.17.4', - 'pangocairo': '1.50.0', + 'pangocairo': '1.50.3', 'math': '-1' } diff --git a/message.c b/message.c index f05b175..0bcb5f1 100644 --- a/message.c +++ b/message.c @@ -86,10 +86,9 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_surface_flush(surface); unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); - struct wlr_renderer *renderer = - wlr_backend_get_renderer(output->wlr_output->backend); - texture = wlr_texture_from_pixels(renderer, DRM_FORMAT_ARGB8888, stride, - width, height, data); + texture = + wlr_texture_from_pixels(output->server->renderer, DRM_FORMAT_ARGB8888, + stride, width, height, data); cairo_surface_destroy(surface); g_object_unref(pango); cairo_destroy(cairo); diff --git a/output.c b/output.c index 8feaec9..3ce60c4 100644 --- a/output.c +++ b/output.c @@ -615,6 +615,12 @@ handle_new_output(struct wl_listener *listener, void *data) { struct cg_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; + if(!wlr_output_init_render(wlr_output, server->allocator, + server->renderer)) { + wlr_log(WLR_ERROR, "Failed to initialize output rendering"); + return; + } + struct cg_output *output = calloc(1, sizeof(struct cg_output)); if(!output) { wlr_log(WLR_ERROR, "Failed to allocate output"); diff --git a/output.h b/output.h index 42cb629..7a0dc7c 100644 --- a/output.h +++ b/output.h @@ -2,7 +2,7 @@ #define CG_OUTPUT_H #include -#include +#include struct cg_server; struct cg_view; diff --git a/render.c b/render.c index ca4a2d2..53ed0ea 100644 --- a/render.c +++ b/render.c @@ -12,11 +12,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -29,8 +29,8 @@ #include "workspace.h" static void -scissor_output(struct wlr_output *output, pixman_box32_t *rect) { - struct wlr_renderer *renderer = wlr_backend_get_renderer(output->backend); +scissor_output(struct wlr_output *output, pixman_box32_t *rect, + struct wlr_renderer *renderer) { struct wlr_box box = { .x = rect->x1, @@ -56,10 +56,7 @@ struct render_data { static void render_texture(struct wlr_output *wlr_output, pixman_region32_t *output_damage, struct wlr_texture *texture, const struct wlr_box *box, - const float matrix[static 9]) { - struct wlr_renderer *renderer = - wlr_backend_get_renderer(wlr_output->backend); - + const float matrix[static 9], struct wlr_renderer *renderer) { pixman_region32_t damage; pixman_region32_init(&damage); pixman_region32_union_rect(&damage, &damage, box->x, box->y, box->width, @@ -72,7 +69,7 @@ render_texture(struct wlr_output *wlr_output, pixman_region32_t *output_damage, int nrects; pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); for(int i = 0; i < nrects; i++) { - scissor_output(wlr_output, &rects[i]); + scissor_output(wlr_output, &rects[i], renderer); wlr_render_texture_with_matrix(renderer, texture, matrix, 1.0F); } @@ -109,7 +106,8 @@ render_surface_iterator(struct cg_output *output, struct wlr_surface *surface, box->height = box->height > data->tile_height ? data->tile_height : box->height; } - render_texture(wlr_output, output_damage, texture, box, matrix); + render_texture(wlr_output, output_damage, texture, box, matrix, + output->server->renderer); } static void @@ -179,8 +177,7 @@ output_render(struct cg_output *output, pixman_region32_t *damage) { struct cg_server *server = output->server; struct wlr_output *wlr_output = output->wlr_output; - struct wlr_renderer *renderer = - wlr_backend_get_renderer(wlr_output->backend); + struct wlr_renderer *renderer = output->server->renderer; if(!renderer) { wlr_log(WLR_DEBUG, "Expected the output backend to have a renderer"); return; @@ -202,7 +199,7 @@ output_render(struct cg_output *output, pixman_region32_t *damage) { int nrects; pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); for(int i = 0; i < nrects; i++) { - scissor_output(wlr_output, &rects[i]); + scissor_output(wlr_output, &rects[i], renderer); wlr_renderer_clear(renderer, server->bg_color); } @@ -238,7 +235,7 @@ output_render(struct cg_output *output, pixman_region32_t *damage) { WL_OUTPUT_TRANSFORM_NORMAL, 0.0F, wlr_output->transform_matrix); render_texture(output->wlr_output, damage, message->message, - message->position, matrix); + message->position, matrix, renderer); } render_drag_icons(output, damage, &server->seat->drag_icons); diff --git a/server.c b/server.c index e5b6137..e554a3c 100644 --- a/server.c +++ b/server.c @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include #include "input_manager.h" #include "output.h" diff --git a/server.h b/server.h index 9ee21e1..092f7bf 100644 --- a/server.h +++ b/server.h @@ -22,6 +22,8 @@ struct cg_server { struct cg_seat *seat; struct cg_input_manager *input; struct wlr_backend *backend; + struct wlr_renderer *renderer; + struct wlr_allocator *allocator; struct wlr_idle *idle; struct wlr_idle_inhibit_manager_v1 *idle_inhibit_v1; struct wl_listener new_idle_inhibitor_v1; diff --git a/signatures/1.8.1.sig b/signatures/1.8.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..ecd7a2566e766615ecc9c10e737a02ac53bfdfae GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%4AyYyb)g5b{@R z(`FTGx!T(h0H){{?qPG=ZpU$mlpWat9^EbI{c8Lyy;kt1*rm4`Zn-JdM*sf#Fi(%s zPDmIpoyiay;`|OpiqTRlr;+8wBa}3SO8i75FYA;Yv7K+zvGnd{dMA$AeU1kS*z!7I zzR4+K>}FuDI`$qP<(@8+d}cU=>Sfo6PU6J9)4CN$b)+);f3gf0KQJKEAT3wWwjBfifp5G6cfrxDu zeigvv$zH8E2x=;*YN|pzK=FKpfazQ)j;mV+@d{(Er(>aBgj7qzHoI%A41;tdX)lGG z@T{lLmWF;b$!WV=DG+{(Ds+@a((i>)PgEd=C#;l3%oC(|1}1p&cgQ7gTYrJbvb3pr zwd*U^2n-gn=2x#p?!43FS=oznOQIq=1K*lP5_+2&R9TiniNfopPck`EQ1X|To;KM^ z;4%v;gdas5G5wI>{Gv&q{nVhf#|Bu1Q=tD9?K(7y&S!3BrUwZ(RN1u_(xrAuUs4>m z7&gKOJ|^7+8)ACXIIcGymF{E5h>ReJ}Q!NQlav`zPR` zt{A@OUb0ec*j}*6kA3S-L;m+WSTDONpoFQ8-6`35$eYA*GQJEM60Wwi`us@?n#+x} EkZ=JPJOBUy literal 0 HcmV?d00001 diff --git a/signatures/1.8.2-cagebreak-config.5.sig b/signatures/1.8.2-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..ee831f34180a3a1a6e550daa8af0771ea5b7043d GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%5LgtpExM5b{@R z(`FTGxgfO=0ItNOUOYhumTMlu%Hu1cO*sO@H7RNJ9K5<%$u6D_`7J(o%ztq0pi0^6 zpn8wU3aWTLvC9h_mRaeoa#FegPZg%6{ppB8GjHXnL>6)*YM@7Xh2~8OplT6&-^m%; zg-|wDJs+S;I>9p}sfE!Li-VP4j)9rtc{d4bj4zod0`YP;26}w}i(9bGA|-Y>?E^9I z1h`lFIsmZWOnd}nHbiNR5A56(6Ny;WIQJO`lDb%z`(ZQM zw3u=hw*-(UA(iX;G$apGwI!YID$ioCWY=YoO)kA82!NeVlkl z`OD|sYV?}dzieXJ3p>14<9U!#)@DW|xo)i|+YLT&-@2bNP4K~qETar-@un9RD=QceT^G~3bkaAy@?>61aiT(U?5 zuY-|>^3l=eo%PtI5ZS^OWX0N9-$G)r%x9FP+PSMa?8Zy+*Th91ca{RC*6JNzL>^^! zkQOpJd#O4;%2aaa>XLI>i9kArPQaF^Zf1z-U8)aSg*M#2j#Vb`3CA}nCd%RcX-?0W Embi`%nE(I) literal 0 HcmV?d00001 diff --git a/signatures/1.8.2-cagebreak.1.sig b/signatures/1.8.2-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..e4133eb28d3b10e4f566ea58267ec02a7b7976dd GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%5LgssIWJ5b{@R z(`FTGxq+Dv{yDkmKMvV5FYPhA3d4w~)7M2!E0{DSNr!&NBv`?VAVXx0`;nkfXnCD< zjP2vj+wk@J8{uuj&;K`qx$}b z*-(ypN7lV1=)E%wFsYt4jaE$!J261^B~&U>-drJ!e!7|u@O@57V^1sEfiYzX@zDgO z%1aR3ywYw381^h4JdeijcX4T(;>Gc0sa8m3^SJOK2L;?Ag5UpD_37S*+Qi-2%dzK{ zXHx>;@34rO^HNgp`K5~c#7};kv!nNhIq*Q22kUCrRw)aJ#(Ms@00oP9PK03M)6vqA zR9hiJi!0e8UUJ@jozus1(vtULdvjWFl&Gv{zz*fLNWK6bUT!YP&Oo91jmC;QG)9yP z$Hj7s)ss}I{W&dq9e@vfUaXV~L5nv}W^c6KbE^;^aRrBbToegKrg*TJKgjy<)L9@`&;8xUKtaLN1dkGQ=I@yUw|_-Z9o$sW E*TQlYN&o-= literal 0 HcmV?d00001 diff --git a/signatures/1.8.2.sig b/signatures/1.8.2.sig index ecd7a2566e766615ecc9c10e737a02ac53bfdfae..1aab7aa3e15f2e0d059983a0a83cb58f7cd94f70 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY&=KrT_{F5b{@R(`FTGx#)Bc|6qyg(@_)X-VO;4oH)lC-!1zL ztHF6NC?g3_y1#xJvDN>t4sIdQZ1dh*xOcYCpyBO$2&yGw39yS9g5I&=TCPPJ{@=#* zdKHwc>aSS1sQENv0{MIO|2Ana3kNmtjT{qHGicfMUf0E47k^K?iF2bFJM#vnv7Xxn z#e3xuGU`^-V|r|C!uBT60+8qrz9$6G4UsA=M?Kk;#r_stB_K(^)emvrm-8K^wr_Rg zf@@bC4k~WoQ-A5C6VmRT?A>vcY>S%puddg)AM@rZ%(R%wyPU3w%4!B84Aw)drM2v# zlV=s6S-#0l?0<0>0~QlML+{HHSP5kMt;+sLO92P%cOrO%=GPUPeyXnMYS}%_Q`;z6 zlCY|iSl1&UO0v9QVH&%a5qJ5=#14u0(eHVvSplw^;R4n~`+Lw0Quh2BkbDsmxZPwKh=Kufz delta 542 zcmV+(0^$9(1hxc_BY%#cYyb)g5b{@R(`FTGx!T(h0H){{?qPG=ZpU$mlpWat9^EbI z{c8Lyy;kt1*rm4`Zn-JdM*sf#Fi(%sPDmIpoyiay;`|OpiqTRlr;+8wBa}3SO8i75 zFYA;Yv7K+zvGnd{dMA$AeU1kS*z!7IzR4+K>}FuDI`$qP<$sD2}UJ z2Js4GuBT(6UVnsCOT#w1Ype`|bR%gmg`DuLr_Yv#el*ExyIUy`ev2w}lt$9;g;7sb zAciNblts)Fq<97>)8tv%i*ie%B02-# znnn_On;KMEmO_cb>!nXJIa5&bmzSP4*-GFt3o3*kMSmPI{gB}NqDi3r)S$J;23Unt zp#K%^Iy8#TXKrSu2MIS+*|iqZrFKbQQXID!Hq)H!tUa-iIed|s`{`WgrFS{wA ggsG0*DHqv!$eYA*GQJEM60Wwi`us@?n#+x}kVpj(MgRZ+ diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index ee831f34180a3a1a6e550daa8af0771ea5b7043d..2c2521097806777388e10ec2a54e39a8da910cda 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY*L~R{#nL5b{@R(`FTGxd?I(|8M?9naG+*bCfpF;j)QRc&QC* z44^0XGuM1wV0;XV_nkbr;Z1hmLeNu?DvE#8%jjLgk^Av|5b2NPY865%o{N)CfoW^Hbdl&3ufxQ z&l=~u^(IV~!$PQ186XTUCCu#c`fkq^-@!Q0td6xDfg*Nf_A6kCBR%j(gJ4d=PGq&4 zMW99jl1q=bTz}PvQ;1eKTpIMHJYjY>vz^Lt7?-5#pD>c-J4HxH=+OIphsf4?&#?R? zd{LU^qbY}Y4=f}S`L&@sMH>$QR}F3pldpr2O>f$#$>WHcKplgGqNx1%Fj3Nip z(nt@z2Vf5!nh<4y8TMl74V|m#)w5I7aU^n<&{!-gNPk)ErE|(K8P3v$^Yd|be>d24 z97hOAjI+T_vO^IS@R3RQnHkkw4>JOUexePAF38^Vowey65H2skb`;6`;ItU^uZmdD zg)@qVf+x^$PZ1J;s{SGau~~vJN}V?J3W=gVM8J`KSZjql&8CxqEI25bl6)*YM@7Xh2~8OplT6&-^m%;g-|wDJs+S;I>9p}segsh6pMqEUygy9;(0d- zYm6_MCj#+uHwJor0E=6&%_1dsIPC*5?*zD4`Z@rx-%NZ2WHv-;j1TPG6%&bA)j0PV z2a>)&bY7%^t}6zg9dX?F%||@kIA6;iidBk0hF~V_r8D2l4lffhr7}3w>zi&*7(bBl z`%mnhMG~8v4}Yj|^n#dGR7){#zuo&`GupJ6au&A)kS8IP>-sb#4~!y2Yea-&>u2Z{ zMa=2nt~b8&r~ct`om=iO@bn%BQ6|%(~Q4P6Pim+tK!LXBA)RlR?5mI9{M>K$H09%Xir7BV_}sX9K&RC4F)l5<*#Ksts_z?P_P gW{BxssuvGhg*M#2j#Vb`3CA}nCd%RcX-?0WmTW8sqW}N^ diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index e4133eb28d3b10e4f566ea58267ec02a7b7976dd..e5280a3e9428d3ac0a136e52a68348cebda750b5 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY*L~Q~(MI5b{@R(`FTGxvGy3|3yA!!;*cYZs2L&&Zx2#rsczC zz-Ab3%~DnXeWM}a3u$4`d;#iudf8UE85-YQht@sU;YgqpRURr~pHvujl#ABOh9n4U zG_sWImrSVTCXQ7YJts^8^#Ue7nC!bYxhUh4^E9aVcmj8u`+pcJ=n`IHuh9Oz&h$w; zM16{%ujQJS^rh49zY5kiv6U5?L&Tq=YUep*tlfmdfuE9Z(TpL2B>CmPMt-56oREQt zmUK1d-L>MF8fG8rc6lWm8x+`b`zCYY$X_aUXUd5FxRb``mT)N?>~(wwLxBKGyg#O2 z8VIsoN-eLJ{eRn!l-6?Fz^xLbLZB)G5{G6)@~(Ou2N6*M7t!vmE}!068OcVHc;cx6 zkf;PW5O-TU-gVr?yiN8LnAEGytGd0sO%NW!A=ZGY_HwvJ^7ED6CtC;2j4aD@^6Zd< zXfuDs@0x3ufxvSyo12D=hc!1+)7%|^z8JPY%^>rfYJbSS1>f1h{$KG;y6*rmet_Dy zom-SBVf+|*K#~^BNymM)a=v=*n6h)?NGVi!r_-!a=)dO~{B2|hWJMd8Vb2$`U~>yR zUHm~Cjeq-n#JwP`WK#pRP5vQ`KH9b?mim*QY;di@1CdZ)I&gN6WN;@Nf{|aIo7s!< g5NQ{_5f@QqCSQgns?}M>HQ4u9R=+=4;#!9ykFrV+)&Kwi delta 542 zcmV+(0^$9(1hxc_BY&=KssIWJ5b{@R(`FTGxq+Dv{yDkmKMvV5FYPhA3d4w~)7M2! zE0{DSNr!&NBv`?VAVXx0`;nkfXnCD{TJQGKtaLN1dkGQ=I@yUw|_-Z9o$sW*OjjhQ~&?~ diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 1aab7aa3e15f2e0d059983a0a83cb58f7cd94f70..6ac0f6398b4e28fed3e1542b7801fd3dfc04345d 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY*L~QUD4G5b{@R(`FTGxsHzy{Si!g6bYArk3RmZG~KkLvUktt zH*dM%C+&*7?wlitog&*iAaZf%mgP-Mu^0!#-NEjWC`6f>bKMWjFY1yZ>)sx&X6s}z&rte!(S_A6Hg%LFiJ>fmqU@fS}l z4?muOCmWKLvVUO?k#sgPS(VWi4)`LC2mtUA^sq8sD}(-~h&}f3{5ImG6);`9C1HgT zV#)*7DSDA;=m)ZhvY+voV7Teeis(#|P(rTfvb<0R_JYuk337-%XeXwuvY&C zY{g2S0>vD$DD?G1lHaa6#2MfyN#LoMiGt g%Bbt4sIdQZ1dh*xOcYCpyBO$2&yGw39yS9g5I&=TCPPJ{@=#* zdKHwc>aSS1sQENv0{MIO|2Ana3kNmtjT{qHGicfMUf0E47k^K?iF2bFJM#vnv7Xxn z#e3xuGU`^-V|r|C!uBT60+8qrz9$6G4UsA=M?Kk;#r_stB_K(^)emvrm-8K^wr_Rg zf@@bC4k~WoQ-A5C6VmRT?A>vcY>S%puddg)AM@rZ%(R%wyPU3w%4!B84Aw)drM2v# zlV=s6S-#0l?0<0>0~QlML+{HHSP5kMt;+sLO92P%cOrO%=GPUPeyXnMYS}%_Q`;z6 zlCY|iSl1&UO0v9QVH&%a5qJ5=#14u0(eHVvSplw^;R4n~`+Lw0Quh2BkbDsmxZPwKh=Kufz diff --git a/util.c b/util.c index 1e7fa7c..4c26b74 100644 --- a/util.c +++ b/util.c @@ -7,7 +7,7 @@ * See the LICENSE file accompanying this file. */ -#include +#include #include "util.h" #include diff --git a/view.c b/view.c index 09fc463..0bbd03b 100644 --- a/view.c +++ b/view.c @@ -12,11 +12,11 @@ #include #include #include -#include #include #include #include #include +#include #include "output.h" #include "seat.h" @@ -311,13 +311,13 @@ view_map(struct cg_view *view, struct wlr_surface *surface, view->wlr_surface = surface; struct wlr_subsurface *subsurface; - wl_list_for_each(subsurface, &view->wlr_surface->subsurfaces_above, - parent_link) { + wl_list_for_each(subsurface, &view->wlr_surface->current.subsurfaces_above, + current.link) { subsurface_create(NULL, view, subsurface); } - wl_list_for_each(subsurface, &view->wlr_surface->subsurfaces_below, - parent_link) { + wl_list_for_each(subsurface, &view->wlr_surface->current.subsurfaces_below, + current.link) { subsurface_create(NULL, view, subsurface); } diff --git a/workspace.h b/workspace.h index a5da674..0e8f91f 100644 --- a/workspace.h +++ b/workspace.h @@ -1,7 +1,7 @@ #ifndef CG_WORKSPACE_H #define CG_WORKSPACE_H -#include +#include struct cg_output; struct cg_server; diff --git a/xdg_shell.c b/xdg_shell.c index 7972b5f..6b9b074 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -11,10 +11,10 @@ #include #include -#include #include #include #include +#include #include #include diff --git a/xwayland.c b/xwayland.c index daf3658..f2285e5 100644 --- a/xwayland.c +++ b/xwayland.c @@ -10,9 +10,9 @@ #include #include #include -#include #include #include +#include #include #include From 4db22aafc379bb51132db8c0b3b0baad21d58b5e Mon Sep 17 00:00:00 2001 From: project-repo Date: Thu, 21 Apr 2022 21:12:57 +0200 Subject: [PATCH 07/19] Release 1.9.0 - Add message functionality (as per Issue 29 in Bugs.md) - message - configure_message - Add (as per Issue 30 in Bugs.md) - movetoprevscreen - movetoscreen - screen - additional output functionality for monitor numbering - Improve configuration documentation - Fix Issue 31 in Bugs.md (word omission) - Improve README.md and split off some files - Add SECURITY.md - Add Hashes.md (hashes of cagebreak binaries and man pages if built reproducably) - Add Changelog.md (changelog for major and minor releases but not patches) - Add FAQ.md (updated information from the former wiki) - Depreciate wiki - Fix Issue 32 in Bugs.md - Improve release checklist to partially prevent the above issue in the future - Fix Issue 33 in Bugs.md - Fix Issue 34 in Bugs.md - Manage gpg keys - Add new cagebreak gpg signing keys - Add new cagebreak email contact gpg key - Add new project-repo AUR gpg key (relevant for cagebreak-pkgbuild) --- Bugs.md | 264 ++++++++++++++ Changelog.md | 66 ++++ FAQ.md | 37 ++ Hashes.md | 211 +++++++++++ README.md | 333 +++--------------- SECURITY.md | 91 +++++ cagebreak.c | 10 - examples/config | 17 + keybinding.c | 32 +- keybinding.h | 24 +- keys/cagebreak@project-repo.co.pub | 193 ++++------ ...=> cagebreak@project-repo.co.pub-legacy-1} | 0 keys/cagebreak@project-repo.co.pub-legacy-2 | 123 +++++++ ...gebreak_signing_key_10@project-repo.co.pub | 76 ++++ ...agebreak_signing_key_9@project-repo.co.pub | 64 ++++ man/cagebreak-config.5.md | 298 ++++++++++------ man/cagebreak.1.md | 14 +- meson.build | 24 +- message.h | 7 + output.c | 2 + output.h | 8 + parse.c | 157 ++++++++- seat.c | 1 - signatures/1.8.3-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.8.3-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.8.3.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes xwayland.c | 3 + 30 files changed, 1493 insertions(+), 562 deletions(-) create mode 100644 Changelog.md create mode 100644 FAQ.md create mode 100644 Hashes.md create mode 100644 SECURITY.md rename keys/{cagebreak@project-repo.co.pub-legacy => cagebreak@project-repo.co.pub-legacy-1} (100%) create mode 100644 keys/cagebreak@project-repo.co.pub-legacy-2 create mode 100644 keys/cagebreak_signing_key_10@project-repo.co.pub create mode 100644 keys/cagebreak_signing_key_9@project-repo.co.pub create mode 100644 signatures/1.8.3-cagebreak-config.5.sig create mode 100644 signatures/1.8.3-cagebreak.1.sig create mode 100644 signatures/1.8.3.sig diff --git a/Bugs.md b/Bugs.md index 328450d..2c909fe 100644 --- a/Bugs.md +++ b/Bugs.md @@ -364,3 +364,267 @@ When I type in anything, the text is refreshed and becomes visible only followin ``` Cagebreak had an error with damage tracking. + +### Issue 29 + + * github issue number: #19 + * Fixed: 1.9.0 + +bda65hp: +``` +Hi, +Is there a way to easily change de font? "monospace 10" are too small for my eyes. I've changed them in message.c but can you add a configuration option, please? +Same for the display time of these window. They sometimes disappear too fast (mainly time). +May be a config for the background and foreground color of the message window too? + +cagebreak is great :) +``` + +project-repo: +``` +No, there is currently no easy way to change the font size, background or display +time of the message. + +Adding these ideas as a command is a good idea though. + +To summarize, the release pertaining to #19 will presumably introduce a +command for configuring the cagebreak messages. This command will be +able to set the following: + + * [ ] Font size + * [ ] Font colour + * [ ] Background colour + * [ ] Display time of message + +Another, related, idea would be to have an interface for sending +arbitrary messages over the socket which are then displayed by +cagebreak. This may also be added to the above features. + +We're glad to hear that you enjoy cagebreak! Thank you for helping to +make it even greater. + +cheers +project-repo +``` + +bda65hp: +``` +Awesome :) +Displaying time in locale format (or configurable) will be great too ;) +``` + +project-repo: +``` +Yes, once it is possible to send arbitrary messages via cagebreak over +the socket it will be possible to have the date be displayed however you +like! +cheers +project-repo +``` + +project-repo: +``` +We pushed some code to development implementing this in 348925e (configuration) and f12a161 (message command). Sorry for not writing this much sooner. However, at least it will be part of the upcoming release. + +cheers +project-repo +``` + +### Issue 30 + + * github issue number: #11 + * Fixed: 1.9.0 + +kinleyd: +``` +In my first post I forgot to thank you for cagebreak. I've been evaluating compositors for my needs and have been through kiwmi, japokwm, wayfire, sway and cagebreak. So far I like cagebreak most of all. + +Back to my question: + +You currently support 'movetonextscreen' but there is no equivalent movetoprevscreen. +For multiple 3 to 4 screen configurations the second command would be useful. + +Also, is it not possible to move to a screen directly, like 'movetoscreen 3'? + +The same thing with prevscreen and nextscreen: something like 'focusscreen 3', if it were possible, would be useful. +``` + +project-repo: +``` +Thank you! It's great to hear that cagebreak seems to suit your needs. + +About your question, yes, that absolutely makes sense. The reason this +wasn't implemented earlier is that no-one has needed it up to now, but +seeing as there now appears to be a use-case, we can definitely +implement these features. In future releases, cagebreak will then most +likely support movetoprevscreen and movetoscreen (as these are +distinct functionalities). + +The only issue I see at this point is that the numbering of screens is +not directly canonical. To resolve this, I suggest that per default, +screens are numbered according to the order in which they were added +along with an additional configuration option to specify numbering (this +would most likely be an additional option for the already existent +output command). Does that seem fine to you? +cheers, +project-repo +``` + +kinleyd: +``` +Yes, that would be perfect. Thank you! +``` + +kinleyd: +``` +May I suggest we also have 'screen ' like we have 'workspace '. +``` + +project-repo: +``` +Thank you for this suggestion. This will be implemented in the release +where the rest of this issue is resolved (probably the next one). + +To summarize, presumably the release pertaining to #11 will include: + + * [ ] movetoprevscreen as a command symmetric to movetonextscreen + * [ ] movetoscreen as a command similar to movetoworkspace + * [ ] screen as a command similar to workspace + * [ ] additional output functionality for monitor numbering (of + course backwards-compatible, such that valid configs remain + valid) + +If anything changes with regard to this draft, we will post it here so +you can let us know what you think. + +cheers, +project-repo +``` + +kinleyd: +``` +Super - I greatly look forward to their addition, and thank you for your responsiveness! +``` + +project-repo: +``` +Everything mentioned on our last comment has now been implemented on the +development branch. (More specifically in 851a2f8, +though documentation was added later.) + +The simple commands work as proposed in our previous comment. +The output command has a new feature called prio now, which you can call as follows: + +output prio + +All outputs, regardless of configuration are added once they request to be added +and have a default priority of -1. Using prio, you can set priorities +greater than or equal to 1 for specific outputs and hence order your outputs +as you wish. Note that cagebreak -s might be useful while fiddling around +with this. + +If you like, you can check it out on development and compile it for yourself. +If you're up to it we would be glad to know what you think about it, +especially when output prio is applied to your multi-screen setup and +regarding the readability of the cagebreak-config man page description of +output prio. + +Please note that this is not a release yet and the development branch +might undergo changes. + +cheers +project-repo +``` + +kinleyd: +``` +I took the development branch for a swirl, and it looks good. Thank you! + +Everything works as you had set out: screen, movetoscreen, movetoprevscreen and output screen prio all work as expected. The default screen position now reflects the prio settings and that's great. + +I took a look at the updates to the man page as well and it looks quite clear. + +So hey, thank you for the great work! I look forward to the incorporation of the new features in the master branch when it is ready. + +Happy holidays and a happy new year! +``` + +### Issue 31 + + * github issue number: #25 + * Fixed: 1.9.0 + +``` +The configuration man page for the input send events setting is missing the events word: + +diff --git man/cagebreak-config.5.md man/cagebreak-config.5.md +index 4eea4c5..c618314 100644 +--- man/cagebreak-config.5.md ++++ man/cagebreak-config.5.md +@@ -123,7 +123,7 @@ by prepending a line with the # symbol. + *dwt enabled|disabled* + Enables or disables disable-while-typing for the specified input device. + + - *enabled|disabled|disabled_on_external_mouse* + - + *events enabled|disabled|disabled_on_external_mouse* + Enables or disables send_events for specified input device. Disabling + send_events disables the input device. +Slightly off topic: I was hoping to use this setting to hide the mouse cursor, but it doesn't work. My embedded system must expose a pointer device even though none is connected, altough I can only infer that much because the system is very bare bones and I can't check. Is there a way to do that? +``` + +The word was omitted before 1.9.0. Mouse hiding was relegated to a new issue (#26). + +### Issue 32 + + * github issue number: #24 + * Fixed: 1.9.0 + +``` +The wlr/xwayland.h include in output.c:32 is missing an #if CG_HAS_XWAYLAND guard, which breaks building without xwayland. +``` + +Cagebreak did not build without xwayland. This bug has been fixed and building +without xwayland has been added to the release checklist. + +### Issue 33 + + * github issue number: #23 + * Fixed: 1.9.0 + +``` +Similar to djpohly/dwl#177. Xwayland works fine elsewhere: cage, hikari, kwinft, labwc, phoc, river, sway, wayfire. +``` +$ cagebreak +[...] +00:00:00.085 [xwayland/server.c:92] Starting Xwayland on :0 +00:00:00.116 [render/swapchain.c:105] Allocating new swapchain buffer +00:00:00.118 [render/allocator/gbm.c:142] Allocated 1280x720 GBM buffer (format 0x34325258, modifier 0x100000000000004) +00:00:00.118 [render/gles2/renderer.c:143] Created GL FBO for buffer 1280x720 +00:00:00.160 [types/wlr_surface.c:748] New wlr_surface 0x880d81f80 (res 0x86f22d380) +00:00:00.165 [xwayland/server.c:243] waitpid for Xwayland fork failed: No child processes +(EE) failed to read Wayland events: Broken pipe +xterm: Xt error: Can't open display: :0 + +$ cc --version +FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe) +Target: x86_64-unknown-freebsd13.0 +Thread model: posix +InstalledDir: /usr/bin + +$ pkg info -x cagebreak wayland wlroots +cagebreak-1.8.3 +wayland-1.20.0 +wayland-protocols-1.25 +xwayland-devel-21.0.99.1.171 +wlroots-0.15.1 +``` +``` + +## Issue 34 + + * github issue number: N/A + * Fixed: 1.9.0 + +Cagebreak crashed when a touch device was removed due to a call to +`wl_list_remove` on a pointer which was never initialized. + diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 0000000..ff24285 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,66 @@ +# Changelog + +## Release 1.0.0 + +Adds basic tiling window manager functionality to cage. + +## Release 1.1.0 + +Unifies commands and actions. See Issue 4 in Bugs.md. + +## Release 1.2.0 + +Adds output configuration as described in the man pages. + +## Release 1.3.0 + +Adds IPC as described in the man pages. + +## Release 1.4.0 + +Adds close command for windows as described in the man pages. + +## Release 1.5.0 + +Adds options to disable or enable outputs. See Issue 22 in Bugs.md and Issue #2 on github. + +## Release 1.6.0 + +Adds support for non-build dependencies and an option for builds without pandoc. + +## Release 1.7.0 + +Improves window ordering. + +## Release 1.8.0 + +Adds libinput configuration and virtual keyboard and pointer support. + +## Release 1.9.0 + +- Add message functionality (as per Issue 29 in Bugs.md) + - message + - configure_message +- Add (as per Issue 30 in Bugs.md) + - movetoprevscreen + - movetoscreen + - screen + - additional output functionality for monitor numbering +- Improve configuration documentation + - Fix Issue 31 in Bugs.md (word omission) +- Improve README.md and split off some files + - Add SECURITY.md + - Add Hashes.md (hashes of cagebreak binaries and man pages if built reproducably) + - Add Changelog.md (changelog for major and minor releases but not patches) + - Add FAQ.md (updated information from the former wiki) +- Depreciate wiki +- Fix Issue 32 in Bugs.md + - Improve release checklist to partially prevent the above issue + in the future +- Fix Issue 33 in Bugs.md +- Fix Issue 34 in Bugs.md +- Manage gpg keys + - Add new cagebreak gpg signing keys + - Add new cagebreak email contact gpg key + - Add new project-repo AUR gpg key (relevant for cagebreak-pkgbuild) + diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..1077a69 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,37 @@ +# Frequently Asked Questions + +## How do I do a particular thing with cagebreak? + + * Check the man pages + * [cagebreak config](man/cagebreak-config.5.md) (probably where you find the answer) + * [cagebreak](man/cagebreak.1.md) (command line options etc.) + * Check the rest of this FAQ + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) or otherwise get in touch with the development team (See section Email Contact in [SECURITY.md](SECURITY.md)). + +Note that the feature set of cagebreak is intentionally limited. + +## How do I remap Caps Lock? + +Remapping Caps Lock globally seems to be the best option. +Follow instructions [here](https://wiki.archlinux.org/title/Linux_console/Keyboard_configuration) to achieve this (should be roughly +distribution-agnostic). + +## How do I get firefox to run under wayland? + +Set the following environment variables + + * `MOZ_USE_WAYLAND=1` + * `GDK_BACKEND=wayland` + +to activate wayland support for firefox. + +## Which further resources are available? + + * [Arch Linux Wiki entry for Cagebreak](https://wiki.archlinux.org/title/Cagebreak) + * [Sway Wiki](https://github.com/swaywm/sway/wiki) + * [Cage Wiki](https://github.com/Hjdskes/cage/wiki) + +## This FAQ did not help me. What now? + + * Consider [opening an issue](https://github.com/project-repo/cagebreak/issues/new) on github or getting in touch with the + development team (See section Email Contact in [SECURITY.md](SECURITY.md)). diff --git a/Hashes.md b/Hashes.md new file mode 100644 index 0000000..abffe85 --- /dev/null +++ b/Hashes.md @@ -0,0 +1,211 @@ +# Hashes + +1.9.0 cagebreak + + * sha 256: 91096b4c558970666c5ef1ebd5c16301fbb40b52b34a73589f18a14c48edf5c1 + * sha 512: 52ec9c6996377d01d35df87ea5480a33c93cd7c62645f54523f3808fa9f84578f3a6201e969c6bdb5987e69b667be7edc8ce7067091c8413193c5e33cb434883 + +1.9.0 cagebreak.1 + + * sha 256: 431909f4c62157e57e789359a8458fc650b5f266b2fccc6fc5c0e501f8c879d3 + * sha 512: f7523288ef3ca406507ee996e189fd339623fa465585973ac769cbea7948399545e8886fe585c7ddd70ca89465c81a188137dcea5b7273353966ea882d9806bd + +1.9.0 cagebreak-config.5 + + * sha 256: 4433d8a160e48834fefb4cdd54fcec1f6038e21801c7a1dffb041b5eb238a2cc + * sha 512: af44aa42fe05b50a773420000c383fac837e45ead248876bb617c53e44e36d09a88ae26df80c1c9ffd6cf7c4dac72acb02d369888a79fed35114ed7e88fbe159 + +1.8.2 cagebreak + + * sha 256: f4d275d48ba3d999969f8cb3c8142d27aa8e8d362106ee7575e4b13c02173b2a + * sha 512: 72b11cb966b0978133b9848c2a7f57574c599c7fe895ca9f1cba16930216e1ac8aeae86d976593fc01b15e94ecc1430666f474654cf2fe41eda8c1181bf03f3d + +1.8.2 cagebreak.1 + + * sha 256: 51ee97a7c0b86268cf7622f84f7b1813df8e4a7838c00aae412a611d3693e87a + * sha 512: 5ce826afbee9cbc1129f37463f5b6d4dfc060583f6f7816dd5039b18d66a2b7e22f7293a4aa03acc4e6c690886d0297fef5b9f85d720a4467becfd833b59a160 + +1.8.2 cagebreak-config.5 + + * sha 256: 7c780ba85211ba40c7535b3f10f12312f9edeaa10030228ba21a96724469a325 + * sha 512: 9a56ba16c2aed6f17d4098e54900a5d25602f986e3606dd6ed26563c1920c66404b210dbca9f41bfcc3284bf5a42b750263bcaa2317320f8725e8f9c66e8b893 + +1.8.1 cagebreak + + * sha 256: e3247281d21525413790e3feceae129d9b0559497615d3fdd64ec2fc4ab9ab3d + * sha 512: 8c7c2820be9d7c74e3f9e239c7da740ff41d7f11cd40953dbfbc59c04942077f08625f6d7ec37e6037fd9c4b6950fc4f9af23478080665fdda867c65e0a187bf + +1.8.1 cagebreak.1 + + * sha 256: 96997afdfde9c2719533799aa48c8f036610bb04bc719130d2ab3a3617b072ee + * sha 512: 0831f5d2e3b4f23fd5775df2b7f6486099d64962567222a8fb49e6a40e7d29ed36a7c2c16201bbdcc985ac74f1d0e034b530afbe0ce58d6a0c53d467cff0a6a0 + +1.8.1 cagebreak-config.5 + + * sha 256: bd0e2eb02ba28ec1c8f2bd0fd5cd4c84af24b615fcc477414e49e68e1963cf1b + * sha 512: 7135a2b371294bfdc759a393c13fa0225f1789dba94bb09e96ae689796215b8030280d6cc09c9d1fe139f000f5a4748efd16bb3e5d3b9fcc74a19259802f20ef + +1.8.0 cagebreak + + * sha 256: ac84aa4a08c311da79ca29d92eef4254cb625674b255dbb75621ee6b171a1d79 + * sha 512: c047bb1986fd1d444547e4d64aa7ef9138b3d30327ac3ad9b4c6976e8df6638bae07c39293b5bc9c20e959c0a22b0e40eb2b23b4766d9a5531377ff954b16229 + +1.8.0 cagebreak.1 + + * sha 256: 4de43de7bde67d6d806d206dffc34389f0b5c3ba648bfef673b7bc0adeb29202 + * sha 512: 72aac9a2e9a47f2f85949222d5944dc293332a616e3b961c625fe876172f66638038057c30aa18904d6d969451f468b4fe45e918c0b204cf6952d58ea4c69c33 + +1.8.0 cagebreak-config.5 + + * sha 256: 678aadde06b5ff6bfbd9bc9460423210f9599bcaa0e50c2eae076dc6d6852781 + * sha 512: 72056018fc1c559f26bd7e007b3f1db7d478cec7ec9337620e03a1e3d06910e244a52e8f655ea4f5d73669ffe064bbd23506005d9a6c06764b0f820d7a1df43f + +1.7.4 cagebreak + + * sha 256: c7442db906239b13f8d09e91cbe01f9e47b2a2c75bbb4b52adefd15dfbfa820f + * sha 512: 9c36ce706f31e1b8afacd8f9cd216c460d66030e0b2736a3dd929902b0d5fc52c5e69dbf6787205b8c495d960e00b6e7f633da86ab6e31613f1b4a9fd47c9f0e + +1.7.4 cagebreak.1 + + * sha 256: 3dacc521e5e9b963cceeefeed6a10104c7c415d86826a72788aba5b33ce320f1 + * sha 512: 0a4c4fbff09dd403fed61056ae3211ad2b4370b4e9ed07806fc22624e5312b4a25e469dc0eef1ca4556cbb8efabb0127e7519df79852e110faa98fb17ca377de + +1.7.4 cagebreak-config.5 + + * sha 256: ed22fed1818172f31d3fb3efbe5e66b49f135cb2367b1c85209fd880ff7532ab + * sha 512: cc634c63962ae50b4de20a3aad8ca0970175b53156690d69e6a69fd8f370ad20d84db783cc7e94c61d4d4d89f1205d43622690e58afba549ed57ddad009e3bac + +1.7.3 cagebreak + + * sha 256: 8adb4911d9603fec5b8eb4f67a09be95b8f0b37e50d4ab579191da78df18f70b + * sha 512: eddaecd7b577b9fe77b1ed4d341074f7f860967568392d0479543ea8860b4289df3eb5645885e18e35260b14843663ae50f98103f8016e857237a397632322a6 + +1.7.3 cagebreak.1 + + * sha 256: bcc623e42c86ab65bc2f8cb7e4377ca0d816ddc281527b7caeded62753e943b8 + * sha 512: b4290e1040bd6a299d478ad6b695de75cf030d0d274340b43d3ed4382cf6877f824cd4ed9d7020bfb55afe276c62de7fc07c3fbee6f6485c6440a024115afe12 + +1.7.3 cagebreak-config.5 + + * sha 256: b9789b6abd473e9afb33d4e2c7822f7d8f3c10e9eb3fb70c47b713f6331c626a + * sha 512: c49e01cfc4a4ed272f054bea8f2845f0e3f1609cf85d1a0ce14c1b67dc207df153b11bc20ceef09c855d467f0e013e54623ce9f70c217c4278607fc54d0e3206 + +1.7.2 cagebreak + + * sha 256: 40f4642e8e8caee338055079b046f6e0b790c87226ee307b27a64fcb2a6c6472 + * sha 512: 22c5f1986ca4262a7c08a6c03cffe36eaedd8c3c5e27e12baf12a90f94aea088ac93ee107770f162fc70148be687f6394b8fd64ad3fe14414bdf63b55b33798e + +1.7.2 cagebreak.1 + + * sha 256: 3253e592c40c78fd3733c761163acc2efaaf5865627cf51fd33cc0bc5d9cc6e7 + * sha 512: 901305e166c10aa7e4a26b721a69e0ba4779f4f8ee690551438ceadae65929f13949457872b9397dd46c5b7bad6a6f2638d6fd6df9bc5567c914c798cbf3e9a4 + +1.7.2 cagebreak-config.5 + + * sha 256: 148ec4d80dc9a86485fe77f8daf1f7fa4cb3d1b6aaa709bb012005583779e1f7 + * sha 512: d5732572e47dd07078ac2f6d589522e6007188fc05ac79520c93442212d5c0341459f135191b88c608a75b2f56c2de4065566bd869fbc24e475936d32a54a7f8 + +1.7.1 cagebreak + + * sha 256: 5a40797e016a2fa32b5bb70a056b35c482bef09f1795bbaf0188dbadaf8197c3 + * sha 512: 2ef327b63ac4651f23517be8d5cb8fbec99bd889f52f8abfd62a09ca6e6c0060347ab8d60e4917d39edd36db34597a673239967533f14457733acb97f6c29a7f + +1.7.1 cagebreak.1 + + * sha 256: 0301f04254ae6e7ada7e22bbe7aee022ec0793fbce434a396868258e6f1ea4cf + * sha 512: f0c0c5de30be907e9ba5c9cfa0bca8cef3e94c0b5f52de9e2c3681c85aa957f75e92b5e26bb894c3a5e251295cfe7a1470653cc7dc05564d7d91c6eb43b7409a + +1.7.1 cagebreak-config.5 + + * sha 256: 6882330a77f3ff98ea642f47b4090b38d542abf0b7be3f226486c5614899efc6 + * sha 512: a572f97836e4ccc6d67aa21c7f4aaebe06adb066c70038b670ec1ef267e3750764cb53e96b8d7bc24c7f993f24c0cfabee183307b45006d049f7416559bcaca4 + +1.7.0 + + * sha 256: 5af11b84e61a82a1a276e8f91f6ebc6baafd2c98d22be3da1d01734cc9d55faa + * sha 512: 45474115fb4c28fe1ee91ad54706bfe521b6e70bd8ea619b94a3f50bae426891bf6a0387aa9b2f7f6d18349280c4e84973e4e433d50c090e5a764c64fa67795d + +1.6.0 + + * sha 256: aef473eae73454429afb158d66a7bd9aec75ef915845b7508de5448820357aa8 + * sha 512: 17889bc1af9f343598a5ee599b25e702987dd0bd905a9566874e8a0094c57168e413938624949fa214e6e382cbcf89d7342292b44012cd8e692947f6c01a960a + +1.5.1 + + * sha 256: 9c6df4b94c180f5657cb424383aa2bf3aca063c8e7b40af0497be1ef7bdb858a + * sha 512: 219f753347ae64a4dd593568797438742e9ddae380c729598d8eda863080a6ed4e5086d735fc348c48328bb795a5a5b57b0421be5dd45755744d895b24312627 + +1.5.0 + + * sha 256: 22010e2916493b0d7cfb08c2196f12589509ce11010a7107aed13ddbfd9709cc + * sha 512: 707d6cc01326ba32402f9fb402ff8aceaeaba63ca6ba2eb157e5a4c83123515a3a74da960813479db303eddc2e7f79f39b241dff05b89d47d72d5f1d20ca6d37 + +1.4.4 + + * sha 256: c6e08e19feb17f768e136cf02f5692ef121ff289763dc60ef8678103803d3307 + * sha 512: aebf27fa9c24f93dfd0b7c96536c253e2ea603d6746c40e8de2163e06367bc57ac4e22d6c07dd1e0963cce5b18b460d373e15b5c12a5a42ae6b70787971960c9 + +1.4.3 + + * sha 256: 5e29cbaf7c0c5ca74f71a5605bb3d6e302e051798401fee9a79419720b8d8e95 + * sha 512: 8004865f8603648d9ac9bb700f3ee040e6516c222ad3d783b34219c8fa3a7bdbba6abb74fe92c4d0bd4dbbce0ec4d08be12297a8bad5032baeb589eec557e24e + +1.4.2 + + * sha 256: 27efb9328cf9cab1f81e66627696baf8c7cc2c372339a2890f955b40f3a7c396 + * sha 512: afcdbbce0753aff4770a88ddbd7df5687a7de0c77de3a2d296f85a8b8e01813212be6a0b69548aadef58e0e7da19ffea71c4f3448572656d4b19ff7f2f2fb70a + +1.4.1 + + * sha 256: c3e0ccceaf1078b91071c40b0ccb7c4f8e53ae38b05ee6637f9f39f7f6ece2cb + * sha 512: fd77f39fc7a7e5376d8505a61d643ed4d8f4cfbbf38d70cf9ef6989645e8cc6cb9d4b1024d241dc689b6fd927a405c97b9c918b6994b8f9ab7406646f37b952d + +1.4.0 + + * sha 256: 14aa93d890c62cc763b3b546a51ad8560479d5e91fa9f949858ae6bc785e80be + * sha 512: 88f93b49792684c38553b65d2296a0e502a059814a0cfff30d05c89958870d6f66d67aac2074cfd307bad82b0d72d5c4944822a61a68f665dc161407db365fbc + +1.3.4 + + * sha 256: ea9f634b8f6e2b9f191745a25abff4969eb7ea19cb3186b79a6138904aedeb1c + * sha 512: 9094f9c92acbff8fd95d38e7458c5184804f8913fa8c405bc2b6a0a220fe478b06cfeadbae41bd5ef84bde8d5642c249df9dada953e39c25926aa650c30a5309 + +1.3.3 + + * sha 256: 801851ceb52afac333a1decdd236ddef55555f8b36f865e8b3a831975a496f0d + * sha 512: ce64dd56ab99bba0a83414fecc82d85322e1ca5ca3a2ca77bdc7055b2dd10fd5e20e3ff62809a696d1b04ff0046fed88e2d7538aa447099d7c2d7df8e627b2e0 + +1.3.2 + + * sha 256: 2cefab73b8d5902b30adb0dda1bd292af2ee808d232abcc4b2a2802d522d5232 + * sha 512: 3789efde2cb6f629c77738dd6c8638646b345d5272868aa9b244b2b19c53e6a0f5911d34744e3a9ff6253c73b2b11f6714f37ae86cc21d6979e0c8539315d659 + +1.3.1 + + * sha 256: 71be224cd99d20da4f039675ec5c48213dd14ef027b804501fa3241886b2b08b + * sha 512: d094b786e5a74b01699997a85747943e6de3544cc903dd1c5dba449c66bd925b6378de800d3734969dabf8a20c7004dc3402e3c59577db09ce107b68a1f7bd21 + +1.3.0 + + * sha 256: aecc5292f56f7250d777110cee1f11a92018a9eb2117d7d37cd51d7d3a5cbae0 + * sha 512: 1d2d220f44787a97359a32f305e33185f0369551e61a9d7066023bfa43de50849eba5bcbb0083d2dc563ac993b8d51dd733afa0adb2a823ef50ecfee5624bbc0 + +1.2.1 + + * sha 256: 803f7667dc4997062f9ec95afcdca0cac68c82a7cf057cef83fe1ccfee33b8bc + * sha 512: 4d6b7efea10d190a153f893123b1715f290f4b131b490f3d23f489e2dd8edbb886001282849aad9575ad2f40375bbbded59c1cb6157115fcc14dd6a2a061b103 + +1.2.0 + + * sha 256: b3c6135833001a0ef600ea9628cca11f4130a524ebe748929d8f7bad034f2bf0 + * sha 512: c044a086a9f65b0d27d05e2f12a20fe5d77386fc5682991c13a1894a84804bcd337c9167235869661d6e6581133521bd710ef2330066a5d2e2703d1630042f3f + +1.1.0 + + * sha 256: fc393e225c549f893b9e21e8b904e546d5857bac1d905b3d26334c8f8a1cda11 + * sha 512: 8b94b1069e767202bcab087cb592eadc42f0453d17ee119d48760be00bc66278cf0fa60bb09308d30cb551df6a7a3e26e2ab8b29c04f0e953cc6906542cd2d6f + +1.0.6 + + * sha 256: 712ae9a8f17a9e589e108f0d503da203cc5eaf1c4a6ca6efb5b4c83b432ce0b8 + * sha 512: d574003023a00cfd6623aac986a5a7f397cfd0bc9114017629a8c72731b0df3977c4a31768502dfa8a6607be06930089b2ccf6ffca9b5bcd1096b7ca0aede226 diff --git a/README.md b/README.md index 939a682..3da2c16 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,23 @@ # Cagebreak: A Wayland Tiling Compositor Inspired by Ratpoison -This is Cagebreak, a Wayland tiling compositor. The goal of this project is to -provide a successor to ratpoison for Wayland users. However, this is -no reimplementation of ratpoison. Should you like to know if a feature -will be implemented, open an issue or get in touch with the development team. +This is Cagebreak, a Wayland tiling compositor. + +The goal of this project is to provide a successor to ratpoison for Wayland +users. However, this is no reimplementation of ratpoison. + +Should you like to know if a feature will be implemented, open an issue +or get in touch with the development team. For documentation of Cagebreak, please see -the man pages for [cagebreak](man/cagebreak.1.md) and cagebreak -[configuration](man/cagebreak-config.5.md) and the -[Wiki](https://github.com/project-repo/cagebreak/wiki/). + * the man pages + * [cagebreak](man/cagebreak.1.md) + * [configuration](man/cagebreak-config.5.md) + * also the [FAQ](FAQ.md) Cagebreak is based on [Cage](https://github.com/Hjdskes/cage), a Wayland kiosk compositor. -Cagebreak is currently being developed under Arch Linux and uses the libraries +Cagebreak is developed under Arch Linux and uses the libraries as they are obtained through pacman. However, cagebreak should also work on other distributions given the proper library versions. @@ -21,8 +25,11 @@ other distributions given the proper library versions. If you are using archlinux, just use the PKGBUILDs from the aur: - * Using the `cagebreak` package, Cagebreak is compiled on the target system (since release 1.3.0) - * Using `cagebreak-bin` package, the pre-built binaries are extracted to the appropriate paths on the target system (since release 1.3.2) + * Using [cagebreak](https://aur.archlinux.org/packages/cagebreak), Cagebreak is + compiled on the target system (since release 1.3.0) + * Using [cagebreak-bin](https://aur.archlinux.org/packages/cagebreak-bin), + the pre-built binaries are extracted to + appropriate paths on the target system (since release 1.3.2) See [cagebreak-pkgbuild](https://github.com/project-repo/cagebreak-pkgbuild) for details. @@ -59,7 +66,7 @@ $ ninja -C build By default, this builds a debug build. To build a release build, use `meson build --buildtype=release`. -#### Xwayland Support +##### Xwayland Support Cagebreak comes with compile-time support for XWayland. To enable this, first make sure that your version of wlroots is compiled with this @@ -67,9 +74,9 @@ option. Then, add `-Dxwayland=true` to the `meson` command above. Note that you'll need to have the XWayland binary installed on your system for this to work. -#### Man Pages +##### Man Pages -Cagebreak has man pages. To use them, make sure that you have `pandoc` +Cagebreak has man pages. To use them, make sure that you have `scdoc` installed. Then, add `-Dman-pages=true` to the `meson` command. ### Running Cagebreak @@ -81,24 +88,22 @@ KMS+DRM backend. For more configuration options, see the man pages. ## Contributing to Cagebreak -Cagebreak is currently developed to fit the needs of its creators. Should you desire -to implement a feature, please let us know in advance by opening an issue. However, -the feature set is intentionally limited (i.e. we removed support for a desktop -background) and will continue to be so in the future. +Cagebreak is currently developed to fit the needs of its creators. Should you +desire to implement a feature, please let us know in advance by opening +an issue. However, the feature set is intentionally limited (i.e. we removed +support for a desktop background) and will continue to be so in the future. -Nonetheless, don't be intimidated by the (slightly lengthy) release checklist or any other -part of this file. Do what you can, open an issue and we will collaborate -toward a solution. +Nonetheless, don't be intimidated by the (slightly lengthy) release checklist +or any other part of this file. Do what you can, open an issue and we will +collaborate toward a solution. ### Branching Strategy and Versioning -All features are to be developed on feature branches, named after the feature. +There exists a branch `development` to which all reasonable code +is comitted for final testing. -There exists a branch `development` to which all reasonable feature branches -are merged for final testing. - -Once `development` is ready for a release, meaning that the release checklist is fulfilled, -it is merged into `master`, creating a new release, which is tagged and signed. +Once `development` is ready for a release, it is merged into `master` (possibly via +a cherry-picked branch), creating a new release, which is tagged and signed. All releases are tagged according to [semantic versioning](https://semver.org) guidelines. @@ -107,7 +112,7 @@ In the past, our git history did not perfectly reflect this scheme. ### Releases The release checklist must be completely fulfilled in one run for a release to -occur. Once any failure occurs the entire checklist must be completed from scratch. +occur. * [ ] `git checkout development` * [ ] `git pull origin development` @@ -120,13 +125,16 @@ occur. Once any failure occurs the entire checklist must be completed from scrat * [ ] man/cagebreak * [ ] man/cagebreak-config * [ ] Set EPOCH to release day in man generation in meson.build - * [ ] wiki - * [ ] README.md Changelog for major and minor releases but not patches + * [ ] FAQ.md + * [ ] Changelog.md for major and minor releases but not patches + * [ ] Check features for SECURITY.md relevance (changes to socket scope + for example) * [ ] Fixed bugs documented in Bugs.md * [ ] Include issue description from github * [ ] Testing * [ ] Manual testing * [ ] Libfuzzer testing + * [ ] Build version without xwayland support * [ ] Version Number * [ ] meson.build * [ ] git tag @@ -165,6 +173,9 @@ occur. Once any failure occurs the entire checklist must be completed from scrat * [ ] `cp build/cagebreak-config.5 release-artefacts_version/` * [ ] `cp build/cagebreak-config.5.sig release-artefacts_version/` * [ ] `cp LICENSE release-artefacts_version/` + * [ ] `cp README.md release-artefacts_version/` + * [ ] `cp SECURITY.md release-artefacts_version/` + * [ ] `cp FAQ.md release-artefacts_version/` * [ ] `export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) ; tar --sort=name --mtime= --owner=0 --group=0 --numeric-owner -czf release-artefacts_version.tar.gz release-artefacts_version` * [ ] Checked archive * [ ] tar -xvf release_version.tar.gz @@ -204,215 +215,7 @@ For every release after 1.0.5, hashes will be provided. For every release after 1.7.0, hashes will be provided for man pages too. -1.8.3 cagebreak - - * sha 256: 85803b75b1be0d9bf600175ce6aa981a1632768872e5afddea7569f825c1f7c3 - * sha 512: 96c9b33804bbd7c652e32556d5001e12c2b07ab7127118a050be513bd6e0d6241fb78c80d9cce50447ae32a7b33c5c6a6cf1def36efaf3d8e8ddb028bcd769df - -1.8.3 cagebreak.1 - - * sha 256: e583f818d73484cbcae65dbe6ffc226ea58fdad87363213ea5b1059d866216e4 - * sha 512: b96d8f9308d31bb1faa346267136fd7a53caed95065e7da09713b5f64addb42c835b27cd6cfa6bcf8c5b5d572a73b1e828f47b14e06a00b0871a77a25a286597 - -1.8.3 cagebreak-config.5 - - * sha 256: d0be008e0e5d47b876ccfb8cf70967097673b81fa93718838db45f4056b76bc0 - * sha 512: 42f8d25eb89219aebd00e927627a51fd8b7f6fda6f7c6147abbc0e4fae5de1ceb5827b79a814127a0706cc213d7717733e02cfa5275960cb0cce23eb54493b1e - -1.8.2 cagebreak - - * sha 256: f4d275d48ba3d999969f8cb3c8142d27aa8e8d362106ee7575e4b13c02173b2a - * sha 512: 72b11cb966b0978133b9848c2a7f57574c599c7fe895ca9f1cba16930216e1ac8aeae86d976593fc01b15e94ecc1430666f474654cf2fe41eda8c1181bf03f3d - -1.8.2 cagebreak.1 - - * sha 256: 51ee97a7c0b86268cf7622f84f7b1813df8e4a7838c00aae412a611d3693e87a - * sha 512: 5ce826afbee9cbc1129f37463f5b6d4dfc060583f6f7816dd5039b18d66a2b7e22f7293a4aa03acc4e6c690886d0297fef5b9f85d720a4467becfd833b59a160 - -1.8.2 cagebreak-config.5 - - * sha 256: 7c780ba85211ba40c7535b3f10f12312f9edeaa10030228ba21a96724469a325 - * sha 512: 9a56ba16c2aed6f17d4098e54900a5d25602f986e3606dd6ed26563c1920c66404b210dbca9f41bfcc3284bf5a42b750263bcaa2317320f8725e8f9c66e8b893 - -1.8.1 cagebreak - - * sha 256: e3247281d21525413790e3feceae129d9b0559497615d3fdd64ec2fc4ab9ab3d - * sha 512: 8c7c2820be9d7c74e3f9e239c7da740ff41d7f11cd40953dbfbc59c04942077f08625f6d7ec37e6037fd9c4b6950fc4f9af23478080665fdda867c65e0a187bf - -1.8.1 cagebreak.1 - - * sha 256: 96997afdfde9c2719533799aa48c8f036610bb04bc719130d2ab3a3617b072ee - * sha 512: 0831f5d2e3b4f23fd5775df2b7f6486099d64962567222a8fb49e6a40e7d29ed36a7c2c16201bbdcc985ac74f1d0e034b530afbe0ce58d6a0c53d467cff0a6a0 - -1.8.1 cagebreak-config.5 - - * sha 256: bd0e2eb02ba28ec1c8f2bd0fd5cd4c84af24b615fcc477414e49e68e1963cf1b - * sha 512: 7135a2b371294bfdc759a393c13fa0225f1789dba94bb09e96ae689796215b8030280d6cc09c9d1fe139f000f5a4748efd16bb3e5d3b9fcc74a19259802f20ef - -1.8.0 cagebreak - - * sha 256: ac84aa4a08c311da79ca29d92eef4254cb625674b255dbb75621ee6b171a1d79 - * sha 512: c047bb1986fd1d444547e4d64aa7ef9138b3d30327ac3ad9b4c6976e8df6638bae07c39293b5bc9c20e959c0a22b0e40eb2b23b4766d9a5531377ff954b16229 - -1.8.0 cagebreak.1 - - * sha 256: 4de43de7bde67d6d806d206dffc34389f0b5c3ba648bfef673b7bc0adeb29202 - * sha 512: 72aac9a2e9a47f2f85949222d5944dc293332a616e3b961c625fe876172f66638038057c30aa18904d6d969451f468b4fe45e918c0b204cf6952d58ea4c69c33 - -1.8.0 cagebreak-config.5 - - * sha 256: 678aadde06b5ff6bfbd9bc9460423210f9599bcaa0e50c2eae076dc6d6852781 - * sha 512: 72056018fc1c559f26bd7e007b3f1db7d478cec7ec9337620e03a1e3d06910e244a52e8f655ea4f5d73669ffe064bbd23506005d9a6c06764b0f820d7a1df43f - -1.7.4 cagebreak - - * sha 256: c7442db906239b13f8d09e91cbe01f9e47b2a2c75bbb4b52adefd15dfbfa820f - * sha 512: 9c36ce706f31e1b8afacd8f9cd216c460d66030e0b2736a3dd929902b0d5fc52c5e69dbf6787205b8c495d960e00b6e7f633da86ab6e31613f1b4a9fd47c9f0e - -1.7.4 cagebreak.1 - - * sha 256: 3dacc521e5e9b963cceeefeed6a10104c7c415d86826a72788aba5b33ce320f1 - * sha 512: 0a4c4fbff09dd403fed61056ae3211ad2b4370b4e9ed07806fc22624e5312b4a25e469dc0eef1ca4556cbb8efabb0127e7519df79852e110faa98fb17ca377de - -1.7.4 cagebreak-config.5 - - * sha 256: ed22fed1818172f31d3fb3efbe5e66b49f135cb2367b1c85209fd880ff7532ab - * sha 512: cc634c63962ae50b4de20a3aad8ca0970175b53156690d69e6a69fd8f370ad20d84db783cc7e94c61d4d4d89f1205d43622690e58afba549ed57ddad009e3bac - -1.7.3 cagebreak - - * sha 256: 8adb4911d9603fec5b8eb4f67a09be95b8f0b37e50d4ab579191da78df18f70b - * sha 512: eddaecd7b577b9fe77b1ed4d341074f7f860967568392d0479543ea8860b4289df3eb5645885e18e35260b14843663ae50f98103f8016e857237a397632322a6 - -1.7.3 cagebreak.1 - - * sha 256: bcc623e42c86ab65bc2f8cb7e4377ca0d816ddc281527b7caeded62753e943b8 - * sha 512: b4290e1040bd6a299d478ad6b695de75cf030d0d274340b43d3ed4382cf6877f824cd4ed9d7020bfb55afe276c62de7fc07c3fbee6f6485c6440a024115afe12 - -1.7.3 cagebreak-config.5 - - * sha 256: b9789b6abd473e9afb33d4e2c7822f7d8f3c10e9eb3fb70c47b713f6331c626a - * sha 512: c49e01cfc4a4ed272f054bea8f2845f0e3f1609cf85d1a0ce14c1b67dc207df153b11bc20ceef09c855d467f0e013e54623ce9f70c217c4278607fc54d0e3206 - -1.7.2 cagebreak - - * sha 256: 40f4642e8e8caee338055079b046f6e0b790c87226ee307b27a64fcb2a6c6472 - * sha 512: 22c5f1986ca4262a7c08a6c03cffe36eaedd8c3c5e27e12baf12a90f94aea088ac93ee107770f162fc70148be687f6394b8fd64ad3fe14414bdf63b55b33798e - -1.7.2 cagebreak.1 - - * sha 256: 3253e592c40c78fd3733c761163acc2efaaf5865627cf51fd33cc0bc5d9cc6e7 - * sha 512: 901305e166c10aa7e4a26b721a69e0ba4779f4f8ee690551438ceadae65929f13949457872b9397dd46c5b7bad6a6f2638d6fd6df9bc5567c914c798cbf3e9a4 - -1.7.2 cagebreak-config.5 - - * sha 256: 148ec4d80dc9a86485fe77f8daf1f7fa4cb3d1b6aaa709bb012005583779e1f7 - * sha 512: d5732572e47dd07078ac2f6d589522e6007188fc05ac79520c93442212d5c0341459f135191b88c608a75b2f56c2de4065566bd869fbc24e475936d32a54a7f8 - -1.7.1 cagebreak - - * sha 256: 5a40797e016a2fa32b5bb70a056b35c482bef09f1795bbaf0188dbadaf8197c3 - * sha 512: 2ef327b63ac4651f23517be8d5cb8fbec99bd889f52f8abfd62a09ca6e6c0060347ab8d60e4917d39edd36db34597a673239967533f14457733acb97f6c29a7f - -1.7.1 cagebreak.1 - - * sha 256: 0301f04254ae6e7ada7e22bbe7aee022ec0793fbce434a396868258e6f1ea4cf - * sha 512: f0c0c5de30be907e9ba5c9cfa0bca8cef3e94c0b5f52de9e2c3681c85aa957f75e92b5e26bb894c3a5e251295cfe7a1470653cc7dc05564d7d91c6eb43b7409a - -1.7.1 cagebreak-config.5 - - * sha 256: 6882330a77f3ff98ea642f47b4090b38d542abf0b7be3f226486c5614899efc6 - * sha 512: a572f97836e4ccc6d67aa21c7f4aaebe06adb066c70038b670ec1ef267e3750764cb53e96b8d7bc24c7f993f24c0cfabee183307b45006d049f7416559bcaca4 - -1.7.0 - - * sha 256: 5af11b84e61a82a1a276e8f91f6ebc6baafd2c98d22be3da1d01734cc9d55faa - * sha 512: 45474115fb4c28fe1ee91ad54706bfe521b6e70bd8ea619b94a3f50bae426891bf6a0387aa9b2f7f6d18349280c4e84973e4e433d50c090e5a764c64fa67795d - -1.6.0 - - * sha 256: aef473eae73454429afb158d66a7bd9aec75ef915845b7508de5448820357aa8 - * sha 512: 17889bc1af9f343598a5ee599b25e702987dd0bd905a9566874e8a0094c57168e413938624949fa214e6e382cbcf89d7342292b44012cd8e692947f6c01a960a - -1.5.1 - - * sha 256: 9c6df4b94c180f5657cb424383aa2bf3aca063c8e7b40af0497be1ef7bdb858a - * sha 512: 219f753347ae64a4dd593568797438742e9ddae380c729598d8eda863080a6ed4e5086d735fc348c48328bb795a5a5b57b0421be5dd45755744d895b24312627 - -1.5.0 - - * sha 256: 22010e2916493b0d7cfb08c2196f12589509ce11010a7107aed13ddbfd9709cc - * sha 512: 707d6cc01326ba32402f9fb402ff8aceaeaba63ca6ba2eb157e5a4c83123515a3a74da960813479db303eddc2e7f79f39b241dff05b89d47d72d5f1d20ca6d37 - -1.4.4 - - * sha 256: c6e08e19feb17f768e136cf02f5692ef121ff289763dc60ef8678103803d3307 - * sha 512: aebf27fa9c24f93dfd0b7c96536c253e2ea603d6746c40e8de2163e06367bc57ac4e22d6c07dd1e0963cce5b18b460d373e15b5c12a5a42ae6b70787971960c9 - -1.4.3 - - * sha 256: 5e29cbaf7c0c5ca74f71a5605bb3d6e302e051798401fee9a79419720b8d8e95 - * sha 512: 8004865f8603648d9ac9bb700f3ee040e6516c222ad3d783b34219c8fa3a7bdbba6abb74fe92c4d0bd4dbbce0ec4d08be12297a8bad5032baeb589eec557e24e - -1.4.2 - - * sha 256: 27efb9328cf9cab1f81e66627696baf8c7cc2c372339a2890f955b40f3a7c396 - * sha 512: afcdbbce0753aff4770a88ddbd7df5687a7de0c77de3a2d296f85a8b8e01813212be6a0b69548aadef58e0e7da19ffea71c4f3448572656d4b19ff7f2f2fb70a - -1.4.1 - - * sha 256: c3e0ccceaf1078b91071c40b0ccb7c4f8e53ae38b05ee6637f9f39f7f6ece2cb - * sha 512: fd77f39fc7a7e5376d8505a61d643ed4d8f4cfbbf38d70cf9ef6989645e8cc6cb9d4b1024d241dc689b6fd927a405c97b9c918b6994b8f9ab7406646f37b952d - -1.4.0 - - * sha 256: 14aa93d890c62cc763b3b546a51ad8560479d5e91fa9f949858ae6bc785e80be - * sha 512: 88f93b49792684c38553b65d2296a0e502a059814a0cfff30d05c89958870d6f66d67aac2074cfd307bad82b0d72d5c4944822a61a68f665dc161407db365fbc - -1.3.4 - - * sha 256: ea9f634b8f6e2b9f191745a25abff4969eb7ea19cb3186b79a6138904aedeb1c - * sha 512: 9094f9c92acbff8fd95d38e7458c5184804f8913fa8c405bc2b6a0a220fe478b06cfeadbae41bd5ef84bde8d5642c249df9dada953e39c25926aa650c30a5309 - -1.3.3 - - * sha 256: 801851ceb52afac333a1decdd236ddef55555f8b36f865e8b3a831975a496f0d - * sha 512: ce64dd56ab99bba0a83414fecc82d85322e1ca5ca3a2ca77bdc7055b2dd10fd5e20e3ff62809a696d1b04ff0046fed88e2d7538aa447099d7c2d7df8e627b2e0 - -1.3.2 - - * sha 256: 2cefab73b8d5902b30adb0dda1bd292af2ee808d232abcc4b2a2802d522d5232 - * sha 512: 3789efde2cb6f629c77738dd6c8638646b345d5272868aa9b244b2b19c53e6a0f5911d34744e3a9ff6253c73b2b11f6714f37ae86cc21d6979e0c8539315d659 - -1.3.1 - - * sha 256: 71be224cd99d20da4f039675ec5c48213dd14ef027b804501fa3241886b2b08b - * sha 512: d094b786e5a74b01699997a85747943e6de3544cc903dd1c5dba449c66bd925b6378de800d3734969dabf8a20c7004dc3402e3c59577db09ce107b68a1f7bd21 - -1.3.0 - - * sha 256: aecc5292f56f7250d777110cee1f11a92018a9eb2117d7d37cd51d7d3a5cbae0 - * sha 512: 1d2d220f44787a97359a32f305e33185f0369551e61a9d7066023bfa43de50849eba5bcbb0083d2dc563ac993b8d51dd733afa0adb2a823ef50ecfee5624bbc0 - -1.2.1 - - * sha 256: 803f7667dc4997062f9ec95afcdca0cac68c82a7cf057cef83fe1ccfee33b8bc - * sha 512: 4d6b7efea10d190a153f893123b1715f290f4b131b490f3d23f489e2dd8edbb886001282849aad9575ad2f40375bbbded59c1cb6157115fcc14dd6a2a061b103 - -1.2.0 - - * sha 256: b3c6135833001a0ef600ea9628cca11f4130a524ebe748929d8f7bad034f2bf0 - * sha 512: c044a086a9f65b0d27d05e2f12a20fe5d77386fc5682991c13a1894a84804bcd337c9167235869661d6e6581133521bd710ef2330066a5d2e2703d1630042f3f - -1.1.0 - - * sha 256: fc393e225c549f893b9e21e8b904e546d5857bac1d905b3d26334c8f8a1cda11 - * sha 512: 8b94b1069e767202bcab087cb592eadc42f0453d17ee119d48760be00bc66278cf0fa60bb09308d30cb551df6a7a3e26e2ab8b29c04f0e953cc6906542cd2d6f - -1.0.6 - - * sha 256: 712ae9a8f17a9e589e108f0d503da203cc5eaf1c4a6ca6efb5b4c83b432ce0b8 - * sha 512: d574003023a00cfd6623aac986a5a7f397cfd0bc9114017629a8c72731b0df3977c4a31768502dfa8a6607be06930089b2ccf6ffca9b5bcd1096b7ca0aede226 +See [Hashes.md](Hashes.md) #### GPG Signatures @@ -441,6 +244,8 @@ keys. * 8F872885968EB8C589A32E9539ACC012896D450F * 896B92AF738C974E0065BF42F2576BD366156BB9 * AA927AFD50AF7C6810E69FE8274F2C605359E31B + * BE2DED372287BC4EB2213E13A0C743848A638955 + * 0F3476E4B2404F95EC41600683D5810F7911B020 Should we at any point retire a key, we will only replace it with keys signed by at least one of the above collection. @@ -520,61 +325,19 @@ issue](https://github.com/project-repo/cagebreak/issues/new) on Fixed bugs are to be assigned a number and summarized inside Bugs.md for future reference independent of github, in case this service is unavailable. -### Security Bugs +Mail contact: `cagebreak @ project-repo . co` -Should you want to get in touch with the developers of cagebreak to report a -security vulnerability or a different issue confidentially, contact -`cagebreak @ project-repo . co`. - -We will try to respond to everything that is not obvious spam. - -Please encrypt your email with the appropriate GPG key found in `keys/`. +GPG Fingerprints: * B15B92642760E11FE002DE168708D42451A94AB5 * F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C + * 3ACEA46CCECD59E4C8222F791CBEB493681E8693 -Note that the keys are signed by cagebreak signing keys. - -If you want us to respond via GPG-encrypted mail, please include your own -public key or provide the fingerprint and directions to obtain the key. +See [SECURITY.md](SECURITY.md) for details. ## Changelog -### Release 1.0.0 - -Adds basic tiling window manager functionality to cage. - -### Release 1.1.0 - -Unifies commands and actions. See Issue 4 in Bugs.md. - -### Release 1.2.0 - -Adds output configuration as described in the man pages. - -### Release 1.3.0 - -Adds IPC as described in the man pages. - -### Release 1.4.0 - -Adds close command for windows as described in the man pages. - -### Release 1.5.0 - -Adds options to disable or enable outputs. See Issue 22 in Bugs.md and Issue #2 on github. - -### Release 1.6.0 - -Adds support for non-build dependencies and an option for builds without pandoc. - -### Release 1.7.0 - -Improve window ordering. - -### Release 1.8.0 - -Adds libinput configuration and virtual keyboard and pointer support. +See [Changelog.md](Changelog.md) ## Contributors diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..5f8ee2c --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,91 @@ +# Security + +The main possibility for security bugs to occur in cagebreak is by privilege +escalation using the socket. Indeed, any program with access to the socket +immediately gains arbitrary code execution rights. As of right now, the socket +is world-writable. If you disagree with this threat model, you may contact +us via email (See section Email Contact below.) or [open an issue on github](https://github.com/project-repo/cagebreak/issues/new). + +Should any problem with the github issue system arise or any other reason +for (potentially confidential) contact with the Cagebreak authors appear, +you may contact us via email (See section Email Contact below.). + +## Supported Versions + +The latest release always contains the latest bug fixes and features. +There are no official backports for security vulnerabilities. Builds +are reproducible under conditions outlined in [README.md](README.md). + +## Bug Reports + +For normal bugs you may [open an issue on github](https://github.com/project-repo/cagebreak/issues/new). + +For everything else, an email contact (with gpg encryption and signature) +is available below. + +## Email Contact + +Should you want to get in touch with the developers of cagebreak to report +a security vulnerability or anything else via email, contact +`cagebreak @ project-repo . co`. + +We will try to respond to everything that is not obvious spam. + +### GPG-Encrypted Emails + +If you can, please encrypt your email with the appropriate GPG key found +in `keys/` and sign your message with your own key. + + * B15B92642760E11FE002DE168708D42451A94AB5 + * F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C + * 3ACEA46CCECD59E4C8222F791CBEB493681E8693 + +Note that our keys are signed by cagebreak signing keys. + +If you want us to respond via GPG-encrypted email, please include your own +public key or provide the fingerprint and directions to obtain the key. + +## Threat Model + +Cagebreak is a wayland compositor, which is run by the user of the system +and thus has access to whichever resources this user has access to. +Cagebreak can restrict other programs in no way, because this would hamper +usability (consider a web browser unable to write a downloaded file to disk +for instance). There is no transmission of information by cagebreak other +than to the screens, ipc and potentially other documented local channels. + +### STRIDE Threat List + +This is not a thorough analysis, just an overview of the ways in which cagebreak +has/does not have an attack surface. + +#### Spoofing + +Not applicable - Using cagebreak already requires a login as a user. + +#### Tampering + +Not applicable - Cagebreak must allow system manipulation for user software. + +#### Repudiation + +Not applicable - There are no prohibited operations (See Tampering above.). +While cagebreak does send events over documented channels there is no logging +activated by default, though, of course, this can be changed by the user +by logging socket output for example. + +#### Information Disclosure + +Not applicable - Information disclosure over documented channels is a feature +and any software run by the user may exfiltrate any data the user has access to. + +#### Denial of Service + +Not applicable - Cagebreak offers functionality to terminate itself, which is +available to all user software over the socket. + +#### Elevation of privilege + +Software may gain arbitrary code execution rights if it has access to the +Cagebreak socket. Privilege escalation to root is unlikely since privileges +are dropped before any user input is accepted. diff --git a/cagebreak.c b/cagebreak.c index b6fbcab..00712f9 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -77,14 +77,6 @@ set_sig_handler(int sig, void (*action)(int)) { } } -void -sig_chld_handler(int signal) { - int pid = 1; - while(pid > 0) { - pid = waitpid(WAIT_ANY, NULL, WNOHANG); - } -} - static bool drop_permissions(void) { if(getuid() != geteuid() || getgid() != getegid()) { @@ -316,8 +308,6 @@ main(int argc, char *argv[]) { wl_event_loop_add_signal(event_loop, SIGALRM, handle_signal, &server); server.event_loop = event_loop; - set_sig_handler(SIGCHLD, sig_chld_handler); - backend = wlr_backend_autocreate(server.wl_display); if(!backend) { wlr_log(WLR_ERROR, "Unable to create the wlroots backend"); diff --git a/examples/config b/examples/config index f701684..e6a6cb5 100644 --- a/examples/config +++ b/examples/config @@ -23,6 +23,7 @@ bind N nextscreen bind P prevscreen bind a time bind C-n movetonextscreen +bind C-p movetoprevscreen bind H exchangeleft bind J exchangedown bind K exchangeup @@ -33,6 +34,7 @@ bind k focusup bind l focusright bind t exec xterm bind C-k close +#bind m message Hello World! definekey resize h resizeleft definekey resize l resizeright definekey resize j resizedown @@ -42,6 +44,20 @@ definekey resize Escape setmode top ###################### #Workspaces ###################### +bind 1 screen 1 +bind 2 screen 2 +bind 3 screen 3 +bind 4 screen 4 +bind 5 screen 5 +bind 6 screen 6 + +bind A-1 movetoscreen 1 +bind A-2 movetoscreen 2 +bind A-3 movetoscreen 3 +bind A-4 movetoscreen 4 +bind A-5 movetoscreen 5 +bind A-6 movetoscreen 6 + definekey top A-1 workspace 1 definekey top A-2 workspace 2 definekey top A-3 workspace 3 @@ -78,6 +94,7 @@ definekey top XF86MonBrightnessUp exec xbacklight -inc 1 #output eDP-1 pos 0 0 res 1366x768 rate 60 #output eDP-1 disable #output eDP-1 enable +#output eDP-1 prio 1 ##################### #Input configuration diff --git a/keybinding.c b/keybinding.c index f7761cd..5207d24 100644 --- a/keybinding.c +++ b/keybinding.c @@ -1,6 +1,7 @@ #define _POSIX_C_SOURCE 200809L #include +#include #include #include #include @@ -718,7 +719,12 @@ keybinding_show_info(struct cg_server *server) { } void -keybinding_move_view_to_next_output(struct cg_server *server) { +keybinding_display_message(struct cg_server *server, char *msg) { + message_printf(server->curr_output, "%s", msg); +} + +void +keybinding_move_view_to_cycle_output(struct cg_server *server, bool reverse) { if(wl_list_length(&server->outputs) <= 1) { return; } @@ -927,20 +933,23 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_SPLIT_VERTICAL: keybinding_split_vertical(server); break; - case KEYBINDING_RUN_COMMAND: - if(fork() == 0) { - into_process(data.c); + case KEYBINDING_RUN_COMMAND: { + int pid; + if((pid = fork()) == 0) { + if(fork() == 0) { + into_process(data.c); + } + _exit(0); + } else if(pid > 0) { + waitpid(pid, NULL, 0); } - break; + } break; case KEYBINDING_CYCLE_VIEWS: keybinding_cycle_views(server, data.b); break; case KEYBINDING_CYCLE_TILES: keybinding_cycle_tiles(server, data.b); break; - case KEYBINDING_CYCLE_OUTPUT: - keybinding_cycle_outputs(server, data.b); - break; case KEYBINDING_SWITCH_WORKSPACE: keybinding_switch_ws(server, data.u); break; @@ -959,6 +968,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_SHOW_INFO: keybinding_show_info(server); break; + case KEYBINDING_DISPLAY_MESSAGE: + keybinding_display_message(server, data.c); + break; case KEYBINDING_RESIZE_TILE_HORIZONTAL: resize_tile(server, data.i, 0); break; @@ -1017,8 +1029,8 @@ run_action(enum keybinding_action action, struct cg_server *server, ->focused_tile); break; } - case KEYBINDING_MOVE_VIEW_TO_NEXT_OUTPUT: { - keybinding_move_view_to_next_output(server); + case KEYBINDING_MOVE_VIEW_TO_CYCLE_OUTPUT: { + keybinding_move_view_to_cycle_output(server, data.b); break; } case KEYBINDING_DEFINEKEY: diff --git a/keybinding.h b/keybinding.h index 4cd0e87..ebbfae9 100644 --- a/keybinding.h +++ b/keybinding.h @@ -20,15 +20,17 @@ enum keybinding_action { KEYBINDING_SPLIT_HORIZONTAL, KEYBINDING_CHANGE_TTY, // data.u is the desired tty KEYBINDING_LAYOUT_FULLSCREEN, - KEYBINDING_CYCLE_VIEWS, // data.b is 0 if forward, 1 if reverse - KEYBINDING_CYCLE_TILES, // data.b is 0 if forward, 1 if reverse - KEYBINDING_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if reverse - KEYBINDING_CONFIGURE_OUTPUT, // data.o_cfg is the desired output - // configuration - KEYBINDING_CONFIGURE_INPUT, // data.i_cfg is the desired input - // configuration + KEYBINDING_CYCLE_VIEWS, // data.b is 0 if forward, 1 if reverse + KEYBINDING_CYCLE_TILES, // data.b is 0 if forward, 1 if reverse + KEYBINDING_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if reverse + KEYBINDING_CONFIGURE_OUTPUT, // data.o_cfg is the desired output + // configuration + KEYBINDING_CONFIGURE_MESSAGE, // data.m_cfg is the desired config + KEYBINDING_CONFIGURE_INPUT, // data.i_cfg is the desired input + // configuration KEYBINDING_QUIT, KEYBINDING_NOOP, + KEYBINDING_SWITCH_OUTPUT, // data.u is the desired output KEYBINDING_SWITCH_WORKSPACE, // data.u is the desired workspace KEYBINDING_SWITCH_MODE, // data.u is the desired mode KEYBINDING_SWITCH_DEFAULT_MODE, // data.u is the desired mode @@ -36,10 +38,13 @@ enum keybinding_action { // to the current width KEYBINDING_RESIZE_TILE_VERTICAL, // data.i is the number of pixels to add to // the current height - KEYBINDING_MOVE_VIEW_TO_WORKSPACE, // data.u is the desired workspace - KEYBINDING_MOVE_VIEW_TO_NEXT_OUTPUT, + KEYBINDING_MOVE_VIEW_TO_WORKSPACE, // data.u is the desired workspace + KEYBINDING_MOVE_VIEW_TO_OUTPUT, // data.u is the desired output + KEYBINDING_MOVE_VIEW_TO_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if + // reverse KEYBINDING_SHOW_TIME, KEYBINDING_SHOW_INFO, + KEYBINDING_DISPLAY_MESSAGE, KEYBINDING_SWAP_LEFT, KEYBINDING_SWAP_RIGHT, @@ -66,6 +71,7 @@ union keybinding_params { struct keybinding *kb; struct cg_output_config *o_cfg; struct cg_input_config *i_cfg; + struct cg_message_config *m_cfg; }; struct keybinding { diff --git a/keys/cagebreak@project-repo.co.pub b/keys/cagebreak@project-repo.co.pub index 6d23cef..c266665 100644 --- a/keys/cagebreak@project-repo.co.pub +++ b/keys/cagebreak@project-repo.co.pub @@ -1,123 +1,76 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -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 -LA== -=UJ+r +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 +PbvoKi4FeWdszeakeWuqdmKEi/+ltIk= +=uqsg -----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak@project-repo.co.pub-legacy b/keys/cagebreak@project-repo.co.pub-legacy-1 similarity index 100% rename from keys/cagebreak@project-repo.co.pub-legacy rename to keys/cagebreak@project-repo.co.pub-legacy-1 diff --git a/keys/cagebreak@project-repo.co.pub-legacy-2 b/keys/cagebreak@project-repo.co.pub-legacy-2 new file mode 100644 index 0000000..6d23cef --- /dev/null +++ b/keys/cagebreak@project-repo.co.pub-legacy-2 @@ -0,0 +1,123 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +LA== +=UJ+r +-----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak_signing_key_10@project-repo.co.pub b/keys/cagebreak_signing_key_10@project-repo.co.pub new file mode 100644 index 0000000..c266665 --- /dev/null +++ b/keys/cagebreak_signing_key_10@project-repo.co.pub @@ -0,0 +1,76 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +PbvoKi4FeWdszeakeWuqdmKEi/+ltIk= +=uqsg +-----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak_signing_key_9@project-repo.co.pub b/keys/cagebreak_signing_key_9@project-repo.co.pub new file mode 100644 index 0000000..2e99549 --- /dev/null +++ b/keys/cagebreak_signing_key_9@project-repo.co.pub @@ -0,0 +1,64 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=gLvW +-----END PGP PUBLIC KEY BLOCK----- diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 4eea4c5..b931db4 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,8 +1,8 @@ -cagebreak-config(1) "Version 1.8.3" "Cagebreak Manual" +cagebreak-config(5) "Version 1.9.0" "Cagebreak Manual" # NAME -*cagebreak-config* — Cagebreak config file +*cagebreak-config* — Cagebreak configuration file # SYNOPSIS @@ -10,91 +10,135 @@ cagebreak-config(1) "Version 1.8.3" "Cagebreak Manual" # DESCRIPTION -The cagebreak configuration file is a simple plain text file which configures -the way cagebreak behaves. -Each line constitutes a separate command which is parsed -independently from the rest of the file. Comments can be added -by prepending a line with the # symbol. +The cagebreak configuration is a plain text file. + +Each line consists of a comment or a command and its arguments which +are parsed sequentially but independently from the rest of the file. + +Each line starting with a "#" is a comment. + +See *KEY DEFINITIONS* for details on modifier keys and *MODES* for details +on modes. ## COMMANDS *abort* - Return to the default mode without running any command + Return to default mode -*background - Set background color* - Set the background color. This command expects three floating point numbers - between 0 and 1, specifying the r, g and b values respectively. - (e.g. "background 1.0 0.0 0.0" sets to background color to red) - There is no support for specifying a background image. +*background * + Set RGB of background - <[r|g|b]> are floating point numbers + between 0 and 1. + There is no support for background images. -*bind - Bind key to command in root mode* - This command requires a key (see *KEY DEFINITIONS*) and a command (see *COMMANDS*) as an argument. - Subsequently, pressing this key while in command mode executes the - supplied action. bind is equivalent to - definekey root +``` +# Set background to red +background 1.0 0.0 0.0 +``` -*close - Close current window* - This command closes the current window. It may be useful for windows of applications which - do not offer any method of closing them. +*bind * + Bind to execute if pressed in root mode -*definekey - Bind key to action in arbitrary mode* - This command behaves similarly to the *bind* command with the - difference that the mode in which the keybinding is activated is - specified by the user. A call to this function is to be structured as follows: +``` +bind +# is equivalent to +definekey root +``` - definekey +*close* + Close current window - This may be useful for windows of + applications which do not offer any method of closing them. -*definemode* - This command requires a single argument; the name of the mode to be defined. - Subsequent to a call to this function, the defined mode may be used along with - the definekey command to create a custom key mapping. Synopsis: +configure_message [font |[f|b]g_color b> |display_time ] + Configure message characteristics - + - font sets + - is + - X core font description or + - FreeType font description via pango + - fg_color sets RGBA of foreground + - bg_color sets RGBA of background + - display_time sets display time in seconds - definemode +``` +# Set font +## Set example X code font +configure_message font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 +## Set example FreeType font description +configure_message font pango:monospace 10 -*escape* - Defines the key with which the current mode can be changed to "root". - escape is equivalent to definekey top switch_mode root +# Set foreground RGBA to red +configure_message fg_color 1.0 0.0 0.0 1.0 + +# Set background RGBA to red +configure_message bg_color 1.0 0.0 0.0 1.0 + +# Set duration for message display to four seconds +configure_message display_time 4 +``` + +*definekey * + Bind to execute if pressed in - + *definekey* is a more general version of *bind*. + +*definemode * + Define new mode - After a call to *definemode*, + can be used with *definekey* to create a custom key mapping. + +``` +# define new mode and create a mapping for it +definemode foo +definekey foo C-t abort +``` + +*escape * + Set to switch to root mode to execute one command + +``` +escape +# is equivalent to +definekey top mode root +``` *exchangedown* - Exchange the current window with the window in the tile to the bottom + Exchange current window with window in the tile to the bottom *exchangeleft* - Exchange the current window with the window in the tile to the left + Exchange current window with window in the tile to the left *exchangeright* - Exchange the current window with the window in the tile to the right + Exchange current window with window in the tile to the right *exchangeup* - Exchange the current window with the window in the tile to the top + Exchange current window with window in the tile to the top -*exec* - Executes the supplied shell command using *sh -c ""*. Synopsis: - - exec +*exec * + Execute using *sh -c* *focus* Focus next tile *focusdown* - Focus the tile to the bottom + Focus tile to the bottom *focusleft* - Focus the tile to the left + Focus tile to the left *focusprev* Focus previous tile *focusright* - Focus the tile to the right + Focus tile to the right *focusup* - Focus the tile to the top + Focus tile to the top *hsplit* Split current tile horizontally *input * - Set the setting "" to "" for device "". The identifier can either be "\*" (wildcard), of the form "type:" or the identifier of the device as printed for example by *cagebreak -s*. The supported input types are + Set to for device - + can be "\*" (wildcard), of the form + "type:" or the identifier of the device as printed + for example by *cagebreak -s*. The supported input types are - touchpad - pointer - keyboard @@ -103,121 +147,145 @@ by prepending a line with the # symbol. - tablet_pad - switch - Configurations are applied sequentially. Currently, only libinput devices may be configured. The available settings and their corresponding values are as follows: + Configurations are applied sequentially. Currently, only libinput + devices may be configured. The available settings and their + corresponding values are as follows: *accel_profile adaptive|flat* - Sets the pointer acceleration profile for the specified input device. + Set pointer acceleration profile for specified input device *calibration_matrix <6 space-separated floating point values>* - Sets the calibration matrix. + Set calibration matrix *click_method none|button_areas|clickfinger* - Changes the click method for the specified device. + Change click method for the specified device *drag enabled|disabled* - Enables or disables tap-and-drag for specified input device. + Enable or disable tap-and-drag for specified input device *drag_lock enabled|disabled* - Enables or disables drag lock for specified input device. + Enable or disable drag lock for specified input device *dwt enabled|disabled* - Enables or disables disable-while-typing for the specified input device. + Enable or disable disable-while-typing for specified input + device - *enabled|disabled|disabled_on_external_mouse* - Enables or disables send_events for specified input device. Disabling - send_events disables the input device. + *event enabled|disabled|disabled_on_external_mouse* + Enable or disable send_events for specified input device - + Disabling send_events disables the input device. *left_handed enabled|disabled* - Enables or disables left handed mode for specified input device. + Enable or disable left handed mode for specified input device *middle_emulation enabled|disabled* - Enables or disables middle click emulation. + Enable or disable middle click emulation *natural_scroll enabled|disabled* - Enables or disables natural (inverted) scrolling for the specified input - device. + Enable or disable natural (inverted) scrolling for specified + input device *pointer_accel [<-1|1>]* - Changes the pointer acceleration for the specified input device. + Change the pointer acceleration for specified input device *scroll_button disable|* - Sets the button used for scroll_method on_button_down. The button can - be given as an event name or code, which can be obtained from *libinput - debug-events*. If set to - _disable_, it disables the scroll_method on_button_down. + Set button used for scroll_method on_button_down - The button + can be given as an event name or code, which can be obtained from + *libinput debug-events*. If set to _disable_, it disables the + scroll_method on_button_down. *scroll_factor * - Changes the scroll factor for the specified input device. Scroll speed will - be scaled by the given value, which must be non-negative. + Change the scroll factor for the specified input device - Scroll + speed will be scaled by the given value, which must be non-negative. *scroll_method none|two_finger|edge|on_button_down* - Changes the scroll method for the specified input device. + Change scroll method for specified input device *tap enabled|disabled* - Enables or disables tap for specified input device. + Enable or disable tap for specified input device *tap_button_map lrm|lmr* - Specifies which button mapping to use for tapping. _lrm_ treats 1 finger as - left click, 2 fingers as right click, and 3 fingers as middle click. _lmr_ - treats 1 finger as left click, 2 fingers as middle click, and 3 fingers as - right click. + Specify which button mapping to use for tapping - _lrm_ treats 1 + finger as left click, 2 fingers as right click, and 3 fingers as + middle click. _lmr_ treats 1 finger as left click, 2 fingers as + middle click, and 3 fingers as right click. + +message + Display a line of arbitrary text. *mode * - Enter mode "". After a keybinding is processed, return to default mode + Enter mode "" - Returns to default mode, after a command is + executed. *movetonextscreen* - Move the current window to the next screen + Move currently focused window to next screen + +*movetoprevscreen* + Move currently focused window to previous screen + +*movetoscreen * + Move currently focused window to -th screen *movetoworkspace * - Move the currently focused window to the n-th workspace + Move currently focused window to -th workspace *next* Focus next window in current tile *nextscreen* - Focus the next screen + Focus next screen *only* - Remove all splits and make the current window fill the entire screen + Remove all splits and make current window fill the entire screen -*output [[pos res x rate ] | enable | disable]* - Configure the output "". and are the position of the monitor - in pixels. The top-left monitor should have the coordinates 0 0. and - specify the resolution in pixels and sets the refresh rate of - the monitor (often this is 50 or 60). The options enable and disable - enable or disable the output . Note that if is the only enabled - output, *output disable* has no effect. +*output [[pos res x rate ] | enable | disable | prio ]* + Configure output "" - + - and are the position of the + monitor in pixels. The top-left monitor should have the coordinates 0 0. + - and specify the resolution in pixels. + - sets the refresh rate of the monitor (often this is 50 or 60). + - enable and disable enable or disable . Note that if + is the only enabled output, *output disable* has + no effect. + - prio is used to set the priority of an output. If + nothing else is set, outputs are added as they request to be added + and have a numerical priority of -1. Using prio it is possible + to set priorities for outputs, where >= 1. The larger is, + the higher the priority is, that is to say, the earlier the output + will appear in the list of outputs. *prev* Focus previous window in current tile *prevscreen* - Focus the previous screen + Focus previous screen *quit* Exit cagebreak *resizedown* - Resize the current tile towards the bottom + Resize current tile towards the bottom *resizeleft* - Resize the current tile towards the left + Resize current tile towards the left *resizeright* - Resize the current tile towards the right + Resize current tile towards the right *resizeup* - Resize the current tile towards the top + Resize current tile towards the top + +*screen * + Change to -th screen *show_info* - Display info about the current setup. In particular, print the identifiers + Display information about the current setup - In particular, print the identifiers of the available inputs and outputs. *setmode * - Set the default mode to + Set default mode to *switchvt * - Switch to tty n + Switch to tty *time* Display time @@ -226,31 +294,37 @@ by prepending a line with the # symbol. Split current tile vertically *workspace * - Change to the n-th workspace + Change to -th workspace -*workspaces* - Requires a single integer larger than 1 and less than 30 as an argument. Sets the number of - workspaces to the supplied number +*workspaces * + Set number of workspaces to - is a single integer larger than 1 + and less than 30. # MODES By default, three modes are defined: *top* - The default mode. Keybindings defined in this mode can be accessed - directly, without the use of an escape key. + Default mode - Keybindings defined in this mode can be accessed + directly. + - *definekey* can be used to set keybindings for top mode. + - *setmode* can be used to set a different default mode. *root* - The command mode. Keybindings defined in this mode can be accessed - after pressing the key defined by the *escape* command. + Command mode - Keybindings defined in this mode can be accessed + after pressing the key defined by *escape*. + - *bind* can be used to set keybindings for root mode. *resize* - Resize mode. This mode is used for resizing tiles. + Resize mode - Used to resize tiles. + +*definemode* can be used to create additional modes. # KEY DEFINITIONS Keys are specified by their names as displayed for example by *xev*. -In addition, modifiers can be specified using the following syntax: + +Modifiers can be specified using the following syntax: - @@ -270,9 +344,11 @@ The supported modifiers are: *5 - Mod 5* -For example to specify the keybinding Control+t, the expression: +For example to specify the keybinding Control+t, the expression - C-t +``` +C-t +``` is used. @@ -284,10 +360,20 @@ is used. See GitHub Issues: +Mail contact: `cagebreak @ project-repo . co` + +GPG Fingerprints: + +- B15B92642760E11FE002DE168708D42451A94AB5 +- F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C +- 3ACEA46CCECD59E4C8222F791CBEB493681E8693 + # LICENSE Copyright (c) 2020-2022 The Cagebreak authors + Copyright (c) 2018-2020 Jente Hidskes + Copyright (c) 2019 The Sway authors Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 4fe5c6c..fd6584c 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,8 +1,8 @@ -cagebreak(1) "Version 1.8.3" "Cagebreak Manual" +cagebreak(1) "Version 1.9.0" "Cagebreak Manual" # NAME -cagebreak - A Wayland tiling compositor to the likes of ratpoison +cagebreak - A Wayland tiling compositor # SYNOPSIS @@ -73,10 +73,20 @@ are displayed in a message box at the top right of the screen. See GitHub Issues: +Mail contact: `cagebreak @ project-repo . co` + +GPG Fingerprints: + +- B15B92642760E11FE002DE168708D42451A94AB5 +- F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C +- 3ACEA46CCECD59E4C8222F791CBEB493681E8693 + # LICENSE Copyright (c) 2020-2022 The Cagebreak authors + Copyright (c) 2018-2020 Jente Hidskes + Copyright (c) 2019 The Sway authors Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/meson.build b/meson.build index 10afb69..b4c7dfd 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.8.3', + version: '1.9.0', license: 'MIT', default_options: [ 'c_std=c11', @@ -206,16 +206,16 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.20.0', 'wayland_cursor': '1.20.0', - 'wlroots': '0.15.0', - 'xkbcommon': '1.3.1', - 'fontconfig': '2.13.94', - 'libinput': '1.19.3', - 'libevdev': '1.12.0', + 'wlroots': '0.15.1', + 'xkbcommon': '1.4.0', + 'fontconfig': '2.14.0', + 'libinput': '1.20.1', + 'libevdev': '1.12.1', 'libudev': '250', 'pixman': '0.40.0', - 'pango': '1.50.3', - 'cairo': '1.17.4', - 'pangocairo': '1.50.3', + 'pango': '1.50.7', + 'cairo': '1.17.6', + 'pangocairo': '1.50.7', 'math': '-1' } @@ -241,7 +241,7 @@ foreach name, dep : cagebreak_dependencies_dict endforeach reproducible_build_compiler = 'gcc' -reproducible_build_compiler_version = '11.1.0' +reproducible_build_compiler_version = '11.2.0' if cc.get_id() != reproducible_build_compiler warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in the README section "Reproducible Builds" (' + reproducible_build_compiler + ').') @@ -270,7 +270,7 @@ if get_option('man-pages') output : 'cagebreak.1', input : 'man/cagebreak.1.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1638785664 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1650564686 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir1 ) @@ -279,7 +279,7 @@ if get_option('man-pages') output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1638785664 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1650564686 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir5 ) diff --git a/message.h b/message.h index 9a4e53e..b1081ab 100644 --- a/message.h +++ b/message.h @@ -16,6 +16,13 @@ enum cg_message_align { CG_MESSAGE_CENTER, }; +struct cg_message_config { + char *font; + int display_time; + float bg_color[4]; + float fg_color[4]; +}; + struct cg_message { struct wlr_box *position; struct wlr_texture *message; diff --git a/output.c b/output.c index 3ce60c4..90f1f7e 100644 --- a/output.c +++ b/output.c @@ -29,7 +29,9 @@ #include #include #include +#if CG_HAS_XWAYLAND #include +#endif #include "keybinding.h" #include "message.h" diff --git a/output.h b/output.h index 7a0dc7c..ca44a6b 100644 --- a/output.h +++ b/output.h @@ -23,11 +23,18 @@ struct cg_output { struct cg_workspace **workspaces; struct wl_list messages; int curr_workspace; + int priority; struct cg_view *last_scanned_out_view; struct wl_list link; // cg_server::outputs }; +struct cg_output_priorities { + char *ident; + int priority; + struct wl_list link; +}; + enum output_status { OUTPUT_ENABLE, OUTPUT_DISABLE, OUTPUT_DEFAULT }; struct cg_output_config { @@ -35,6 +42,7 @@ struct cg_output_config { struct wlr_box pos; char *output_name; float refresh_rate; + int priority; struct wl_list link; // cg_server::output_config }; diff --git a/parse.c b/parse.c index 4bbf72d..92a8943 100644 --- a/parse.c +++ b/parse.c @@ -8,6 +8,7 @@ #include "input_manager.h" #include "keybinding.h" +#include "message.h" #include "output.h" #include "parse.h" #include "server.h" @@ -122,7 +123,7 @@ parse_input_config(char **saveptr, char **errstr) { char *ident = NULL; if(cfg == NULL) { *errstr = - log_error("Failed to allocate memory for output configuration"); + log_error("Failed to allocate memory for input configuration"); goto error; } @@ -340,6 +341,9 @@ parse_input_config(char **saveptr, char **errstr) { "Invalid option \"%s\" to setting \"tap_button_map\"", value); goto error; } + } else { + *errstr = log_error("Invalid option to command \"input\""); + goto error; } free(value); @@ -503,6 +507,8 @@ parse_output_config_keyword(char *key_str, enum output_status *status) { } if(strcmp(key_str, "pos") == 0) { *status = OUTPUT_DEFAULT; + } else if(strcmp(key_str, "prio") == 0) { + *status = OUTPUT_DEFAULT; } else if(strcmp(key_str, "enable") == 0) { *status = OUTPUT_ENABLE; } else if(strcmp(key_str, "disable") == 0) { @@ -521,6 +527,11 @@ parse_output_config(char **saveptr, char **errstr) { log_error("Failed to allocate memory for output configuration"); goto error; } + cfg->status = OUTPUT_DEFAULT; + cfg->pos.x = -1; + cfg->output_name = NULL; + cfg->refresh_rate = 0; + cfg->priority = -1; char *name = strtok_r(NULL, " ", saveptr); if(name == NULL) { *errstr = @@ -529,7 +540,7 @@ parse_output_config(char **saveptr, char **errstr) { } char *key_str = strtok_r(NULL, " ", saveptr); if(parse_output_config_keyword(key_str, &(cfg->status)) != 0) { - *errstr = log_error("Expected keyword \"pos\", \"enable\" or " + *errstr = log_error("Expected keyword \"pos\", \"prio\", \"enable\" or " "\"disable\" in output configuration for output %s", name); goto error; @@ -539,6 +550,18 @@ parse_output_config(char **saveptr, char **errstr) { return cfg; } + if(strcmp(key_str, "prio") == 0) { + cfg->priority = parse_uint(saveptr, " "); + if(cfg->priority < 0) { + *errstr = log_error( + "Error parsing priority of output configuration for output %s", + name); + goto error; + } + cfg->output_name = strdup(name); + return cfg; + } + cfg->pos.x = parse_uint(saveptr, " "); if(cfg->pos.x < 0) { *errstr = log_error( @@ -606,6 +629,74 @@ error: return NULL; } +struct cg_message_config * +parse_message_config(char **saveptr, char **errstr) { + struct cg_message_config *cfg = calloc(1, sizeof(struct cg_message_config)); + if(cfg == NULL) { + *errstr = + log_error("Failed to allocate memory for message configuration"); + goto error; + } + + cfg->bg_color[0] = -1; + cfg->fg_color[0] = -1; + cfg->display_time = -1; + cfg->font = NULL; + + char *setting = strtok_r(NULL, " ", saveptr); + if(setting == NULL) { + *errstr = log_error( + "Expected setting to be set for message configuration, got none"); + goto error; + } + + if(strcmp(setting, "font") == 0) { + cfg->font = strdup(*saveptr); + if(cfg->font == NULL) { + *errstr = log_error("Unable to allocate memory for font descrition " + "in command \"message\""); + goto error; + } + } else if(strcmp(setting, "display_time") == 0) { + cfg->display_time = parse_uint(saveptr, " "); + if(cfg->display_time < 0) { + *errstr = + log_error("Error parsing command \"configure_message " + "display_time\", expected a non-negative integer"); + goto error; + } + } else if(strcmp(setting, "bg_color") == 0) { + for(int i = 0; i < 4; ++i) { + cfg->bg_color[i] = parse_float(saveptr, " "); + if(cfg->bg_color[i] == FLT_MIN) { + *errstr = log_error( + "Error parsing command \"configure_message bg_color\", " + "expected 4 float values separated by spaces"); + goto error; + } + } + } else if(strcmp(setting, "fg_color") == 0) { + for(int i = 0; i < 4; ++i) { + cfg->fg_color[i] = parse_float(saveptr, " "); + if(cfg->fg_color[i] == FLT_MIN) { + *errstr = log_error( + "Error parsing command \"configure_message bg_color\", " + "expected 4 float values separated by spaces"); + goto error; + } + } + } else { + *errstr = log_error("Invalid option to command \"configure_message\""); + goto error; + } + return cfg; + +error: + wlr_log(WLR_ERROR, "Message configuration must be of the form " + "'configure_message '"); + return NULL; +} + int parse_command(struct cg_server *server, struct keybinding *keybinding, char *saveptr, char **errstr) { @@ -641,6 +732,15 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, keybinding->action = KEYBINDING_LAYOUT_FULLSCREEN; } else if(strcmp(action, "abort") == 0) { keybinding->action = KEYBINDING_NOOP; + } else if(strcmp(action, "message") == 0) { + keybinding->action = KEYBINDING_DISPLAY_MESSAGE; + if(saveptr == NULL) { + *errstr = + log_error("Not enough paramaters to \"message\". Expected " + "string to display."); + return -1; + } + keybinding->data.c = strdup(saveptr); } else if(strcmp(action, "time") == 0) { keybinding->action = KEYBINDING_SHOW_TIME; } else if(strcmp(action, "nextscreen") == 0) { @@ -669,6 +769,23 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, } else if(strcmp(action, "resizeup") == 0) { keybinding->action = KEYBINDING_RESIZE_TILE_VERTICAL; keybinding->data.i = -10; + } else if(strcmp(action, "screen") == 0) { + keybinding->action = KEYBINDING_SWITCH_OUTPUT; + char *noutp_str = strtok_r(NULL, " ", &saveptr); + if(noutp_str == NULL) { + *errstr = + log_error("Expected argument for \"output\" action, got none."); + return -1; + } + + long outp = strtol(noutp_str, NULL, 10); + if(outp < 1) { + *errstr = log_error("Workspace number must be an integer number " + "larger or equal to 1. Got %ld", + outp); + return -1; + } + keybinding->data.u = outp; } else if(strcmp(action, "workspace") == 0) { keybinding->action = KEYBINDING_SWITCH_WORKSPACE; char *nws_str = strtok_r(NULL, " ", &saveptr); @@ -686,12 +803,29 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, return -1; } keybinding->data.u = ws - 1; + } else if(strcmp(action, "movetoscreen") == 0) { + keybinding->action = KEYBINDING_MOVE_VIEW_TO_OUTPUT; + char *noutp_str = strtok_r(NULL, " ", &saveptr); + if(noutp_str == NULL) { + *errstr = log_error( + "Expected argument for \"movetoscreen\" action, got none."); + return -1; + } + + long outp = strtol(noutp_str, NULL, 10); + if(outp < 1) { + *errstr = log_error("Output number must be an integer larger or " + "equal to 1. Got %ld", + outp); + return -1; + } + keybinding->data.u = outp; } else if(strcmp(action, "movetoworkspace") == 0) { keybinding->action = KEYBINDING_MOVE_VIEW_TO_WORKSPACE; char *nws_str = strtok_r(NULL, " ", &saveptr); if(nws_str == NULL) { *errstr = log_error( - "Expected argument for \"workspace\" action, got none."); + "Expected argument for \"movetoworkspace\" action, got none."); return -1; } @@ -720,7 +854,11 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, } else if(strcmp(action, "focusdown") == 0) { keybinding->action = KEYBINDING_FOCUS_BOTTOM; } else if(strcmp(action, "movetonextscreen") == 0) { - keybinding->action = KEYBINDING_MOVE_VIEW_TO_NEXT_OUTPUT; + keybinding->action = KEYBINDING_MOVE_VIEW_TO_CYCLE_OUTPUT; + keybinding->data.b = false; + } else if(strcmp(action, "movetoprevscreen") == 0) { + keybinding->action = KEYBINDING_MOVE_VIEW_TO_CYCLE_OUTPUT; + keybinding->data.b = true; } else if(strcmp(action, "switchvt") == 0) { keybinding->action = KEYBINDING_CHANGE_TTY; char *ntty = strtok_r(NULL, " ", &saveptr); @@ -735,13 +873,12 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, keybinding->action = KEYBINDING_SWITCH_MODE; char *mode = strtok_r(NULL, " ", &saveptr); if(mode == NULL) { - *errstr = - log_error("Expected mode after \"switch_mode\". Got nothing."); + *errstr = log_error("Expected mode after \"mode\". Got nothing."); return -1; } int mode_idx = get_mode_index_from_name(server->modes, mode); if(mode_idx == -1) { - *errstr = log_error("Unknown mode \"%s\" for switch_mode", mode); + *errstr = log_error("Unknown mode \"%s\" for \"mode\"", mode); return -1; } keybinding->data.u = (unsigned int)mode_idx; @@ -808,6 +945,12 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, if(keybinding->data.i_cfg == NULL) { return -1; } + } else if(strcmp(action, "configure_message") == 0) { + keybinding->action = KEYBINDING_CONFIGURE_MESSAGE; + keybinding->data.m_cfg = parse_message_config(&saveptr, errstr); + if(keybinding->data.m_cfg == NULL) { + return -1; + } } else { *errstr = log_error("Error, unsupported action \"%s\".", action); return -1; diff --git a/seat.c b/seat.c index 280b3ea..5449aa4 100644 --- a/seat.c +++ b/seat.c @@ -138,7 +138,6 @@ remove_touch(struct cg_seat *seat, struct cg_touch *touch) { if(!touch) { return; } - wl_list_remove(&touch->link); wlr_cursor_detach_input_device(seat->cursor, touch->device->wlr_device); --seat->num_touch; free(touch); diff --git a/signatures/1.8.3-cagebreak-config.5.sig b/signatures/1.8.3-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..2c2521097806777388e10ec2a54e39a8da910cda GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%7sLR{#nL5b{@R z(`FTGxd?I(|8M?9naG+*bCfpF;j)QRc&QC*44^0XGuM1wKjt7{QA{%7v_k=4ON<_ef zWpIiARd7*H2y~9j8!;;;+xk&9L*$MNX6n7q8t1$9CQO#YLa0(1APg=g%{ZqF6p z!8p*YjO|nA~74VTs_?a2iTn{q>gnpt8 zhAzn7^PRQn9uO`sz;+bL`{1+~^{0xFiM>^^a_ch zK19HgeOPOSJI$t(fh;&En3U?~hm-W^&PX=AOb*Ub&o#mc66T~NI@$v(QTt7ikTf87 EK3}vC2><{9 literal 0 HcmV?d00001 diff --git a/signatures/1.8.3-cagebreak.1.sig b/signatures/1.8.3-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..e5280a3e9428d3ac0a136e52a68348cebda750b5 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%7sLQ~(MI5b{@R z(`FTGxvGy3|3yA!!;*cYZs2L&&Zx2#rsczCz-Ab3%~DnXeWM}a3u$4`d;#iudf8UE z85-YQht@sU;YgqpRURr~pHvujl#ABOh9n4UG_sWImrSVTCXQ7YJts^8^#Ue7nC!bY zxhUh4^E9aVcmj8u`xq+d5?*4j(Eh#7^hrBJeTtv2<(iiCrPJ@f3f4BUl@*#p#Gj&S z=Q(7o-Gst{pOSCUj3I&~`Q^VxexaY7kb#JnbT#JPwc?l>W*_Qyc_kYg6xee6CUfD) zUn+KI%835Blg8(ka48(@b$kXxfdEUqKc-(A2(n#DEw7gS+mDpia@)YI5~M<)DgzRS zW<>I?dK?E4Q34my?yWAL-dP#RMv{2qsR59v1UL|PTRYx$+{L_2_7s@ZtIeyry}V5j z9>O8kfT{L!xJL5xmEI>?2hEHu%X9MVkb`J5f5q>bYnOq*b1|EnhKz?bH&WBw9e}QRu(t8T@Tz2V_MXm|@QsvS4!yJYD=j8;yVaeZ;*Wtz=UJwN3sZjXv78Czkq? zpKNfg!UK^|UpjDhk7RHs8-kHvo}1Z=@(^hkz7bJnCSQgns?}M>HQ4u9R=+=4;#!9y EkJ_6S%m4rY literal 0 HcmV?d00001 diff --git a/signatures/1.8.3.sig b/signatures/1.8.3.sig new file mode 100644 index 0000000000000000000000000000000000000000..6ac0f6398b4e28fed3e1542b7801fd3dfc04345d GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%7sLQUD4G5b{@R z(`FTGxsHzy{Si!g6bYArk3RmZG~KkLvUkttH*dM%C+&*7?wlitog&*iAaZf%mgP-M zu^0!#-NEjWC`6f>bKKr-_nGtivVVGfaWHZob2(H0K)B8>CcMjOp;JS zuIIA6PzLsb(2famh&|+fRaZQX+HvI%Ir;MVzrk~FUY-7#gq3lF%k5xBn+SCNystm6H|WtCT2dJNnq!JIfk&VBDwdoy$5-IQ!Oe{2JsOzul;oWCB%c zk}&nU(Cz2DmFN2uqj6M~TZ^^C`sm7;5zH1|d!MJk3MYrMG@+mW zu_B!hLyCsptEvb($9?ogTecWcHapn(b$l+bQiPNJm4^bA=Jo}U=e+ye$JCou%?%$c z99UyJiQPJnbZpTJeZ$$|nFzmY2ORLI));==hW$&1& zePyl%{uIFE7|P<4Ug=Q!tLtKd#EH`^o~VvTVpW20Q3 zQKwL?vPxdOX)_*VO!_X{tEt}=qZPj7c`$j>7B8nP9^OKGKj7JDA`%mEhD0%$Nww5c zCR7d5NwmW6D(b$vw@99AsC;o}^{3*X$=61%1C1eCI_kZCYC(QP6&SB$+QqU_LPa$u zOS?D%NXh*lr*`_`7FL84Ff51wXeQK26F*W4!_Ou+>{O_EyV#yzQ{pJeXC51)*Ru#r E&X@KM`v3p{ literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%7sLR{#nL5b{@R z(`FTGxd?I(|8M?9naG+*bCfpF;j)QRc&QC*44^0XGuM1wKjt7{QA{%7v_k=4ON<_ef zWpIiARd7*H2y~9j8!;;;+xk&9L*$MNX6n7q8t1$9CQO#YLa0(1APg=g%{ZqF6p z!8p*YjO|nA~74VTs_?a2iTn{q>gnpt8 zhAzn7^PRQn9uO`sz;+bL`{1+~^{0xFiM>^^a_ch zK19HgeOPOSJI$t(fh;&En3U?~hm-W^&PX=AOb*Ub&o#mc66T~NI@$v(QTt7ikTf87 EK3}vC2><{9 diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index e5280a3e9428d3ac0a136e52a68348cebda750b5..47ba7f2978d4cfa6d59e5b25d8e340db574ad9ef 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%BpPe*g*z5TM6H zgo=}DIUWoz{7hfGwj z^imey0J@ey-HnU+B@C^oa-Ib0cEc4X%ehZ(a2a_vs23Y_k3lCVFk{MGsxw>qMvjWt zRDDJP;fxyhvo+2LrGo`xb-~fRB{I>mUl;lw!y;n<-D%{_>@RgJO(~P-@P}4E>)1c? zBtl!)Kzq55_Gb4?)o@(YjfVr@Mr>^)azcSCeaV34$NfO!AF=9pvR%+_wdk@8%mw;$ z=u_9NpuLBE2J0hv<4BIY4TUx3as)h4-eVr;vq7{%DNML|$D0Ii-8;17x_#TyM=BK? zPz`O`y}Y#QX9t@YxtIJh*M=^Xt+^uZ1j?Wi`N`I0rVLX!K+ykoCyBfWv}fV~c!Z*V z@eNWSR{CACsW6`TSjmP-8>e#vHh8A>rRyfhvA#IVeC8-r62C27bbVL&1A>rszmJ1)If? zx)<_hI(xdUgSHKi+2oj7bLWd14Ry)Dxl0Q6a}*ykRohKejfqufwkluKOkIs=F^dK) z(xGR7HVsYvD_98Ti4<(0n98&j0ex#xY%DqS%%E+FD|YOcUY3i)f<^at+w@s$xcxM- ET8sA(CjbBd literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%7sLQ~(MI5b{@R z(`FTGxvGy3|3yA!!;*cYZs2L&&Zx2#rsczCz-Ab3%~DnXeWM}a3u$4`d;#iudf8UE z85-YQht@sU;YgqpRURr~pHvujl#ABOh9n4UG_sWImrSVTCXQ7YJts^8^#Ue7nC!bY zxhUh4^E9aVcmj8u`xq+d5?*4j(Eh#7^hrBJeTtv2<(iiCrPJ@f3f4BUl@*#p#Gj&S z=Q(7o-Gst{pOSCUj3I&~`Q^VxexaY7kb#JnbT#JPwc?l>W*_Qyc_kYg6xee6CUfD) zUn+KI%835Blg8(ka48(@b$kXxfdEUqKc-(A2(n#DEw7gS+mDpia@)YI5~M<)DgzRS zW<>I?dK?E4Q34my?yWAL-dP#RMv{2qsR59v1UL|PTRYx$+{L_2_7s@ZtIeyry}V5j z9>O8kfT{L!xJL5xmEI>?2hEHu%X9MVkb`J5f5q>bYnOq*b1|EnhKz?bH&WBw9e}QRu(t8T@Tz2V_MXm|@QsvS4!yJYD=j8;yVaeZ;*Wtz=UJwN3sZjXv78Czkq? zpKNfg!UK^|UpjDhk7RHs8-kHvo}1Z=@(^hkz7bJnCSQgns?}M>HQ4u9R=+=4;#!9y EkJ_6S%m4rY diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 6ac0f6398b4e28fed3e1542b7801fd3dfc04345d..2cc14a8392a06e2f4bee8076cd2bd3acdee2f4cc 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%BpPd;kgw5TM6H zgo6OjSbm&_ZEJ$$GagLEuabvlKYurs-dCP z#3oIYm2Oi?{pu1ZF{He;gxqi@kqjd%|G3QZ>3@Su%n~0l%d#3a{ckK9_K0WjWfPAo zNkknL(M{;s?|M55Zd zW+nlT^h+U-g9YKl2?|kQrMea*2@zxm+<=NDnI~D=obs&(((46JW6TfX%W!R40dn0M z1VnSD9d`RJzY)dZuKUv)>h_&ZLNWeJV2*b-Hp$qj5~{~N!;h{G-CT&b@|1#s8oxAP z^PDV3tXr>ju?9Yf-$rPOgG)x5l?Q8%ncMRxa@} zsZUn+m@#F3baYgr#wwd+>S)gm`y7V>e&`8IYafPMo;jl9?x4+M1#Qrlh6{?Ii&$zi z=E{C}c0!`SQ5s9Vyq%1}8_@_ANb&Xk8+QE1@YTdJ(iRM3sX Ev3HpTg#Z8m literal 566 zcmV-60?GY}0y6{v0SEvc79j+QYm%>XjF(OTWxqo5S8LN|6>GT#0%7sLQUD4G5b{@R z(`FTGxsHzy{Si!g6bYArk3RmZG~KkLvUkttH*dM%C+&*7?wlitog&*iAaZf%mgP-M zu^0!#-NEjWC`6f>bKKr-_nGtivVVGfaWHZob2(H0K)B8>CcMjOp;JS zuIIA6PzLsb(2famh&|+fRaZQX+HvI%Ir;MVzrk~FUY-7#gq3lF%k5xBn+SCNystm6H|WtCT2dJNnq!JIfk&VBDwdoy$5-IQ!Oe{2JsOzul;oWCB%c zk}&nU(Cz2DmFN2uqj6M~TZ^^C`sm7; #include @@ -14,7 +15,9 @@ #include #include #include +#if CG_HAS_XWAYLAND #include +#endif #include "output.h" #include "server.h" From 728c2e4ec8f72ac28509ec0eb827781ca0b29898 Mon Sep 17 00:00:00 2001 From: project-repo Date: Fri, 29 Jul 2022 22:41:17 +0200 Subject: [PATCH 08/19] Release 1.9.1 - Fix Issue 35 in Bugs.md (nextscreen/prevscreen feature broken) - Fix Issue 36 in Bugs.md (configure_message feature broken) - Fix Issue 37 in Bugs.md (screen/movetoscreen feature broken) --- Bugs.md | 24 ++++ Hashes.md | 15 +++ cagebreak.c | 14 ++- keybinding.c | 143 +++++++++++++++++++++--- man/cagebreak-config.5.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 22 ++-- message.c | 17 +-- server.h | 2 + signatures/1.9.0-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/1.9.0-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.9.0.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 15 files changed, 203 insertions(+), 38 deletions(-) create mode 100644 signatures/1.9.0-cagebreak-config.5.sig create mode 100644 signatures/1.9.0-cagebreak.1.sig create mode 100644 signatures/1.9.0.sig diff --git a/Bugs.md b/Bugs.md index 2c909fe..822f3f6 100644 --- a/Bugs.md +++ b/Bugs.md @@ -628,3 +628,27 @@ wlroots-0.15.1 Cagebreak crashed when a touch device was removed due to a call to `wl_list_remove` on a pointer which was never initialized. +## Issue 35 + + * github issue number: N/A + * Fixed: 1.9.1 + +Cagebreak 1.9.0 broke the nextscreen and prevscreen functionality. +This issue was not present in earlier releases. + +## Issue 36 + + * github issue number: N/A + * Fixed: 1.9.1 + +Cagebreak 1.9.0 broke the configure_message functionality. +This issue was not present in earlier releases. + +## Issue 37 + + * github issue number: N/A + * Fixed: 1.9.1 + +Cagebreak 1.9.0 broke the screen/movetoscreen functionality. +This issue was not present in earlier releases. + diff --git a/Hashes.md b/Hashes.md index abffe85..97d6217 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,20 @@ # Hashes +1.9.1 cagebreak + + * sha 256: 262c67170eb2a39174d40f97d940707029dca0b2b613b514a1cca29152a12665 + * sha 512: bbd962eaf90441338a67215fc7ac0a717b8cb7bd93ce7ef7ed446aa1df9f4e44026994cc1172e6245e5cd4b9c588150ed9c894941069c5c132c9e2009523c241 + +1.9.1 cagebreak.1 + + * sha 256: f9c1ee94c0788b98f1e8d93433a0e39d4265ed5c8107e964648da11c60c995ed + * sha 512: 1d39748c42a56852ce21aa5ea872160da0810d0539901f6c307b141d4c2545c52a7de98d924e4e45827dafa8cb76b483abf5e02403e6536f69d2144575d3dfdb + +1.9.1 cagebreak-config.5 + + * sha 256: 2b0d5655e01942cb5130a95c7209e32c1ce3f44411f2a3294a160d6a2232bef4 + * sha 512: c13a92e091e56aad099c12c4bf652943bf43dad5aace61677af992331a2700d3d2f433cd2a674cbc2cc080e971169516973835c44416de555a85b5aae9da9a9d + 1.9.0 cagebreak * sha 256: 91096b4c558970666c5ef1ebd5c16301fbb40b52b34a73589f18a14c48edf5c1 diff --git a/cagebreak.c b/cagebreak.c index 00712f9..97f4f91 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -297,7 +297,18 @@ main(int argc, char *argv[]) { } server.nws = 1; - server.message_timeout = 2; + server.message_config.fg_color[0] = 0.0; + server.message_config.fg_color[1] = 0.0; + server.message_config.fg_color[2] = 0.0; + server.message_config.fg_color[3] = 1.0; + + server.message_config.bg_color[0] = 0.9; + server.message_config.bg_color[1] = 0.85; + server.message_config.bg_color[2] = 0.85; + server.message_config.bg_color[3] = 1.0; + + server.message_config.display_time = 2; + server.message_config.font = strdup("pango:Monospace 10"); event_loop = wl_display_get_event_loop(server.wl_display); sigint_source = @@ -626,6 +637,7 @@ end: wlr_output_layout_destroy(server.output_layout); free(server.input); + free(server.message_config.font); pango_cairo_font_map_set_default(NULL); cairo_debug_reset_static_data(); FcFini(); diff --git a/keybinding.c b/keybinding.c index 5207d24..ec83acc 100644 --- a/keybinding.c +++ b/keybinding.c @@ -76,6 +76,12 @@ keybinding_free(struct keybinding *keybinding, bool recursive) { free(keybinding->data.i_cfg->mapped_to_output); } free(keybinding->data.o_cfg); + break; + case KEYBINDING_CONFIGURE_MESSAGE: + if(keybinding->data.m_cfg->font != NULL) { + free(keybinding->data.m_cfg->font); + } + break; default: break; } @@ -594,23 +600,8 @@ into_process(const char *command) { } void -keybinding_cycle_outputs(struct cg_server *server, bool reverse) { - if(reverse) { - server->curr_output = wl_container_of(server->curr_output->link.prev, - server->curr_output, link); - } else { - server->curr_output = wl_container_of(server->curr_output->link.next, - server->curr_output, link); - } - if(&server->curr_output->link == &server->outputs) { - if(reverse) { - server->curr_output = wl_container_of( - server->curr_output->link.prev, server->curr_output, link); - } else { - server->curr_output = wl_container_of( - server->curr_output->link.next, server->curr_output, link); - } - } +set_output(struct cg_server *server, struct cg_output *output) { + server->curr_output = output; seat_set_focus( server->seat, server->curr_output->workspaces[server->curr_output->curr_workspace] @@ -618,6 +609,26 @@ keybinding_cycle_outputs(struct cg_server *server, bool reverse) { message_printf(server->curr_output, "Current Output"); } +void +keybinding_cycle_outputs(struct cg_server *server, bool reverse) { + struct cg_output *output = NULL; + if(reverse) { + output = wl_container_of(server->curr_output->link.prev, + server->curr_output, link); + } else { + output = wl_container_of(server->curr_output->link.next, + server->curr_output, link); + } + if(&output->link == &server->outputs) { + if(reverse) { + output = wl_container_of(output->link.prev, output, link); + } else { + output = wl_container_of(output->link.next, output, link); + } + } + set_output(server, output); +} + /* Cycle through views, whereby the workspace does not change */ void keybinding_cycle_views(struct cg_server *server, bool reverse) { @@ -837,6 +848,49 @@ keybinding_set_background(struct cg_server *server, float *bg) { server->bg_color[2] = bg[2]; } +void +keybinding_switch_output(struct cg_server *server, int output) { + struct cg_output *it; + int count = 1; + wl_list_for_each(it, &server->outputs, link) { + if(count == output) { + set_output(server, it); + return; + } + ++count; + } + message_printf(server->curr_output, "Output %d does not exist", output); + return; +} + +void +keybinding_move_view_to_output(struct cg_server *server, int output_num) { + struct cg_view *view = + server->curr_output->workspaces[server->curr_output->curr_workspace] + ->focused_tile->view; + if(view != NULL) { + wl_list_remove(&view->link); + server->curr_output->workspaces[server->curr_output->curr_workspace] + ->focused_tile->view = NULL; + keybinding_cycle_views(server, false); + if(server->curr_output->workspaces[server->curr_output->curr_workspace] + ->focused_tile->view == NULL) { + seat_set_focus(server->seat, NULL); + } + } + keybinding_switch_output(server, output_num); + if(view != NULL) { + struct cg_workspace *ws = + server->curr_output + ->workspaces[server->curr_output->curr_workspace]; + view->workspace = ws; + wl_list_insert(&ws->views, &view->link); + ws->focused_tile->view = view; + view_maximize(view, ws->focused_tile); + seat_set_focus(server->seat, view); + } +} + void keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) { struct cg_view *view = @@ -865,6 +919,23 @@ keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) { } } +void +merge_config(struct cg_output_config *config_new, + struct cg_output_config *config_old) { + if(config_new->status == OUTPUT_DEFAULT) { + config_new->status = config_old->status; + } + if(config_new->pos.x == -1) { + config_new->pos = config_old->pos; + } + if(config_new->refresh_rate == 0) { + config_new->refresh_rate = config_old->refresh_rate; + } + if(config_new->priority == -1) { + config_new->priority = config_old->priority; + } +} + void keybinding_configure_output(struct cg_server *server, struct cg_output_config *cfg) { @@ -883,6 +954,7 @@ keybinding_configure_output(struct cg_server *server, wl_list_for_each_safe(it, tmp, &server->output_config, link) { if(strcmp(config->output_name, it->output_name) == 0) { wl_list_remove(&it->link); + merge_config(config, it); free(it->output_name); free(it); } @@ -910,6 +982,30 @@ keybinding_configure_input(struct cg_server *server, cg_input_apply_config(cfg, server); } +void +keybinding_configure_message(struct cg_server *server, + struct cg_message_config *config) { + if(config->font != NULL) { + free(server->message_config.font); + server->message_config.font = strdup(config->font); + } + if(config->display_time != -1) { + server->message_config.display_time = config->display_time; + } + if(config->bg_color[0] != -1) { + server->message_config.bg_color[0] = config->bg_color[0]; + server->message_config.bg_color[1] = config->bg_color[1]; + server->message_config.bg_color[2] = config->bg_color[2]; + server->message_config.bg_color[3] = config->bg_color[3]; + } + if(config->fg_color[0] != -1) { + server->message_config.fg_color[0] = config->fg_color[0]; + server->message_config.fg_color[1] = config->fg_color[1]; + server->message_config.fg_color[2] = config->fg_color[2]; + server->message_config.fg_color[3] = config->fg_color[3]; + } +} + void keybinding_configure_input_dev(struct cg_server *server, struct cg_input_config *cfg) {} @@ -950,9 +1046,15 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_CYCLE_TILES: keybinding_cycle_tiles(server, data.b); break; + case KEYBINDING_CYCLE_OUTPUT: + keybinding_cycle_outputs(server, data.b); + break; case KEYBINDING_SWITCH_WORKSPACE: keybinding_switch_ws(server, data.u); break; + case KEYBINDING_SWITCH_OUTPUT: + keybinding_switch_output(server, data.u); + break; case KEYBINDING_SWITCH_MODE: server->seat->mode = data.u; break; @@ -981,6 +1083,10 @@ run_action(enum keybinding_action action, struct cg_server *server, keybinding_move_view_to_workspace(server, data.u); break; } + case KEYBINDING_MOVE_VIEW_TO_OUTPUT: { + keybinding_move_view_to_output(server, data.u); + break; + } case KEYBINDING_SWAP_LEFT: { swap_tile_left( server->curr_output->workspaces[server->curr_output->curr_workspace] @@ -1048,6 +1154,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_CONFIGURE_OUTPUT: keybinding_configure_output(server, data.o_cfg); break; + case KEYBINDING_CONFIGURE_MESSAGE: + keybinding_configure_message(server, data.m_cfg); + break; case KEYBINDING_CONFIGURE_INPUT: keybinding_configure_input(server, data.i_cfg); break; diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index b931db4..541e713 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 1.9.0" "Cagebreak Manual" +cagebreak-config(5) "Version 1.9.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index fd6584c..7ef7963 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.9.0" "Cagebreak Manual" +cagebreak(1) "Version 1.9.1" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index b4c7dfd..172741f 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('cagebreak', 'c', - version: '1.9.0', + version: '1.9.1', license: 'MIT', default_options: [ 'c_std=c11', @@ -204,18 +204,18 @@ cagebreak_dependencies_dict = { reproducible_build_versions = { 'server_protos': '-1', 'wayland_server': '1.19.0', - 'wayland_client': '1.20.0', - 'wayland_cursor': '1.20.0', + 'wayland_client': '1.21.0', + 'wayland_cursor': '1.21.0', 'wlroots': '0.15.1', - 'xkbcommon': '1.4.0', + 'xkbcommon': '1.4.1', 'fontconfig': '2.14.0', - 'libinput': '1.20.1', + 'libinput': '1.21.0', 'libevdev': '1.12.1', - 'libudev': '250', + 'libudev': '251', 'pixman': '0.40.0', - 'pango': '1.50.7', + 'pango': '1.50.8', 'cairo': '1.17.6', - 'pangocairo': '1.50.7', + 'pangocairo': '1.50.8', 'math': '-1' } @@ -241,7 +241,7 @@ foreach name, dep : cagebreak_dependencies_dict endforeach reproducible_build_compiler = 'gcc' -reproducible_build_compiler_version = '11.2.0' +reproducible_build_compiler_version = '12.1.0' if cc.get_id() != reproducible_build_compiler warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in the README section "Reproducible Builds" (' + reproducible_build_compiler + ').') @@ -270,7 +270,7 @@ if get_option('man-pages') output : 'cagebreak.1', input : 'man/cagebreak.1.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1650564686 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1658688233 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir1 ) @@ -279,7 +279,7 @@ if get_option('man-pages') output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1650564686 ; @0@ < @INPUT@'.format(scdoc.path())], + command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1658688233 ; @0@ < @INPUT@'.format(scdoc.path())], install: true, install_dir: mandir5 ) diff --git a/message.c b/message.c index 0bcb5f1..9e600bb 100644 --- a/message.c +++ b/message.c @@ -35,7 +35,6 @@ struct wlr_texture * create_message_texture(const char *string, const struct cg_output *output) { const int WIDTH_PADDING = 8; const int HEIGHT_PADDING = 2; - const char *font = "pango:Monospace 10"; struct wlr_texture *texture; double scale = output->wlr_output->scale; @@ -60,7 +59,8 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_font_options_set_subpixel_order( fo, to_cairo_subpixel_order(output->wlr_output->subpixel)); cairo_set_font_options(c, fo); - get_text_size(c, font, &width, &height, NULL, scale, "%s", string); + get_text_size(c, output->server->message_config.font, &width, &height, NULL, + scale, "%s", string); width += 2 * WIDTH_PADDING; height += 2 * HEIGHT_PADDING; cairo_surface_destroy(dummy_surface); @@ -72,16 +72,19 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST); cairo_set_font_options(cairo, fo); cairo_font_options_destroy(fo); - cairo_set_source_rgba(cairo, 0.9, 0.85, 0.85, 1.0); + float *bg_col = output->server->message_config.bg_color; + cairo_set_source_rgba(cairo, bg_col[0], bg_col[1], bg_col[2], bg_col[3]); cairo_paint(cairo); PangoContext *pango = pango_cairo_create_context(cairo); - cairo_set_source_rgba(cairo, 0, 0, 0, 1); + float *fg_col = output->server->message_config.fg_color; + cairo_set_source_rgba(cairo, fg_col[0], fg_col[1], fg_col[2], fg_col[3]); cairo_set_line_width(cairo, 2); cairo_rectangle(cairo, 0, 0, width, height); cairo_stroke(cairo); cairo_move_to(cairo, WIDTH_PADDING, HEIGHT_PADDING); - pango_printf(cairo, font, scale, "%s", string); + pango_printf(cairo, output->server->message_config.font, scale, "%s", + string); cairo_surface_flush(surface); unsigned char *data = cairo_image_surface_get_data(surface); @@ -175,7 +178,7 @@ message_printf(struct cg_output *output, const char *fmt, ...) { message_set_output(output, buffer, box, CG_MESSAGE_TOP_RIGHT); free(buffer); - alarm(output->server->message_timeout); + alarm(output->server->message_config.display_time); } #if CG_HAS_FANALYZE #pragma GCC diagnostic pop @@ -194,7 +197,7 @@ message_printf_pos(struct cg_output *output, struct wlr_box *position, message_set_output(output, buffer, position, align); free(buffer); - alarm(output->server->message_timeout); + alarm(output->server->message_config.display_time); } void diff --git a/server.h b/server.h index 092f7bf..a5139f6 100644 --- a/server.h +++ b/server.h @@ -3,6 +3,7 @@ #include "config.h" #include "ipc_server.h" +#include "message.h" #include #include @@ -44,6 +45,7 @@ struct cg_server { struct keybinding_list *keybindings; struct wl_list output_config; struct wl_list input_config; + struct cg_message_config message_config; enum wl_output_transform output_transform; diff --git a/signatures/1.9.0-cagebreak-config.5.sig b/signatures/1.9.0-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..d6ac6bbc35d2718a0d202eb9ebc09571c3ec4eda GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%BpPf&dB$5TM6H zgo5zH1|d!MJk3MYrMG@+mW zu_B!hLyCsptEvb($9?ogTecWcHapn(b$l+bQiPNJm4^bA=Jo}U=e+ye$JCou%?%$c z99UyJiQPJnbZpTJeZ$$|nFzmY2ORLI));==hW$&1& zePyl%{uIFE7|P<4Ug=Q!tLtKd#EH`^o~VvTVpW20Q3 zQKwL?vPxdOX)_*VO!_X{tEt}=qZPj7c`$j>7B8nP9^OKGKj7JDA`%mEhD0%$Nww5c zCR7d5NwmW6D(b$vw@99AsC;o}^{3*X$=61%1C1eCI_kZCYC(QP6&SB$+QqU_LPa$u zOS?D%NXh*lr*`_`7FL84Ff51wXeQK26F*W4!_Ou+>{O_EyV#yzQ{pJeXC51)*Ru#r E&X@KM`v3p{ literal 0 HcmV?d00001 diff --git a/signatures/1.9.0-cagebreak.1.sig b/signatures/1.9.0-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..47ba7f2978d4cfa6d59e5b25d8e340db574ad9ef GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%BpPe*g*z5TM6H zgo=}DIUWoz{7hfGwj z^imey0J@ey-HnU+B@C^oa-Ib0cEc4X%ehZ(a2a_vs23Y_k3lCVFk{MGsxw>qMvjWt zRDDJP;fxyhvo+2LrGo`xb-~fRB{I>mUl;lw!y;n<-D%{_>@RgJO(~P-@P}4E>)1c? zBtl!)Kzq55_Gb4?)o@(YjfVr@Mr>^)azcSCeaV34$NfO!AF=9pvR%+_wdk@8%mw;$ z=u_9NpuLBE2J0hv<4BIY4TUx3as)h4-eVr;vq7{%DNML|$D0Ii-8;17x_#TyM=BK? zPz`O`y}Y#QX9t@YxtIJh*M=^Xt+^uZ1j?Wi`N`I0rVLX!K+ykoCyBfWv}fV~c!Z*V z@eNWSR{CACsW6`TSjmP-8>e#vHh8A>rRyfhvA#IVeC8-r62C27bbVL&1A>rszmJ1)If? zx)<_hI(xdUgSHKi+2oj7bLWd14Ry)Dxl0Q6a}*ykRohKejfqufwkluKOkIs=F^dK) z(xGR7HVsYvD_98Ti4<(0n98&j0ex#xY%DqS%%E+FD|YOcUY3i)f<^at+w@s$xcxM- ET8sA(CjbBd literal 0 HcmV?d00001 diff --git a/signatures/1.9.0.sig b/signatures/1.9.0.sig new file mode 100644 index 0000000000000000000000000000000000000000..2cc14a8392a06e2f4bee8076cd2bd3acdee2f4cc GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%BpPd;kgw5TM6H zgo6OjSbm&_ZEJ$$GagLEuabvlKYurs-dCP z#3oIYm2Oi?{pu1ZF{He;gxqi@kqjd%|G3QZ>3@Su%n~0l%d#3a{ckK9_K0WjWfPAo zNkknL(M{;s?|M55Zd zW+nlT^h+U-g9YKl2?|kQrMea*2@zxm+<=NDnI~D=obs&(((46JW6TfX%W!R40dn0M z1VnSD9d`RJzY)dZuKUv)>h_&ZLNWeJV2*b-Hp$qj5~{~N!;h{G-CT&b@|1#s8oxAP z^PDV3tXr>ju?9Yf-$rPOgG)x5l?Q8%ncMRxa@} zsZUn+m@#F3baYgr#wwd+>S)gm`y7V>e&`8IYafPMo;jl9?x4+M1#Qrlh6{?Ii&$zi z=E{C}c0!`SQ5s9Vyq%1}8_@_ANb&Xk8+QE1@YTdJ(iRM3sX Ev3HpTg#Z8m literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index d6ac6bbc35d2718a0d202eb9ebc09571c3ec4eda..7349ebcab4fa32168646d48f892bcd5596a3192f 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY)&OF#rk)5TM6Hgo9>tYPA>a(B~! z^>{#QM`;&Ks#9hY(iZU4k8V6+u7a|13x%(-a?xhLZT+17sI6;Yl3SkvVYk^S>Ur>mqlBDv%p&b zyXZ>{XYf{zf5Znp7=&To+PBFaU@jZ=3`vY%qC`~oY$L2#0ANF9egTBdF(cP z5<`_TtPH7uydo}(15>)Q8ooXiDY8P9y1Tn#aTuv^bJuxX&4TtJK6;|s;VrH(b%KLv>jY=9%XSI zF(sTrofg)X-Ev#Ga#;y14*3dy8|zq!)BCe1-HB#AE!d_HVju_feh9E#H1mFKV`&0O zn6>xe>oj&}xbQeoI8Zgk(qKmS5EGv3~`Hst27^QY&H~rLYjMaV3Q` zZ>&d3WK{PGOV@wh%jla+RN@q)!ew~v+Edj+>JSDDq^(+J8H%t6gjnI99eD>_tvo?0 zU>n2GCXF?~6zi8<^KF(CJ-H4cGYmEkVX+oY!uZU#QPscv!P(E!)#+GqVS=Q;=EXbK gCQ-SssuyQEbP<+f7PT!o81aUMd)X(zx~6zVzY!<^n*aa+ delta 542 zcmV+(0^$9(1hxc_BY$D2f&dB$5TM6Hgo5zH1|d!MJk3MYrMG@+mWu_B!hLyCsptEvb($A5kFMO(HQQ8qi+_;q|P zuTq4Q{gsCTmFD&ZkmtPn+{e_LRm}|_EF4&4JBi&okK{a1%M&gkX$wy>idW9Sg)Sbh z^h_5K%%9D&kHNab*|;Xy9acqIpM;yThj-5b{Npf|gNkas63T%S>=P_42`UVpr4Gah72`Yzk6soxc&6~5$o zFnQ7zFQ+UX-a>mn;Mr&*5)*NTL@}93wbW83R1MNew8HNy>b|r{bW= z*G8@bjUie(>b-tyL4HIP7_Vd6#j;UCMKvZ%yEp{O_EyV#yzQ{pJeXC51)*Ru#r&H-@<$^ZZW diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 47ba7f2978d4cfa6d59e5b25d8e340db574ad9ef..e0a399bb986388fd35276fee09dbbf5ccac80832 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY)&OIRFX?5TM6HgoqZ-^11nv;!IzNKG?CCR3*qIjlr607+v2?mnfYhMc3P^(}@ZgMa zgU{dgn6#*WL4PRyQ9!3WZp93ru2dr!ECr4Fs!e zymoXj4>W#mCg$7WYOfC$=ho-LsAKrq@_#{zhxJwNF8+HFW*h z*DwhYyk^{acUgYXsG31z3q<=`>)&6T-G^`kC34^f-ml=jX zd3hwc&ZL!_s3Mq(TxI<9kugz{e$flSj!5R(sSyav%AEpyo0-ggo*=TuDTFhAJYw%$ zGU1%#5SptS54=}DIUWoz{7hfGwj^imey0J@ey-HnU+B@C^oa-Ib0cEc4X%ehZ( za2a_vs23Y_k3lCVFk{MGsxw>qMvjWtRDDJP;fxyhvo+2LrGJA3Vs*jMyd^Txv0oSZ z9>XGI0NrWi&Fn9AEKMns=kSMCKkL{(@+3lA*Fbx@kM?HwOx18))QyJ&-$rb0ByvK5 zD}Bj;=Ewa&;vcc71aI9twBx#c+tNoW6&p|uZQ8xOwCZOEn;5y5{4&>uE|jggBJKpr zpc47X)@7y)Q#e4-|8^&dya=>s;sAJrqJQxXQXp3PU9zb#p7~hGhDjTza|1SbruC)k zCdjeAILmzIC{z_&d=&wvE;Ty8?%!;1W`boP1a8cPiGTD;VcHz$G7)mY$=z(vSwjMB zyu?^e!_x7!FzS4=tw&So5hg27xHF0d%CTIwhfQj=ZhK*b;-cF zOA7XL6dy8G+f7uBiB)H|Dqqt~U5#iliv}#xp=W?L4Nd(kSP15c6l|cF%Cr>$eQQx{ gEIIVdpcie4D|YOcUY3i)f<^at+w@s$xcxM-TJx<5_5c6? diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 2cc14a8392a06e2f4bee8076cd2bd3acdee2f4cc..1813ed2426494a05f625ea4b7e3ab605ed4f8601 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY)&OH2?|;5TM6Hgo z9ROudEg(73sF&{gAji%Mu!6xkWxIWi-X<6Kgywn!hlTI#HGk%MzxuJUbH~UuWjbrA9pC<}|8A9VJ@X0zxN`VNvWzZw*e)YMR)(MA@zW*V)~gJ!gmcUTel41s4(OMDwux8<4JEf zo{2_rKAG^+Wt5G3vRN{eH~t6A2sWTgUzK`nTW(NYh`EistdMr0(ybER`7|K`Elm#~ g29sryaTk{o0OlLqNij*hoj~ECUMrZkGFI}X$HzDW0{{R3 delta 542 zcmV+(0^$9(1hxc_BY$D2d;kgw5TM6Hgo6O zjSbm&_ZEJ$$GagLEuabvlKYurs-dCP#3oIYm2Oi?{pu1ZF@L1IwS?SoCXoyyEC0C6 z^67trOUx1 zVjW)TE+_A%m5iJe9~+WP?#HeIueE>D4SLqocW9Y0gv=cA&`Rw;lv3FQDCLI79+QE1@YTdJ(iRM3sXvBEq5MF0Q* From 6dbcb7eda9b3d287a04296e445282614a387a47a Mon Sep 17 00:00:00 2001 From: project-repo Date: Sun, 8 Jan 2023 22:09:15 +0100 Subject: [PATCH 09/19] Release 2.0.0 This is a major release and includes BREAKING changes! Breaking Changes: * More intuitive switch of focus, next, prev and exchange (#20, 40 in Bugs.md) Cagebreak will probably still feel broadly the same though. * Remove -r flag - This is replaced by output configuration. * Socket disabled by default - The socket is enabled by invoking Cagebreak with the -e flag. * Socket permissions restricted to the user of the Cagebreak process (700) This may require modification of scripts interacting with the socket with different UIDs than the UID of the Cagebreak process. * Rename "Current frame" indicator to "Current tile" Changelog: * Move to wlr_scene * Add events displaying change over the socket * this enables scripting tools * Add support for scaling outputs (thanks to Oliver Friedmann) * Remove -r flag * Add rotation to output configuration * Add cursor enable|disable flag * Add input keyboard configuration * Custom path flag for configuration file * Restrict socket permissions to the user running cagebreak (700) * Fix Issue #31 (resolve some terminology) 38 in Bugs.md * Fix Issue #30 - 39 in Bugs.md * Fix Issue #20 - 40 in Bugs.md * Fix Issue #12 - 41 in Bugs.md (dump + events over socket) * Fix Bugs found via scan-build static analysis (42 - 45 in Bugs.md) * Fix Issue #33 - 46 in Bugs.md * Fix Issue #32 - 47 in Bugs.md * Fix Issue #16 - 48 in Bugs.md * Fix Issue #3 - 49 in Bugs.md (disabling keybinding interpretation for specific keyboards is now possible) * Fix Issue #26 - 50 in Bugs.md * Fix Issue #7 - 51 in Bugs.md (Change cursor to square while Cagebreak is waiting for a key) * Fix config bug for some commands - 52 in Bugs.md * Fix Issue #35 - 53 in Bugs.md (update to wlroots 0.16.1) * Improve FAQ.md (related to some Issues) * Disable outputs when unable to set any mode (crashed previously) * Add Code of Conduct * Print version number on startup --- Bugs.md | 462 +++++++++++- CODE_OF_CONDUCT.md | 15 + Changelog.md | 42 ++ FAQ.md | 60 ++ Hashes.md | 20 + README.md | 586 ++++++++++----- SECURITY.md | 62 +- cagebreak.c | 332 ++++++--- config.h.in | 5 + example_scripts/cb_script_header.sh | 18 + example_scripts/focus_follows_cursor.sh | 23 + example_scripts/show_workspace_views.sh | 25 + examples/config | 6 + fuzz/execl_override.c | 6 +- fuzz/fuzz-lib.c | 278 +++---- fuzz/fuzz-lib.h | 9 +- fuzz/fuzz-parse.c | 18 +- fuzz/meson.build | 5 +- idle_inhibit_v1.c | 10 +- idle_inhibit_v1.h | 2 + input.h | 6 +- input_manager.c | 303 ++++++-- input_manager.h | 22 +- ipc_server.c | 177 ++++- ipc_server.h | 6 + keybinding.c | 934 ++++++++++++++++++++---- keybinding.h | 130 ++-- libinput.c | 207 ++---- man/cagebreak-config.5.md | 63 +- man/cagebreak-socket.7.md | 606 +++++++++++++++ man/cagebreak.1.md | 14 +- meson.build | 68 +- meson_options.txt | 2 + message.c | 132 +++- message.h | 8 +- output.c | 914 ++++++++++------------- output.h | 33 +- pango.c | 3 + pango.h | 3 + parse.c | 201 +++-- parse.h | 5 +- render.c | 274 ------- render.h | 9 - seat.c | 440 ++++++----- seat.h | 11 +- server.c | 4 +- server.h | 18 +- signatures/1.9.1-cagebreak-config.sig | Bin 0 -> 566 bytes signatures/1.9.1-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/1.9.1-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes util.c | 11 +- util.h | 3 + view.c | 265 ++----- view.h | 65 +- workspace.c | 74 +- workspace.h | 13 +- xdg_shell.c | 327 ++++----- xdg_shell.h | 15 +- xwayland.c | 105 +-- xwayland.h | 4 +- 64 files changed, 4813 insertions(+), 2646 deletions(-) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 example_scripts/cb_script_header.sh create mode 100644 example_scripts/focus_follows_cursor.sh create mode 100644 example_scripts/show_workspace_views.sh create mode 100644 man/cagebreak-socket.7.md delete mode 100644 render.c delete mode 100644 render.h create mode 100644 signatures/1.9.1-cagebreak-config.sig create mode 100644 signatures/1.9.1-cagebreak.1.sig create mode 100644 signatures/1.9.1-cagebreak.sig create mode 100644 signatures/cagebreak-socket.7.sig diff --git a/Bugs.md b/Bugs.md index 822f3f6..25eeeca 100644 --- a/Bugs.md +++ b/Bugs.md @@ -591,7 +591,6 @@ without xwayland has been added to the release checklist. * github issue number: #23 * Fixed: 1.9.0 -``` Similar to djpohly/dwl#177. Xwayland works fine elsewhere: cage, hikari, kwinft, labwc, phoc, river, sway, wayfire. ``` $ cagebreak @@ -618,7 +617,6 @@ wayland-protocols-1.25 xwayland-devel-21.0.99.1.171 wlroots-0.15.1 ``` -``` ## Issue 34 @@ -652,3 +650,463 @@ This issue was not present in earlier releases. Cagebreak 1.9.0 broke the screen/movetoscreen functionality. This issue was not present in earlier releases. +## Issue 38 + + * github issue number: #31 + * Fixed: 2.0.0 + +Cagebreak terminology was unclear up to and including 1.9.1. + +The following are extracts from the github issue discussion: + +kinleyd: +``` +This isn't an issue per se, but concerns cagebreak terminology. +I won't try to cover the entire range of terms used but stick +to the ones that concern me at the moment: + +OK, so I get the use of the terms 'output', 'workspace' and 'tile'. + +So my question: In cagebreak, what exactly is a 'screen'? At the +moment, the use of nextscreen, prevscreen, movetoscreen, +movetonextscreen, movetoprevscreen all seem to suggest that +'screen' is the same as 'output'. If so, shouldn't all the +aforementioned commands have screen replaced with output? +eg. nextoutput, prevoutput, etc. +``` + +project-repo +``` +You make an interesting point. + +We have considered this and the tricky bit is that both output and *screen are +defined cagebreak commands. It would be difficult to merge these two +commands in a reasonable way (even with the freedom of breaking changes). + +Additionally, there is a sort of informal symmetry between output and input +we would like to maintain. + +Our current conclusion is that we will leave the commands unmodified. +The now ex-post defined distinction between output and *screen is that +the *screen stuff works with the natural number uniquely identifying the +output within a given cagebreak session (but not across sessions, "nextscreen" +and "prevscreen" do so internally by in-/decrementing this number), whereas +output always deals with an output name as does input with an input name. + +Please feel free to point out any other inconsistencies in cagebreak or better +solutions than outlined above in this issue. + +You can post your suggestions here. + +We will close this issue once 2.0.0 is released where the points mentioned above +will be outlined in the documentation. Please leave it open in +the mean time. Afterwards, you may open a new issue. + +cheers +project-repo +``` + +kinleyd: +``` +> Our current conclusion is that we will leave the commands unmodified. +> The now ex-post defined distinction between output and *screen is +> that the *screen stuff works with the natural number uniquely +> identifying the output within a given cagebreak session (but not +> across sessions, "nextscreen" and "prevscreen" do so internally +> by in-/decrementing this number), whereas output always deals +> with an output name as does input with an input name. + +That makes perfect sense. Additionally, I also realize that there +is the virtual display for which the concept of 'screen' as +distinct from 'output' is necessary as a screen could then be +a fraction of an output, or combine multiple outputs. + +> We will close this issue once 2.0.0 is released where the points +> mentioned above will be outlined in the documentation. Please +> leave it open in the mean time. Afterwards, you may open a new issue. + +Hey, I look forward to version 2.0.0! +``` + +project-repo: +``` +We have now modified the cagebreak-config man page on the development +branch to clarify the relationship of output and the screen family of +commands. + +Please let us know if anything can be improved in that regard. + +cheers +project-repo +``` + +## Issue 39 + + * github issue number: #30 + * Fixed: 2.0.0 + +Cagebreak 1.9.1 had an issue where clicks did not evoke +any response under some very specific circumstances. + +This was remediated by switching Cagebreak to `wlr_scene`. + +There was extensive discussion inside the github issue +but this is omitted here due to irrelevance. + +## Issue 40 + + * github issue number: #20 + * Fixed: 2.0.0 + +nor-0 proposed a more intuitive way to switch focus. This +is a breaking change and as such is introduced on a major +release. + +Details are described in the github issue discussion, which +is reproduced here: + +nor-0: +``` +Hello, + +I think switching focus is a bit confusing in some situations. +When focus is switched in a direction, it can end up diagonally +instead of the frame next to the previously focused one. +The minimal example for this is with four frames, but it +also applies in layouts with more than four of them. + +Let´s say I press the keybindings for these actions: +`vsplit`, `hsplit`, `focusright`, `hsplit`. +This leaves me with a layout of four simple quarters: + +> +-----+-----+ +> | 1 | 2 | +> +-----+-----+ +> | 3 | 4 | +> +-----+-----+ + +Now, using `focuslefton` frame 2 brings me to frame 3 instead +of one. Likewise, `focusright` on frame 3 brings me to frame +2 instead of frame 4. + +As soon as I resize a width, switching works as expected and +desired. The oddness however reappears whenever the vertical +frame edges are realigned. + +The same trouble happens when creating the layout with the +keybindings for `hsplit`, `vsplit`, `focusdown`, `vsplit`. +Now, focusing up from frame 3 brings me two frame 2 instead +of 1, and same with the symmetrical opposite again +(2 downwards is 3 instead of 4). Now resizing heights is what +helps until the horizontal edges are realigned. + +As said before, similar things occur with more complex layouts. +I use those much less frequently of course, but intuitive +navigation is even more important then. In these two minimal +examples, reaching the frames 1 and 4 is also often more +tedious then necessary. + +I understand this is due to the way the frames were created +and makes some sense in this regard. However, unless there +is some reason to keep this behavior (which disappears by +some resize options anyways), I´d suggest to change it to +be more intuitive. + +I imagine an approach for this could be to determine the +frames center point and then looking for an adjacent frame +in horizontal (vertical) direction from there when +`focusright` or `focusleft` (`focusdown` or `focusup`) is used. + +(Everything said about `focus[direction]` also applies to +`exchange[direction]`.) +``` + +project-repo: +``` +Thanks for the suggestion! Yes, I agree that the current implementation +is not a very satisfying solution... The reason it is handled like this +is simply because it was easiest to implement. Fortunately however, +changing this should not require too much coding since the +determination of the tile to jump to is handled globally by a single +function for each direction. + +I like your idea with considering the center of the frame and then +looking for the one adjacent to it which is at the height of the center, +since such a frame is always guaranteed to exist (unless we are at the +edge of the screen in which case there is nothing to jump to). +Of course, this would have to involve some kind of tie-breaking when +two adjacent frames share a border at the height of the center (which is +bound to occur often if you never resize the tiles). I'm currently +leaning towards simply taking the top/left one in this case (or some +similar scheme) but if anyone else has thoughts on this, we'd be glad to +hear! + +Some notes: + + * This would be a breaking change, so the version number would jump to 2.0.0. + * Also, due to limited developer capacity at the moment and + the ongoing porting of cagebreak to the wlr_scene API it may be a + while until we are able to implement this, so bear with us! + +cheers +project-repo +``` + +project-repo: +``` +We pushed some code to development implementing this in `ed5cca9`. +Sorry for not writing this much sooner. + +To anyone who reads this: This feature will remain on the development +branch for some time, partially due to some unresolved xwayland and +wlr_scene bugs and partially to allow breaking changes. So if anyone +would like to see something changed, please feel free to let us know! + +cheers +project-repo +``` + +## Issue 41 + + * github issue number: #12 + * Fixed: 2.0.0 + +kinleyd raised the issue of changing the focussed screen +on mouse hover. The Cagebreak philosophy is completely +keyboard-oriented and this feature request was denied. +However, this line of inquiry led to the idea of implementing +an ipc socket which would report key events and an information +dump functionality which would enable almost arbitrary scripting. + +Related Material: +- [cagebreak-config man page](man/cagebreak-config.md) +- [cagebreak-socket man page](man/cagebreak-socket.md) +- [scripting examples](https://github.com/project-repo/cagebreak/tree/development/example_scripts) + +The github issue discussion is partially reproduced below: + +kinleyd: +``` +While fully recognizing - and appreciating - Cagebreak's keyboard orientation, would it be possible to accommodate support for screen change on mouse over? This would help avoid a series of key presses on multi-screen setups and improve overall ergonomics. + +Thanks. +``` + +project-repo: +``` +As you correctly recognised, cagebreak is designed to be completely +keyboard-oriented. However, I understand that for the multi-monitor +setup you describe it may be useful to have some kind of +mouse-compositor interaction. To accommodate this, we are considering +implementing a command which allows to obtain the current cagebreak +state from the ipc socket, including the current cursor position. +That way, by implementing a script which listens for cursor events +and acts accordingly, it should be possible to implement the behaviour +you describe externally (provided #11 is implemented as intended). +What do you think? + +If you have any other ideas, don't hesitate to let us know! + +cheers +project-repo +``` + +project-repo +``` +There has been much talk about #12 and how it would improve all sorts of +use cases, once implemented. While much remains to be determined, we would +like to give an update. + +First, #12 is secondary in priority to #11, which is presumably easier +to implement and much clearer in its scope. + +Once implemented, cagebreak will communicate the state of at least the +following internal properties: + + * [ ] Current cursor position (allowing setting of the current screen + as per navigating screens question and suggestion #11 + * [ ] IDs for graphical programs along with position on screen + * [ ] IDs for tiles on particular screens + * [ ] Currently focussed tile, screen, etc. + * [ ] Events such as "new window", "screen split", etc. + +In which format this information will be provided is yet to be +determined, but we are considering at least the following: + + * full blob of data upon request via ipc socket + * partial information on events + +To improve user experience, the release of #12 will include examples of +how to use the new API over the socket for real world use cases, +analogous to the current example config. + + * [ ] Example script "Current screen follows cursor on click" + * [ ] Example script "Setup multi screen environment with graphical programs on + specific tiles" + +Note that this is just the current state of planning, +the final properties of cagebreak are specified in the man pages upon +release and cagebreak is provided as is, as specified in the LICENSE. + +cheers +project-repo +``` + +project-repo: +``` +Some but not all features mentioned in our previous comment have now been implemented on +the development branch. + +Information on current events is provided through the ipc socket +now. The types of events which are reported are still subject to change and the +feature is not yet documented but you may check it out nonetheless. Let +us know if there is any additional information you would like to obtain +for the different events. + +Current format displayed on the socket is as follows: + +'cg-ipc<4 bytes denoting message length>(:,:,...,:)' + +Consider it a proof of concept. + +A full dump of the current cagebreak state is not yet possible. + +Happy new year to you too! +cheers +project-repo +``` + +project-repo: +``` +We pushed some code to development implementing the dump +functionality. This should contain the information you require since it +gives you the view currently focussed by the pointer from which you can +deduce the output the cursor is currently hovering over by looking up +the output on which the view is placed. Note that this only works when +the cursor is actually hovering over a view (i.e. not when it is on an +empty tile). Alternatively, you could read the cursor coordinates and +compare these with the coordinates of the different outputs, though atm +the coordinates of the outputs are not dumped (we aim to add this later). + +To anyone who reads this: This feature will remain on the development +branch for some time, partially due to some unresolved xwayland and +wlr_scene bugs and partially to allow breaking changes +(removing/changing data outputted by dump and other information sent by +IPC). So if anyone would like to see something changed, please feel free +to let us know (either by posting here or opening a new issue)! + +cheers +project-repo +``` + +## Issue 42 + + * github issue number: N/A + * Fixed: 2.0.0 + +When Cagebreak exited due to an error on startup, it was possible for +memory leaks to occur since `server.modes` was not freed correctly. The +same applies to the variable `name` in `input_manager.c`. + +This bug was found using the scan-build utility. + +## Issue 43 + + * github issue number: N/A + * Fixed: 2.0.0 + +In `keybinding_move_view_to_cycle_output`, it was previously possible for a +null pointer dereference to occur, when no view to be moved was focussed. + +This bug was found using the scan-build utility. + +## Issue 44 + + * github issue number: N/A + * Fixed: 2.0.0 + +`cg_input_reset_libinput_device` was removed as it was unused code. + +This bug was found using the scan-build utility. + +## Issue 45 + + * github issue number: N/A + * Fixed: 2.0.0 + +Various memory leaks in `parse_message_config`, `full_screen_workspace` +and `server_show_info` were fixed. + +This bug was found using the scan-build utility. + +## Issue 46 + + * github issue number: #33 + * Fixed: 2.0.0 + +Cagebrak did not state in its FAQ how to use letters not found +on the current keyboards alphabet. + +## Issue 47 + + * github issue number: #32 + * Fixed: 2.0.0 + +Cagebreak did not state in its FAQ how programs can be launched. + +## Issue 48 + + * github issue number: #16 + * Fixed: 2.0.0 + +Cagebreak cursor sizes varied under some environmental circumstances. +Investigations showed that the cursor is set by the respective application +but environment variables are usually respected. This is now documented in +the FAQ. + +## Issue 49 + + * github issue number: #3 + * Fixed: 2.0.0 + +Cagebreak used to have no way to disable the interpretation of keybindings +for a specific keyboard, which was cumbersome for some applications. This +feature is now available + +## Issue 50 + + * github issue number: #26 + * Fixed: 2.0.0 + +Cagebreak used to have no way to hide the cursor. This is now possible. + +## Issue 51 + + * github issue number: #7 + * Fixed: 2.0.0 + +Cagebreak used to not change the cursor while waiting for a key. The cursor +is now a square in this state. + +## Issue 52 + + * github issue number: N/A + * Fixed: 2.0.0 + +Cagebreak did not correctly apply some simple commands if they were simply +written in the configuration file. + +Consider the example config file: + +``` +quit +``` + +Under these circumstances Cagebreak did not quit right after startup. + +## Issue 53 + + * github issue number: #35 + * Fixed: 2.0.0 + +Cagebreak did not build with wlroots 0.16.1 and this was adjusted. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f094d9a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,15 @@ +# Code of Conduct + +As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. + +Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. + +This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting project-repo (See [SECURITY.md](SECURITY.md) for an e-mail contact.). + +This Code of Conduct is adapted from Curl, available at https://curl.se/docs/code-of-conduct.html and transitively the Contributor Covenant, version 1.1.0, available at https://contributor-covenant.org/version/1/1/0/ diff --git a/Changelog.md b/Changelog.md index ff24285..e469a6c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -64,3 +64,45 @@ Adds libinput configuration and virtual keyboard and pointer support. - Add new cagebreak email contact gpg key - Add new project-repo AUR gpg key (relevant for cagebreak-pkgbuild) +## Release 2.0.0 + +This is a major release and includes BREAKING changes! + +Breaking Changes: + * More intuitive switch of focus, next, prev and exchange (#20, 40 in Bugs.md) + Cagebreak will probably still feel broadly the same though. + * Remove -r flag - This is replaced by output configuration. + * Socket disabled by default - The socket is enabled by invoking Cagebreak with the -e flag. + * Socket permissions restricted to the user of the Cagebreak process (700) + This may require modification of scripts interacting with the socket with + different UIDs than the UID of the Cagebreak process. + * Rename "Current frame" indicator to "Current tile" + +Changelog: + * Move to wlr_scene + * Add events displaying change over the socket + * this enables scripting tools + * Add support for scaling outputs (thanks to Oliver Friedmann) + * Remove -r flag + * Add rotation to output configuration + * Add cursor enable|disable flag + * Add input keyboard configuration + * Custom path flag for configuration file + * Restrict socket permissions to the user running cagebreak (700) + * Fix Issue #31 (resolve some terminology) 38 in Bugs.md + * Fix Issue #30 - 39 in Bugs.md + * Fix Issue #20 - 40 in Bugs.md + * Fix Issue #12 - 41 in Bugs.md (dump + events over socket) + * Fix Bugs found via scan-build static analysis (42 - 45 in Bugs.md) + * Fix Issue #33 - 46 in Bugs.md + * Fix Issue #32 - 47 in Bugs.md + * Fix Issue #16 - 48 in Bugs.md + * Fix Issue #3 - 49 in Bugs.md (disabling keybinding interpretation for specific keyboards is now possible) + * Fix Issue #26 - 50 in Bugs.md + * Fix Issue #7 - 51 in Bugs.md (Change cursor to square while Cagebreak is waiting for a key) + * Fix config bug for some commands - 52 in Bugs.md + * Fix Issue #35 - 53 in Bugs.md (update to wlroots 0.16.1) + * Improve FAQ.md (related to some Issues) + * Disable outputs when unable to set any mode (crashed previously) + * Add Code of Conduct + * Print version number on startup diff --git a/FAQ.md b/FAQ.md index 1077a69..d8918a0 100644 --- a/FAQ.md +++ b/FAQ.md @@ -5,6 +5,7 @@ * Check the man pages * [cagebreak config](man/cagebreak-config.5.md) (probably where you find the answer) * [cagebreak](man/cagebreak.1.md) (command line options etc.) + * [cagebreak-socket](man/cagebreak-socket.7.md) (socket information, mostly useful for scritping) * Check the rest of this FAQ * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) or otherwise get in touch with the development team (See section Email Contact in [SECURITY.md](SECURITY.md)). @@ -25,6 +26,65 @@ Set the following environment variables to activate wayland support for firefox. +## How do I map characters which are not on the Keyboard? + +Suppose you want to use a command like `bind` for a character +which is likely not on your keyboard like "Ñ‹" - you should write +it as "Cyrillic_yeru". + +These names can be obtained by running xev and pressing the respective +key(s) (combinations). + +## How do I change the size of the cursor? + +The size and shape of the cursor is determined by the application, however, +most applications respect the environment variables `XCURSOR_SIZE` and +`XCURSOR_THEME` + +To change the cursor size, one could use: + +``` +export XCURSOR_SIZE=1 +``` + +If you are using an application which inherits its environment variables +from something outside the scope of the export (such as a daemon for +emacs might), you can usually specify your environment variables in +the applications respective configuration. + +## How is Cagebreak launched? + +The documentation says to start Cagebreak like any other binary. + +If you want to start Cagebreak on login, you can use your shells +equivalent of a `.bash_profile`. In BASH appending cagebreak +(given that it is installed in the path) to `.bash_profile` +is fine. + +If you want to start Cagebreak using systemd you could use a +service started on user login, though the development team once ran +into some issues with permissions for the services. + +Please note that Cagebreak does not solve the problem of +locking the screen or login in general. + +## How are applications launched in Cagebreak? + +There are multiple ways to launch external programs in cagebreak. + + * Using a terminal emulator is a perfectly valid way to launch + applications. If you want to be able to close the terminal + you used to start the program, you may use `&disown`, which should + be available in every shell. + * Using the `exec` command in the cagebreak config, it is possible to + launch programs when cagebreak is started. Moreover, as this command + can be combined with commands such as `bind`, it can be used to + create custom keybindings which execute external programs. (See also + the man page `cagebreak-config`). + * All commands mentioned previously are also available over the socket + which allows the creation of (arbitrary) keybindings on the fly and + a fortiori keybindings running arbitrary commands. + ## Which further resources are available? * [Arch Linux Wiki entry for Cagebreak](https://wiki.archlinux.org/title/Cagebreak) diff --git a/Hashes.md b/Hashes.md index 97d6217..627d428 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.0.0 cagebreak + + * sha 256: 45f88abdae03bbc7dad5734dd6fb1a00e1bf37d3e0c4016dad2fa3de832335cf + * sha 512: dc261a788ea1843e701f4fb6985200c4813113fda0f911bee4e3cc9b20fd082055e40e9fc60647128674a94ece75f4aa55d1faede8e94e6e1940b02d8a6de8e0 + +2.0.0 cagebreak.1 + + * sha 256: 0d96947c2054fb42b284b31cc4ea793944a4562509f5f00b7927d11d0046041d + * sha 512: 4f3eadc88680d994f9ebcf85be38626b7e95971bc3233d710613cee58496553e0bb1e65258956f8a50c633bdd4dbc5c0283826fd5b661e9de0092366cc47caae + +2.0.0 cagebreak-config.5 + + * sha 256: 4ee6ed443ce93cd6af3df49fe5e32244baeca04ca167993fb3d71970bf20939d + * sha 512: d6bf8f73ed8c9084b784653e88e1f149fbab35997f412f6c505972d3299a47bec1238aecd4334dd597bb32e46ced93f36d488badd25c6a8d61bdb73f3aea87ab + +2.0.0 cagebreak-socket.7 + + * sha 256: 682b3cc46ad059147b7d7ab814ac1831689511e31c0d6f2b91732e85244da99e + * sha 512: 92057e4cbbcec4f4dbd98f3a99cb4c450ef31aef557705e5f8f2927b53653149b232771b455f9b9ae8435a7351667a4e663b7d120b76a0bbb5c7ba04db551489 + 1.9.1 cagebreak * sha 256: 262c67170eb2a39174d40f97d940707029dca0b2b613b514a1cca29152a12665 diff --git a/README.md b/README.md index 3da2c16..1dba0b5 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,81 @@ -# Cagebreak: A Wayland Tiling Compositor Inspired by Ratpoison +# Cagebreak: A Wayland Tiling Compositor -This is Cagebreak, a Wayland tiling compositor. +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.0.0)](https://repology.org/project/cagebreak/versions) -The goal of this project is to provide a successor to ratpoison for Wayland -users. However, this is no reimplementation of ratpoison. +## Quick Introduction -Should you like to know if a feature will be implemented, open an issue -or get in touch with the development team. +Cagebreak is a [Wayland](https://wayland.freedesktop.org/) tiling compositor +based on [Cage](https://github.com/Hjdskes/cage) and inspired by [ratpoison](https://www.nongnu.org/ratpoison/). -For documentation of Cagebreak, please see - * the man pages +### Purpose + +The goal of this project is to provide a successor to ratpoison for Wayland. +However, this is no reimplementation of ratpoison. + +#### New Features, Bugs and Contact Information + +Should you want to know if a feature will be implemented, file a bug or +get in touch, [open an issue](https://github.com/project-repo/cagebreak/issues/new) +or write an e-mail (See [SECURITY.md](SECURITY.md) for details.). + +The Roadmap section outlines what is planned for the future. + +#### Compatibility & Development Distribution + +Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the libraries +(and software versions) as they are obtained through [pacman](https://wiki.archlinux.org/title/Pacman) +at the time of release. Any other use is out of scope. + +Most other setups probably work with a bit of luck. We +make no guarantees. + +### Quick Installation + +This assumes Arch Linux: + +1. Use the [cagebreak PKGBUILD](https://aur.archlinux.org/packages/cagebreak). +2. Add an example config such as [config](examples/config) to `$USER/.config/cagebreak/config` +3. Execute cagebreak like any other binary. + +See the [ArchWiki](https://wiki.archlinux.org/title/Cagebreak#Getting_started) for +details on getting started and the documentation for everything else. + +### Documentation + + * the rest of this file + * the man pages: * [cagebreak](man/cagebreak.1.md) * [configuration](man/cagebreak-config.5.md) - * also the [FAQ](FAQ.md) + * [socket](man/cagebreak-socket.7.md) + * the [FAQ](FAQ.md) + * [SECURITY.md](SECURITY.md) + +#### What's new? + +See the [Changelog](Changelog.md). + +### Uninstallation + +`pacman -R cagebreak` should be sufficient. + +### Contributing + + * Just [open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your idea. + We will consider the proposal and get back to you. + * Don't open a pull request. We might not accept your code and + it would be sad to waste the effort. + * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never + had to intervene - Keep it that way!) + +### Name Cagebreak is based on [Cage](https://github.com/Hjdskes/cage), a Wayland kiosk -compositor. - -Cagebreak is developed under Arch Linux and uses the libraries -as they are obtained through pacman. However, cagebreak should also work on -other distributions given the proper library versions. +compositor. Since it breaks the kiosk into tiles the name +Cagebreak seemed appropriate. ## Installation -If you are using archlinux, just use the PKGBUILDs from the aur: +On Arch Linux, just use the PKGBUILDs from the [AUR](https://aur.archlinux.org/): * Using [cagebreak](https://aur.archlinux.org/packages/cagebreak), Cagebreak is compiled on the target system (since release 1.3.0) @@ -37,17 +89,17 @@ See [cagebreak-pkgbuild](https://github.com/project-repo/cagebreak-pkgbuild) for There are different ways to obtain cagebreak source: - * git clone (for all releases) - * download release asset tarballs (starting at release 1.2.1) + * [git clone](https://github.com/project-repo/cagebreak) (for all releases) + * [download release asset tarballs](https://github.com/project-repo/cagebreak/releases) (starting at release 1.2.1) -### Verifying Source Code +#### Verifying Source Code There are corresponding methods of verifying that you obtained the correct code: * our git history includes signed tags for releases * release assets starting at release 1.2.1 contain a signature for the tarball -### Building Cagebreak +## Building Cagebreak You can build Cagebreak with the [meson](https://mesonbuild.com/) build system. It requires wayland, wlroots and xkbcommon to be installed. Note that Cagebreak is @@ -57,14 +109,14 @@ breaking changes as soon as they occur. Simply execute the following steps to build Cagebreak: ``` -$ meson build +$ meson setup build $ ninja -C build ``` #### Release Build By default, this builds a debug build. To build a release build, use `meson -build --buildtype=release`. +setup build --buildtype=release`. ##### Xwayland Support @@ -84,178 +136,129 @@ installed. Then, add `-Dman-pages=true` to the `meson` command. You can start Cagebreak by running `./build/cagebreak`. If you run it from within an existing X11 or Wayland session, it will open in a virtual output as a window in your existing session. If you run it in a TTY, it'll run with the -KMS+DRM backend. For more configuration options, see the man pages. +KMS+DRM backend. Note that a configuration file is required. For more +configuration options, see the man pages. -## Contributing to Cagebreak +Please see `example_scripts/` for example scripts and a basis to customize +from. -Cagebreak is currently developed to fit the needs of its creators. Should you -desire to implement a feature, please let us know in advance by opening -an issue. However, the feature set is intentionally limited (i.e. we removed -support for a desktop background) and will continue to be so in the future. +#### Usage Philosophy -Nonetheless, don't be intimidated by the (slightly lengthy) release checklist -or any other part of this file. Do what you can, open an issue and we will -collaborate toward a solution. +Cagebreak was originally built to suit the needs of its creators. This section outlines +how we intended some parts of cagebreak and might ease learning how to use cagebreak a +little bit. Please note that this does not replace the man pages or the FAQ. +Also, this is in no way intended as a guide on how cagebreak must be used but rather +as a source of inspiration and of explanations for why certain particularities. -### Branching Strategy and Versioning +1. Cagebreak is keyboard-based. Everything regarding cagebreak can be done + through the keyboard and it is our view that it should be. This does not mean + that pointers, touchpads and such are not available for the few applications + that do require them. -There exists a branch `development` to which all reasonable code -is comitted for final testing. +2. Cagebreak is a tiling compositor. Every view takes up as much screen space + as possible. We believe this is useful, as only very few programs are typically + necessary to complete a task. To manage multiple tasks concurrently, we use + workspaces. -Once `development` is ready for a release, it is merged into `master` (possibly via -a cherry-picked branch), creating a new release, which is tagged and signed. +3. Each task deserves its own workspace. Any given task (the sort of thing you + might find in your calendar or on your todo list) probably requires very few + views and ideally, these take up as much of the screen as possible. -All releases are tagged according to [semantic versioning](https://semver.org) guidelines. +> Combining 2. and 3. might look like this in practice: -In the past, our git history did not perfectly reflect this scheme. +> * Task 1: Edit introduction section for paper on X +> * Task 2: Coordinate event with person Y -### Releases +> * split screen vertically +> * open web browser or pdf viewer to read literature +> * focus next +> * open editor +> * change to a different workspace +> * split screen vertically +> * open calendar application +> * focus next +> * open chat application -The release checklist must be completely fulfilled in one run for a release to -occur. +> Now each task has its own workspace and switching between tasks is possible +> by switching between workspaces. - * [ ] `git checkout development` - * [ ] `git pull origin development` - * [ ] `git push origin development` - * [ ] `ninja -C build clang-format` makes no changes - * [ ] New version number determined according to [semantic versioning](https://semver.org) guidelines - * [ ] Relevant Documentation completed - * [ ] New features - * [ ] man pages - * [ ] man/cagebreak - * [ ] man/cagebreak-config - * [ ] Set EPOCH to release day in man generation in meson.build - * [ ] FAQ.md - * [ ] Changelog.md for major and minor releases but not patches - * [ ] Check features for SECURITY.md relevance (changes to socket scope - for example) - * [ ] Fixed bugs documented in Bugs.md - * [ ] Include issue description from github - * [ ] Testing - * [ ] Manual testing - * [ ] Libfuzzer testing - * [ ] Build version without xwayland support - * [ ] Version Number - * [ ] meson.build - * [ ] git tag - * [ ] man pages - * [ ] meson.build reproducible build versions are current archlinux libraries and gcc - * [ ] Cagebreak is reproducible on multiple machines - * [ ] Documented reproducible build artefacts - * [ ] Hashes of the artefacts in README.md - * [ ] Renamed previous signatures - * [ ] Created gpg signature of the artefacts - * [ ] `gpg --detach-sign -u keyid cagebreak` - * [ ] `gpg --detach-sign -u keyid cagebreak.1` - * [ ] `gpg --detach-sign -u keyid cagebreak-config.5` - * [ ] `git add` relevant files - * [ ] `git commit` - * [ ] `git push origin development` - * [ ] Determined commit and tag message (Start with "Release version_number\n\n") - * [ ] Mentioned fixed Bugs.md issues ("Fixed Issue n") - * [ ] Mentioned other important changes - * [ ] `git checkout master` - * [ ] `git merge --squash development` - * [ ] `git commit` and insert message - * [ ] `git tag -u keyid version HEAD` and insert message - * [ ] `git tag -v version` and check output - * [ ] `git push --tags origin master` - * [ ] `git checkout development` - * [ ] `git merge master` - * [ ] `git push --tags origin development` - * [ ] `git archive --prefix=cagebreak/ -o release_version.tar.gz tags/version .` - * [ ] Create release-artefacts_version.tar.gz - * [ ] `mkdir release-artefacts_version` - * [ ] `cp build/cagebreak release-artefacts_version/` - * [ ] `cp build/cagebreak.sig release-artefacts_version/` - * [ ] `cp build/cagebreak.1 release-artefacts_version/` - * [ ] `cp build/cagebreak.1.sig release-artefacts_version/` - * [ ] `cp build/cagebreak-config.5 release-artefacts_version/` - * [ ] `cp build/cagebreak-config.5.sig release-artefacts_version/` - * [ ] `cp LICENSE release-artefacts_version/` - * [ ] `cp README.md release-artefacts_version/` - * [ ] `cp SECURITY.md release-artefacts_version/` - * [ ] `cp FAQ.md release-artefacts_version/` - * [ ] `export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) ; tar --sort=name --mtime= --owner=0 --group=0 --numeric-owner -czf release-artefacts_version.tar.gz release-artefacts_version` - * [ ] Checked archive - * [ ] tar -xvf release_version.tar.gz - * [ ] cd cagebreak - * [ ] meson build --buildtype=release - * [ ] ninja -C build - * [ ] gpg --verify ../signatures/cagebreak.sig build/cagebreak - * [ ] cd .. - * [ ] rm -rf cagebreak - * [ ] `gpg --detach-sign -u keyid release_version.tar.gz` - * [ ] `gpg --detach-sign -u keyid release-artefacts_version.tar.gz` - * [ ] Upload archives and signatures as release assets +> Note that, for example by using the socket, more advanced setups are +> possible. But the user is warned that excessive tweaking eats into the work +> to be done. -### Reproducible Builds +4. Use keybindings and terminal emulators for the right purpose. Given the + philosophy outlined above you probably launch the same few programs very + often and others are very rarely used. We believe that commonly + used programs should have their own keybindings together with the most + important cagebreak commands. All the rarely used programs should be launched + from a terminal emulator as they probably require special flags, environment + variables and file paths anyway. -Cagebreak offers reproducible builds given the exact library versions specified -in `meson.build`. Should a version mismatch occur, a warning will be emitted. We have -decided on this compromise to allow flexibility and security. In general we will -adapt the versions to the packages available under Arch Linux at the time of -release. +> In practice this means thinking about the applications and cagebreak commands +> you use and taking your keyboard layout into account when defining keybindings for +> your individual needs. -There are reproducibility issues up to and including release `1.2.0`. See -`Issue 5` in [Bugs.md](Bugs.md). +5. Cagebreak can't do everything, but with scripting you can do most things. + Through the socket and with a bit of scripting, you can use the internal state + of cagebreak in combination with cagebreak commands and the full power of + a scripting language of your choice to do almost whatever you want. -#### Reproducible Build Instructions +> Example scripts can be found in the repository under `example_scripts/`. -All hashes and signatures are provided for the following build instructions. +## Contributing -``` -meson build -Dxwayland=true -Dman-pages=true --buildtype=release -ninja -C build -``` + * Read this document. + * Just [open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your feature request. + We will consider the proposal and get back to you. + * Don't open a pull request without asking first. We might not accept your + code and it would be sad to waste the effort. + * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never + had to intervene - Please keep it that way!) -#### Hashes for Builds +### Good First Contributions -For every release after 1.0.5, hashes will be provided. + * Reviewing the project is always welcome. + * Read the code. + * Read the documentation. + * Test whether the documentation matches the code. + * Test Cagebreak in more esoteric setups (many monitors, for instance). + * Compile the code. + * Ideas on improving the testing and quality assurance are particularly + welcome. + * If you want, you can share your cagebreak scripts and we might include them + in the repository provided you agree to release them under MIT and we agree + with the use case and coding style. + * Iff you are happy with Cagebreak and use Arch Linux, you may vote for + [Cagebreak in the AUR](https://aur.archlinux.org/packages/cagebreak). + * The points above still apply. -For every release after 1.7.0, hashes will be provided for man pages too. +### Philosophy -See [Hashes.md](Hashes.md) +Cagebreak is currently developed to fit the needs of its creators. -#### GPG Signatures +The feature set is intentionally limited - we removed +support for a desktop background image for example. -For every release after 1.0.5, a GPG signature will be provided in `signatures`. +Nonetheless, don't be intimidated by any other part of this file. +Do your best and we will collaborate toward a solution. -The current signature is called `cagebreak.sig`, whereas all older signatures -will be named after their release version. +## Development -Due to errors in the release process, the releases 1.7.1 and 1.7.2 did not include the release -signatures in the appropriate folder of the git repository. However, signatures were provided -as release-artefacts at the time of release. The signatures were introduced into the -repository with 1.7.3. The integrity of cagebreak is still the same because the signatures were -provided as release-artefacts (which were themselves signed) and the hashes in README.md -are part of a signed release tag. +### Compatibility & Development Distribution -#### Signing Keys +Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the libraries +(and software versions) as they are obtained through [pacman](https://wiki.archlinux.org/title/Pacman) +at the time of release. Any other use is out of scope. -All releases are signed by at least one of the following collection of -keys. +However, Cagebreak may also work on other distributions given the +proper library versions (Some package maintainers have done this and it +seems to work (To date, we dealt with a few Issues and never felt the +need to ask for the distribution the user was having the issue on.)). - * E79F6D9E113529F4B1FFE4D5C4F974D70CEC2C5B - * 4739D329C9187A1C2795C20A02ABFDEC3A40545F - * 7535AB89220A5C15A728B75F74104CC7DCA5D7A8 - * 827BC2320D535AEAD0540E6E2E66F65D99761A6F - * A88D7431E5BAAD0B6EAE550AC8D61D8BD4FA3C46 - * 8F872885968EB8C589A32E9539ACC012896D450F - * 896B92AF738C974E0065BF42F2576BD366156BB9 - * AA927AFD50AF7C6810E69FE8274F2C605359E31B - * BE2DED372287BC4EB2213E13A0C743848A638955 - * 0F3476E4B2404F95EC41600683D5810F7911B020 +[![Packaging status](https://repology.org/badge/vertical-allrepos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) -Should we at any point retire a key, we will only replace it with keys signed -by at least one of the above collection. - -We registered project-repo.co and added mail addresses after release `1.3.0`. - -We now have a mail address and its key is signed by signing keys. See Security -Bugs for details. - -The full public keys can be found in `keys/` along with any revocation certificates. +You should use Arch Linux if you want to modify Cagebreak +for yourself. ### GCC and -fanalyzer @@ -298,7 +301,7 @@ Here is an example workflow: ``` rm -rf build -CC=clang meson build -Dfuzz=true -Db_sanitize=address,undefined -Db_lundef=false +CC=clang meson setup build -Dfuzz=true -Db_sanitize=address,undefined -Db_lundef=false ninja -C build/ mkdir build/fuzz_corpus cp examples/config build/fuzz_corpus/ @@ -316,35 +319,254 @@ Currently, there are memory leaks which do not seem to stem from our code but ra the code of wl-roots or some other library we depend on. We are working on the problem. In the meantime, add `-Db_detect-leaks=0` to the meson command to exclude memory leaks. +### Reproducible Builds + +Cagebreak offers reproducible builds given the exact library versions specified +in `meson.build`. Should a version mismatch occur, a warning will be emitted. We have +decided on this compromise to allow flexibility and security. In general we will +adapt the versions to the packages available under Arch Linux at the time of +release. + +There are reproducibility issues up to and including release `1.2.0`. See +`Issue 5` in [Bugs.md](Bugs.md). + +#### Reproducible Build Instructions + +All hashes and signatures are provided for the following build instructions. + +``` +meson setup build -Dxwayland=true -Dman-pages=true --buildtype=release +ninja -C build +``` + +#### Hashes for Builds + +For every release after 1.0.5, hashes will be provided. + +For every release after 1.7.0, hashes will be provided for man pages too. + +See [Hashes.md](Hashes.md) + +#### GPG Signatures + +For every release after 1.0.5, a GPG signature will be provided in `signatures`. + +The current signature is called `cagebreak.sig`, whereas all older signatures +will be named after their release version. + +Due to errors in the release process, the releases 1.7.1 and 1.7.2 did not include the release +signatures in the appropriate folder of the git repository. However, signatures were provided +as release-artefacts at the time of release. The signatures were introduced into the +repository with 1.7.3. The integrity of cagebreak is still the same because the signatures were +provided as release-artefacts (which were themselves signed) and the hashes in Hashes.md +are part of a signed release tag. + +#### Signing Keys + +All releases are signed by at least one of the following collection of +keys. + + * E79F6D9E113529F4B1FFE4D5C4F974D70CEC2C5B + * 4739D329C9187A1C2795C20A02ABFDEC3A40545F + * 7535AB89220A5C15A728B75F74104CC7DCA5D7A8 + * 827BC2320D535AEAD0540E6E2E66F65D99761A6F + * A88D7431E5BAAD0B6EAE550AC8D61D8BD4FA3C46 + * 8F872885968EB8C589A32E9539ACC012896D450F + * 896B92AF738C974E0065BF42F2576BD366156BB9 + * AA927AFD50AF7C6810E69FE8274F2C605359E31B + * BE2DED372287BC4EB2213E13A0C743848A638955 + * 0F3476E4B2404F95EC41600683D5810F7911B020 + +Should we at any point retire a key, we will only replace it with keys signed +by at least one of the above collection. + +We registered project-repo.co and added mail addresses after release `1.3.0`. + +We now have a mail address and its key is signed by signing keys. See Security +Bugs for details. + +The full public keys can be found in `keys/` along with any revocation certificates. + +### Versioning & Branching Strategy + +Cagebreak uses [semantic versioning](https://semver.org). + +There are three permanent branches in cagebreak: + + * `master` (for releases) + * `development` (for polishing code between releases) + * `hotfix` (for small emergent releases, usually up-to-date with master) + +Releases are merged to master as per the release procedure, with +reasonable exceptions as the situation requires. + +The release commit is tagged with the release version. + +In the past, our git history did not perfectly reflect this scheme. + +### Release Procedure + +The release procedure outlines the process for a release to occur. + + * [ ] `git checkout development` + * [ ] `git pull origin development` + * [ ] `git push origin development` + * [ ] New semantic version number determined + * [ ] Adjust version number + * [ ] meson.build + * [ ] git tag + * [ ] man pages + * [ ] README.md repology badges minversion + * [ ] Relevant Documentation completed + * [ ] New features + * [ ] man pages + * [ ] cagebreak + * [ ] cagebreak-config + * [ ] cagebreak-socket + * [ ] example config + * [ ] Set EPOCH to release day in man generation in meson.build + * [ ] FAQ.md + * [ ] Changelog.md for major and minor releases but not patches + * [ ] Check features for SECURITY.md relevance (changes to socket scope + for example) + * [ ] Synchronize any socket changes to cagebreak-socket man page + * [ ] Fixed bugs documented in Bugs.md + * [ ] Include issue discussion from github, where applicable + * [ ] Testing + * [ ] Manual testing + * [ ] Libfuzzer testing + * [ ] Build version without xwayland support + * [ ] meson.build reproducible build versions are current archlinux libraries and gcc + * [ ] wlr_xdg_shell version check + * [ ] `ninja -C build clang-format` makes no changes + * [ ] `ninja -C build scan-build` shows no issues + * [ ] Cagebreak is reproducible on multiple machines + * [ ] Documented reproducible build artefacts + * [ ] Hashes of the artefacts in Hashes.md + * [ ] Renamed previous signatures + * [ ] Created gpg signature of the artefacts + * [ ] `gpg --detach-sign -u keyid cagebreak` + * [ ] `gpg --detach-sign -u keyid cagebreak.1` + * [ ] `gpg --detach-sign -u keyid cagebreak-config.5` + * [ ] `gpg --detach-sign -u keyid cagebreak-socket.7` + * [ ] `git add` relevant files + * [ ] `git commit` + * [ ] `git push origin development` + * [ ] Determined commit and tag message (Start with "Release version_number\n\n") + * [ ] Mentioned fixed Bugs.md issues ("Fixed Issue n") + * [ ] Mentioned other important changes + * [ ] `git checkout master` + * [ ] `git merge --squash development` + * [ ] `git commit` and insert message + * [ ] `git tag -u keyid version HEAD` and insert message + * [ ] `git tag -v version` and check output + * [ ] `git push --tags origin master` + * [ ] `git checkout development` (merge to development depends on whether release was a hotfix) + * [ ] `git merge master` + * [ ] `git push --tags origin development` + * [ ] `git checkout hotfix` (hotfix is to be kept current with master after releases) + * [ ] `git merge master` + * [ ] `git push --tags origin hotfix` + * [ ] `git archive --prefix=cagebreak/ -o release_version.tar.gz tags/version .` + * [ ] Create release-artefacts_version.tar.gz + * [ ] `mkdir release-artefacts_version` + * [ ] `cp build/cagebreak release-artefacts_version/` + * [ ] `cp build/cagebreak.sig release-artefacts_version/` + * [ ] `cp build/cagebreak.1 release-artefacts_version/` + * [ ] `cp build/cagebreak.1.sig release-artefacts_version/` + * [ ] `cp build/cagebreak-config.5 release-artefacts_version/` + * [ ] `cp build/cagebreak-config.5.sig release-artefacts_version/` + * [ ] `cp build/cagebreak-socket.7 release-artefacts_version/` + * [ ] `cp build/cagebreak-socket.7.sig release-artefacts_version/` + * [ ] `cp LICENSE release-artefacts_version/` + * [ ] `cp README.md release-artefacts_version/` + * [ ] `cp SECURITY.md release-artefacts_version/` + * [ ] `cp FAQ.md release-artefacts_version/` + * [ ] `export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) ; tar --sort=name --mtime= --owner=0 --group=0 --numeric-owner -czf release-artefacts_version.tar.gz release-artefacts_version` + * [ ] Checked archive + * [ ] tar -xvf release_version.tar.gz + * [ ] cd cagebreak + * [ ] meson setup build -Dxwayland=true -Dman-pages=true --buildtype=release + * [ ] ninja -C build + * [ ] gpg --verify ../signatures/cagebreak.sig build/cagebreak + * [ ] cd .. + * [ ] rm -rf cagebreak + * [ ] `gpg --detach-sign -u keyid release_version.tar.gz` + * [ ] `gpg --detach-sign -u keyid release-artefacts_version.tar.gz` + * [ ] Upload archives and signatures as release assets + +## Roadmap + +Cagebreak plans to do or keep doing the following things +in the future: + + * React to all issues. + * Add or modify features, which the authors find convenient or important. + * Improve the [OpenSSF Best Practices Badge Program](https://bestpractices.coreinfrastructure.org/en) level + +## Governance + +Cagebreak is managed by project-repo. + +Project-repo is a pseudonym of at least two individuals acting +as benevolent dictators for the project by the others mutual consent. + +The individuals comprising project-repo are not otherwise associated +by payment from any organisation or grant. + +For all intents and purposes consider project-repo as a single +benevolent dictator for life that happens to occupy at least two brains. + +### Roles + +There are members of project-repo and those who are not. + +There are no specific roles forced unto anyone. + +### Bus Factor + +The Bus Factor is a measure of how many people have to be +incapacitated for a project to be unable to continue. + +The current bus factor for Cagebreak is: 1 + +Project-repo could still react to issues (even confidential +e-mails) and fix easier issues if any one individual were +incapacitated. + +However, not all aspects of the code or release engineering +are fully resilient to the loss of any one individual. + +We strive to improve the Bus Factor to at least two in all +aspects of Cagebreak. + +### Governance Issues + +Anyone can use the information in [SECURITY.md](SECURITY.md) to +contact the members of project-repo and bring governance +issues to their attention. + ## Bugs -For any bug, please [create an -issue](https://github.com/project-repo/cagebreak/issues/new) on -[GitHub](https://github.com/project-rep/cagebreak). +For any bug, please [create an issue](https://github.com/project-repo/cagebreak/issues/new) on +[GitHub](https://github.com/project-repo/cagebreak). Fixed bugs are to be assigned a number and summarized inside Bugs.md for future reference independent of github, in case this service is unavailable. -Mail contact: `cagebreak @ project-repo . co` - -GPG Fingerprints: - - * B15B92642760E11FE002DE168708D42451A94AB5 - * F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C - * 3ACEA46CCECD59E4C8222F791CBEB493681E8693 - -See [SECURITY.md](SECURITY.md) for details. - -## Changelog - -See [Changelog.md](Changelog.md) +For other means of contacting the Cagebreak authors and for security issues +see [SECURITY.md](SECURITY.md). ## Contributors * Aisha Tammy * [make man pages optional](https://github.com/project-repo/cagebreak/pull/4), released in 1.6.0 with slight modifications + * Oliver Friedmann + * [Add output scaling](https://github.com/project-repo/cagebreak/pull/34), released + in 2.0.0 with slight modifications ## License -Please see [LICENSE](https://github.com/project-repo/cagebreak/blob/master/LICENSE) +MIT, please see [LICENSE](https://github.com/project-repo/cagebreak/blob/master/LICENSE). + diff --git a/SECURITY.md b/SECURITY.md index 5f8ee2c..bd7c388 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,10 +1,13 @@ # Security -The main possibility for security bugs to occur in cagebreak is by privilege -escalation using the socket. Indeed, any program with access to the socket -immediately gains arbitrary code execution rights. As of right now, the socket -is world-writable. If you disagree with this threat model, you may contact -us via email (See section Email Contact below.) or [open an issue on github](https://github.com/project-repo/cagebreak/issues/new). +The main possibility for security bugs in cagebreak is by privilege +escalation through the socket. Any program with access to the socket +immediately gains arbitrary code execution rights. The socket +is restricted to the user of the cagebreak process (700) and has to +be explicitely enabled using the `-e` flag on invocation. + +If you disagree with this threat model, you may contact us via email (See +section Email Contact below.) or [open an issue on github](https://github.com/project-repo/cagebreak/issues/new). Should any problem with the github issue system arise or any other reason for (potentially confidential) contact with the Cagebreak authors appear, @@ -12,9 +15,9 @@ you may contact us via email (See section Email Contact below.). ## Supported Versions -The latest release always contains the latest bug fixes and features. -There are no official backports for security vulnerabilities. Builds -are reproducible under conditions outlined in [README.md](README.md). +The most recent release always contains the latest bug fixes and features. +There are no official backports for security vulnerabilities. +Builds are reproducible under conditions outlined in [README.md](README.md). ## Bug Reports @@ -25,20 +28,20 @@ is available below. ## Email Contact -Should you want to get in touch with the developers of cagebreak to report +If you want to get in touch with the developers of cagebreak to report a security vulnerability or anything else via email, contact `cagebreak @ project-repo . co`. -We will try to respond to everything that is not obvious spam. +We try to respond to everything that is not obvious spam. ### GPG-Encrypted Emails If you can, please encrypt your email with the appropriate GPG key found in `keys/` and sign your message with your own key. - * B15B92642760E11FE002DE168708D42451A94AB5 - * F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C - * 3ACEA46CCECD59E4C8222F791CBEB493681E8693 +* B15B92642760E11FE002DE168708D42451A94AB5 +* F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C +* 3ACEA46CCECD59E4C8222F791CBEB493681E8693 Note that our keys are signed by cagebreak signing keys. @@ -47,21 +50,23 @@ public key or provide the fingerprint and directions to obtain the key. ## Threat Model -Cagebreak is a wayland compositor, which is run by the user of the system +Cagebreak is a wayland compositor run by the user of the system and thus has access to whichever resources this user has access to. Cagebreak can restrict other programs in no way, because this would hamper usability (consider a web browser unable to write a downloaded file to disk -for instance). There is no transmission of information by cagebreak other -than to the screens, ipc and potentially other documented local channels. +for instance). + +There is no transmission of information by cagebreak other than to the +screens, ipc and potentially other documented local channels. ### STRIDE Threat List This is not a thorough analysis, just an overview of the ways in which cagebreak -has/does not have an attack surface. +has (no) attack surface. #### Spoofing -Not applicable - Using cagebreak already requires a login as a user. +Not applicable - Using Cagebreak already requires a login as a user. #### Tampering @@ -72,7 +77,7 @@ Not applicable - Cagebreak must allow system manipulation for user software. Not applicable - There are no prohibited operations (See Tampering above.). While cagebreak does send events over documented channels there is no logging activated by default, though, of course, this can be changed by the user -by logging socket output for example. +by logging socket output (if enabled) for example. #### Information Disclosure @@ -82,10 +87,25 @@ and any software run by the user may exfiltrate any data the user has access to. #### Denial of Service Not applicable - Cagebreak offers functionality to terminate itself, which is -available to all user software over the socket. +available to all user software over the socket if the socket is enabled. -#### Elevation of privilege +#### Elevation of Privilege Software may gain arbitrary code execution rights if it has access to the Cagebreak socket. Privilege escalation to root is unlikely since privileges are dropped before any user input is accepted. + +## GPG Keys of the Cagebreak Repository + +All Cagebreak project keys are found under keys/ in the cagebreak +repository (the public keys anyway). + +The most trusted keys of the Cagebreak project are its signing keys, +all signing keys are signed by at least one of its predecessors and at +least one non-expired signing key is used at the time of release to +sign the commit tag and the release code tarball. + +Signing keys are also used to lend credence to other keys in the Cagebreak +project, such as the keys for email correspondence and the key used in the +cagebreak-pkgbuild repository. + diff --git a/cagebreak.c b/cagebreak.c index 97f4f91..0c5c247 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -1,12 +1,8 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200812L +#define _DEFAULT_SOURCE #include "config.h" @@ -16,8 +12,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -31,16 +29,19 @@ #include #include #include +#include +#include +#include #include #include -#if CG_HAS_XWAYLAND -#include -#endif +#include +#include #include #include #include #include #if CG_HAS_XWAYLAND +#include #include #endif @@ -53,6 +54,7 @@ #include "parse.h" #include "seat.h" #include "server.h" +#include "workspace.h" #include "xdg_shell.h" #if CG_HAS_XWAYLAND #include "xwayland.h" @@ -123,37 +125,21 @@ usage(FILE *file, const char *const cage) { fprintf(file, "Usage: %s [OPTIONS]\n" "\n" - " -r\t Rotate the output 90 degrees clockwise, specify up to three " - "times\n" -#ifdef DEBUG - " -D\t Turn on damage tracking debugging\n" -#endif - " -h\t Display this help message\n" - " -v\t Show the version number and exit\n" - " -s\t Show information about the current setup and exit\n", + " -c \t Load configuration file from \n" + " -e\t\t Enable socket\n" + " -h\t\t Display this help message\n" + " -s\t\t Show information about the current setup and exit\n" + " -v\t\t Show the version number and exit\n", cage); } static bool -parse_args(struct cg_server *server, int argc, char *argv[]) { +parse_args(struct cg_server *server, int argc, char *argv[], + char **config_path) { int c; -#ifdef DEBUG - while((c = getopt(argc, argv, "rDhvs")) != -1) { -#else - while((c = getopt(argc, argv, "rhvs")) != -1) { -#endif + server->enable_socket = false; + while((c = getopt(argc, argv, "c:hvse")) != -1) { switch(c) { - case 'r': - server->output_transform++; - if(server->output_transform > WL_OUTPUT_TRANSFORM_270) { - server->output_transform = WL_OUTPUT_TRANSFORM_NORMAL; - } - break; -#ifdef DEBUG - case 'D': - server->debug_damage_tracking = true; - break; -#endif case 'h': usage(stdout, argv[0]); return false; @@ -163,6 +149,15 @@ parse_args(struct cg_server *server, int argc, char *argv[]) { case 's': show_info = true; break; + case 'c': + if(optarg != NULL) { + *config_path = strdup(optarg); + optarg = NULL; + } + break; + case 'e': + server->enable_socket = true; + break; default: usage(stderr, argv[0]); return false; @@ -187,9 +182,28 @@ set_configuration(struct cg_server *server, config_file_path); return 1; } - char line[MAX_LINE_SIZE * sizeof(char)]; - for(unsigned int line_num = 1; - fgets(line, MAX_LINE_SIZE, config_file) != NULL; ++line_num) { + uint32_t line_length = 64; + char *line = calloc(line_length, sizeof(char)); + for(unsigned int line_num = 1;; ++line_num) { + while(true) { + if(fgets(line + strlen(line), line_length - strlen(line), + config_file) == NULL) { + break; + } + if(strcspn(line, "\n") != line_length - 1) { + break; + } + line_length *= 2; + line = reallocarray(line, line_length, sizeof(char)); + if(line == NULL) { + wlr_log(WLR_ERROR, "Could not allocate buffer for reading " + "configuration file."); + return 1; + } + } + if(strlen(line) == 0) { + break; + } line[strcspn(line, "\n")] = '\0'; if(*line != '\0' && *line != '#') { char *errstr; @@ -200,16 +214,22 @@ set_configuration(struct cg_server *server, if(errstr != NULL) { free(errstr); } + free(line); return -1; } } + memset(line, 0, line_length * sizeof(char)); } + free(line); fclose(config_file); return 0; } char * -get_config_file() { +get_config_file(char *udef_path) { + if(udef_path != NULL) { + return strdup(udef_path); + } const char *config_home_path = getenv("XDG_CONFIG_HOME"); char *addition = "/cagebreak/config"; if(config_home_path == NULL || config_home_path[0] == '\0') { @@ -236,25 +256,30 @@ main(int argc, char *argv[]) { struct wl_event_source *sigint_source = NULL; struct wl_event_source *sigterm_source = NULL; struct wl_event_source *sigalrm_source = NULL; + struct wl_event_source *sigpipe_source = NULL; struct wlr_backend *backend = NULL; struct wlr_compositor *compositor = NULL; + struct wlr_subcompositor *subcompositor = NULL; struct wlr_data_device_manager *data_device_manager = NULL; struct wlr_server_decoration_manager *server_decoration_manager = NULL; struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager = NULL; struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager = NULL; struct wlr_screencopy_manager_v1 *screencopy_manager = NULL; struct wlr_data_control_manager_v1 *data_control_manager = NULL; + struct wlr_viewporter *viewporter = NULL; + struct wlr_presentation *presentation = NULL; struct wlr_xdg_output_manager_v1 *output_manager = NULL; struct wlr_gamma_control_manager_v1 *gamma_control_manager = NULL; struct wlr_xdg_shell *xdg_shell = NULL; -#if CG_HAS_XWAYLAND - struct wlr_xwayland *xwayland = NULL; - struct wlr_xcursor_manager *xcursor_manager = NULL; -#endif + wl_list_init(&server.input_config); + wl_list_init(&server.output_config); + wl_list_init(&server.output_priorities); + int ret = 0; - if(!parse_args(&server, argc, argv)) { - return 1; + char *config_path = NULL; + if(!parse_args(&server, argc, argv, &config_path)) { + goto end; } #ifdef DEBUG @@ -263,25 +288,34 @@ main(int argc, char *argv[]) { wlr_log_init(WLR_ERROR, NULL); #endif - wl_list_init(&server.input_config); - wl_list_init(&server.output_config); - server.modes = malloc(4 * sizeof(char *)); if(!server.modes) { wlr_log(WLR_ERROR, "Error allocating mode array"); - return -1; + goto end; } /* Wayland requires XDG_RUNTIME_DIR to be set. */ if(!getenv("XDG_RUNTIME_DIR")) { - wlr_log(WLR_ERROR, "XDG_RUNTIME_DIR is not set in the environment"); - return 1; + wlr_log(WLR_INFO, "XDG_RUNTIME_DIR is not set in the environment"); } server.wl_display = wl_display_create(); if(!server.wl_display) { wlr_log(WLR_ERROR, "Cannot allocate a Wayland display"); - return 1; + free(server.modes); + server.modes = NULL; + goto end; + } + + server.xcursor_size = XCURSOR_SIZE; + const char *env_cursor_size = getenv("XCURSOR_SIZE"); + if(env_cursor_size && strlen(env_cursor_size) > 0) { + errno = 0; + char *end; + unsigned size = strtoul(env_cursor_size, &end, 10); + if(!*end && errno == 0) { + server.xcursor_size = size; + } } server.running = true; @@ -293,10 +327,12 @@ main(int argc, char *argv[]) { if(server.modes[0] == NULL || server.modes[1] == NULL || server.modes[2] == NULL) { wlr_log(WLR_ERROR, "Error allocating default modes"); - return 1; + goto end; } server.nws = 1; + server.views_curr_id = 1; + server.tiles_curr_id = 1; server.message_config.fg_color[0] = 0.0; server.message_config.fg_color[1] = 0.0; server.message_config.fg_color[2] = 0.0; @@ -317,6 +353,8 @@ main(int argc, char *argv[]) { wl_event_loop_add_signal(event_loop, SIGTERM, handle_signal, &server); sigalrm_source = wl_event_loop_add_signal(event_loop, SIGALRM, handle_signal, &server); + sigpipe_source = + wl_event_loop_add_signal(event_loop, SIGPIPE, handle_signal, &server); server.event_loop = event_loop; backend = wlr_backend_autocreate(server.wl_display); @@ -345,6 +383,7 @@ main(int argc, char *argv[]) { ret = 1; goto end; } + server.allocator = wlr_allocator_autocreate(server.backend, server.renderer); if(!server.allocator) { @@ -352,6 +391,7 @@ main(int argc, char *argv[]) { ret = 1; goto end; } + wlr_renderer_init_wl_display(server.renderer, server.wl_display); server.bg_color = (float[4]){0, 0, 0, 1}; @@ -365,6 +405,20 @@ main(int argc, char *argv[]) { goto end; } + if(ipc_init(&server) != 0) { + wlr_log(WLR_ERROR, "Failed to initialize IPC"); + ret = 1; + goto end; + } + + server.scene = wlr_scene_create(); + if(!server.scene) { + wlr_log(WLR_ERROR, "Unable to create scene"); + ret = 1; + goto end; + } + wlr_scene_attach_output_layout(server.scene, server.output_layout); + compositor = wlr_compositor_create(server.wl_display, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); @@ -372,6 +426,13 @@ main(int argc, char *argv[]) { goto end; } + subcompositor = wlr_subcompositor_create(server.wl_display); + if(!subcompositor) { + wlr_log(WLR_ERROR, "Unable to create the wlroots subcompositor"); + ret = 1; + goto end; + } + data_device_manager = wlr_data_device_manager_create(server.wl_display); if(!data_device_manager) { wlr_log(WLR_ERROR, "Unable to create the data device manager"); @@ -420,7 +481,7 @@ main(int argc, char *argv[]) { &server.new_idle_inhibitor_v1); wl_list_init(&server.inhibitors); - xdg_shell = wlr_xdg_shell_create(server.wl_display); + xdg_shell = wlr_xdg_shell_create(server.wl_display, 3); if(!xdg_shell) { wlr_log(WLR_ERROR, "Unable to create the XDG shell interface"); ret = 1; @@ -451,6 +512,21 @@ main(int argc, char *argv[]) { wlr_server_decoration_manager_set_default_mode( server_decoration_manager, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + viewporter = wlr_viewporter_create(server.wl_display); + if(!viewporter) { + wlr_log(WLR_ERROR, "Unable to create the viewporter interface"); + ret = 1; + goto end; + } + + presentation = wlr_presentation_create(server.wl_display, server.backend); + if(!presentation) { + wlr_log(WLR_ERROR, "Unable to create the presentation interface"); + ret = 1; + goto end; + } + wlr_scene_set_presentation(server.scene, presentation); + export_dmabuf_manager = wlr_export_dmabuf_manager_v1_create(server.wl_display); if(!export_dmabuf_manager) { @@ -474,6 +550,13 @@ main(int argc, char *argv[]) { goto end; } + if(!wlr_primary_selection_v1_device_manager_create(server.wl_display)) { + wlr_log(WLR_ERROR, + "Unable to create the primary selection device manager"); + ret = 1; + goto end; + } + gamma_control_manager = wlr_gamma_control_manager_v1_create(server.wl_display); if(!gamma_control_manager) { @@ -483,40 +566,32 @@ main(int argc, char *argv[]) { } #if CG_HAS_XWAYLAND - xwayland = wlr_xwayland_create(server.wl_display, compositor, true); - if(!xwayland) { + server.xwayland = wlr_xwayland_create(server.wl_display, compositor, true); + if(!server.xwayland) { wlr_log(WLR_ERROR, "Cannot create XWayland server"); ret = 1; goto end; } server.new_xwayland_surface.notify = handle_xwayland_surface_new; - wl_signal_add(&xwayland->events.new_surface, &server.new_xwayland_surface); + wl_signal_add(&server.xwayland->events.new_surface, + &server.new_xwayland_surface); - xcursor_manager = wlr_xcursor_manager_create(DEFAULT_XCURSOR, XCURSOR_SIZE); - if(!xcursor_manager) { - wlr_log(WLR_ERROR, "Cannot create XWayland XCursor manager"); - ret = 1; - goto end; - } - - if(setenv("DISPLAY", xwayland->display_name, true) < 0) { + if(setenv("DISPLAY", server.xwayland->display_name, true) < 0) { wlr_log_errno(WLR_ERROR, "Unable to set DISPLAY for XWayland.", "Clients may not be able to connect"); } else { wlr_log(WLR_DEBUG, "XWayland is running on display %s", - xwayland->display_name); + server.xwayland->display_name); } - if(!wlr_xcursor_manager_load(xcursor_manager, 1)) { - wlr_log(WLR_ERROR, "Cannot load XWayland XCursor theme"); - } - struct wlr_xcursor *xcursor = - wlr_xcursor_manager_get_xcursor(xcursor_manager, DEFAULT_XCURSOR, 1); + struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( + server.seat->xcursor_manager, DEFAULT_XCURSOR, 1); + if(xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; - wlr_xwayland_set_cursor(xwayland, image->buffer, image->width * 4, - image->width, image->height, image->hotspot_x, - image->hotspot_y); + wlr_xwayland_set_cursor(server.xwayland, image->buffer, + image->width * 4, image->width, image->height, + image->hotspot_x, image->hotspot_y); } #endif @@ -537,13 +612,13 @@ main(int argc, char *argv[]) { wlr_log_errno(WLR_ERROR, "Unable to set WAYLAND_DISPLAY.", "Clients may not be able to connect"); } else { - wlr_log(WLR_DEBUG, - "Cagebreak " CG_VERSION " is running on Wayland display %s", + fprintf(stderr, + "Cagebreak " CG_VERSION " is running on Wayland display %s\n", socket); } #if CG_HAS_XWAYLAND - wlr_xwayland_set_seat(xwayland, server.seat->seat); + wlr_xwayland_set_seat(server.xwayland, server.seat->seat); #endif if(show_info) { @@ -557,14 +632,8 @@ main(int argc, char *argv[]) { exit(0); } - if(ipc_init(&server) != 0) { - wlr_log(WLR_ERROR, "Failed to initialize IPC"); - ret = 1; - goto end; - } - { // config_file should only be visible as long as it is valid - char *config_file = get_config_file(); + char *config_file = get_config_file(config_path); if(config_file == NULL) { wlr_log(WLR_ERROR, "Unable to get path to config file"); ret = 1; @@ -573,27 +642,35 @@ main(int argc, char *argv[]) { int conf_ret = set_configuration(&server, config_file); // Configurtion file not found - if(conf_ret == 1) { - char *default_conf = "/etc/xdg/cagebreak/config"; - wlr_log(WLR_ERROR, "Loading default configuration file: \"%s\"", - default_conf); - conf_ret = set_configuration(&server, default_conf); + if(conf_ret != 0) { + if(config_file == NULL) { + char *default_conf = "/etc/xdg/cagebreak/config"; + wlr_log(WLR_INFO, "Loading default configuration file: \"%s\"", + default_conf); + conf_ret = set_configuration(&server, default_conf); + } else { + conf_ret = 1; + } } - if(conf_ret != 0) { - free(config_file); + free(config_file); + if(conf_ret != 0 || !server.running) { ret = 1; goto end; } - free(config_file); } { - + struct wl_list tmp_list; + wl_list_init(&tmp_list); + wl_list_insert_list(&tmp_list, &server.outputs); + wl_list_init(&server.outputs); struct cg_output *output, *output_tmp; - wl_list_for_each_safe(output, output_tmp, &server.outputs, link) { + wl_list_for_each_safe(output, output_tmp, &tmp_list, link) { output_configure(&server, output); } + server.curr_output = + wl_container_of(server.outputs.next, server.curr_output, link); } /* Place the cursor to the top left of the output layout. */ @@ -601,21 +678,23 @@ main(int argc, char *argv[]) { wl_display_run(server.wl_display); -#if CG_HAS_XWAYLAND - wlr_xwayland_destroy(xwayland); - wlr_xcursor_manager_destroy(xcursor_manager); -#endif wl_display_destroy_clients(server.wl_display); end: + if(server.modes != NULL) { #if CG_HAS_FANALYZE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wanalyzer-double-free" #endif - for(unsigned int i = 0; server.modes[i] != NULL; ++i) { - free(server.modes[i]); + for(unsigned int i = 0; server.modes[i] != NULL; ++i) { + free(server.modes[i]); + } + free(server.modes); + } + + if(config_path != NULL) { + free(config_path); } - free(server.modes); struct cg_output_config *output_config, *output_config_tmp; wl_list_for_each_safe(output_config, output_config_tmp, @@ -625,19 +704,52 @@ end: free(output_config); } - keybinding_list_free(server.keybindings); - wl_event_source_remove(sigint_source); - wl_event_source_remove(sigterm_source); - wl_event_source_remove(sigalrm_source); + struct cg_input_config *input_config, *input_config_tmp; + wl_list_for_each_safe(input_config, input_config_tmp, &server.input_config, + link) { + wl_list_remove(&input_config->link); + if(input_config->identifier != NULL) { + free(input_config->identifier); + } + free(input_config); + } + + if(server.keybindings != NULL) { + keybinding_list_free(server.keybindings); + } + + if(server.message_config.font != NULL) { + free(server.message_config.font); + } + server.running = false; + if(server.seat != NULL) { + seat_destroy(server.seat); + } +#if CG_HAS_XWAYLAND + if(server.xwayland != NULL) { + wlr_xwayland_destroy(server.xwayland); + } +#endif + + if(sigint_source != NULL) { + wl_event_source_remove(sigint_source); + wl_event_source_remove(sigterm_source); + wl_event_source_remove(sigalrm_source); + wl_event_source_remove(sigpipe_source); + } - seat_destroy(server.seat); /* This function is not null-safe, but we only ever get here with a proper wl_display. */ - wl_display_destroy(server.wl_display); - wlr_output_layout_destroy(server.output_layout); + if(server.wl_display != NULL) { + wl_display_destroy(server.wl_display); + } + if(server.output_layout != NULL) { + wlr_output_layout_destroy(server.output_layout); + } - free(server.input); - free(server.message_config.font); + if(server.input != NULL) { + free(server.input); + } pango_cairo_font_map_set_default(NULL); cairo_debug_reset_static_data(); FcFini(); diff --git a/config.h.in b/config.h.in index 8495284..a79a80c 100644 --- a/config.h.in +++ b/config.h.in @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_CONFIG_H #define CG_CONFIG_H @@ -6,4 +9,6 @@ #mesondefine CG_VERSION +#define MAX_NESTING_LEVEL 50 + #endif diff --git a/example_scripts/cb_script_header.sh b/example_scripts/cb_script_header.sh new file mode 100644 index 0000000..9533beb --- /dev/null +++ b/example_scripts/cb_script_header.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX -License-Identifier: MIT + +named_pipe_send="$(mktemp -u)" +named_pipe_recv="$(mktemp -u)" +mkfifo "${named_pipe_send}" +mkfifo "${named_pipe_recv}" +nc -U "${CAGEBREAK_SOCKET}" < "${named_pipe_send}" > "${named_pipe_recv}"& +# The file descriptor 3 is set up to send commands to cagebreak and file +# descriptor 4 can be used to read events. Notice that events will pile up in +# file descriptor 4, so it is a good idea to continuously read from it or to +# clear it before starting a new transaction. +exec 3>"${named_pipe_send}" +exec 4<"${named_pipe_recv}" +# When the script exits, the os will clean up the pipe +rm "${named_pipe_recv}" +rm "${named_pipe_send}" diff --git a/example_scripts/focus_follows_cursor.sh b/example_scripts/focus_follows_cursor.sh new file mode 100644 index 0000000..79e2889 --- /dev/null +++ b/example_scripts/focus_follows_cursor.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX -License-Identifier: MIT + +# This script uses the cagebreak socket to modify the compositor's behaviour in +# such a way that the currently focussed tile follows the cursor, i.e. that the +# currently focussed tile is always the one within which the cursor is located. + +# Start up the ipc link +source "$(dirname "${BASH_SOURCE[0]}")/cb_script_header.sh" + +while IFS= read -r -d $'\0' event +do + # Remove the cg-ipc header + event="${event:6}" + if [[ "$(echo "${event}" | jq ".event_name")" = "\"cursor_switch_tile\"" ]] + then + new_tile="$(echo "${event}"|jq -r ".new_tile")" + new_output_id="$(echo "${event}"|jq -r ".new_output_id")" + # Send the new tile to focus to cagebreak + echo -e "screen ${new_output_id}\nfocus_tile ${new_tile}" >&3 + fi +done <&4 diff --git a/example_scripts/show_workspace_views.sh b/example_scripts/show_workspace_views.sh new file mode 100644 index 0000000..3be9cbb --- /dev/null +++ b/example_scripts/show_workspace_views.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# SPDX -License-Identifier: MIT + +# This script displays the process names of the views on the current workspace. + +# Start up the ipc link +source "$(dirname "${BASH_SOURCE[0]}")/cb_script_header.sh" + +echo "dump" >&3 + +while IFS= read -r -d $'\0' event +do + # Remove the cg-ipc header + event="${event:6}" + if [[ "$(echo "${event}" | jq ".event_name")" = "\"dump\"" ]] + then + curr_output="$(echo "${event}"|jq ".curr_output")" + curr_workspace="$(echo "${event}"|jq -r ".outputs.${curr_output}.curr_workspace")" + # Print the process names of the view on the current workspace. jq retrieves + # their PID and ps is then used to retrieve the process names. + (echo -n "message ";ps -o comm=Command -p $(echo "${event}"|jq -r ".outputs.${curr_output}.workspaces[$((curr_workspace-1))].views[].pid")|tail +2|sed ':a; N; $!ba; s/\n/||/g') >&3 + break + fi +done <&4 diff --git a/examples/config b/examples/config index e6a6cb5..d79a792 100644 --- a/examples/config +++ b/examples/config @@ -1,3 +1,5 @@ +# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# SPDX -License-Identifier: MIT ###################### # General settings an key bindings ###################### @@ -41,6 +43,9 @@ definekey resize j resizedown definekey resize k resizeup definekey resize Escape setmode top +#unhide cursor (default) +cursor enable + ###################### #Workspaces ###################### @@ -95,6 +100,7 @@ definekey top XF86MonBrightnessUp exec xbacklight -inc 1 #output eDP-1 disable #output eDP-1 enable #output eDP-1 prio 1 +#output eDP-2 pos 0 0 res 1366x768 rate 60 scale 2.0 ##################### #Input configuration diff --git a/fuzz/execl_override.c b/fuzz/execl_override.c index 316cf1e..9fc9e6e 100644 --- a/fuzz/execl_override.c +++ b/fuzz/execl_override.c @@ -1,5 +1,7 @@ -/* This file is used by the fuzzer in order to prevent executing shell commands. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT +// This file is used by the fuzzer in order to prevent executing shell commands. + #define _GNU_SOURCE #include "../output.h" #include diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index c94dd8b..c159538 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -1,10 +1,5 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -35,8 +30,12 @@ #include #include #include +#include +#include +#include #include #include +#include #if CG_HAS_XWAYLAND #include #endif @@ -88,15 +87,6 @@ drop_permissions(void) { return true; } -static bool -parse_args(struct cg_server *server, int argc, char *argv[]) { - server->output_transform = WL_OUTPUT_TRANSFORM_NORMAL; -#ifdef DEBUG - server->debug_damage_tracking = false; -#endif - return true; -} - void cleanup() { server.running = false; @@ -120,13 +110,11 @@ cleanup() { seat_destroy(server.seat); /* This function is not null-safe, but we only ever get here with a proper wl_display. */ - wl_display_destroy(server.wl_display); wlr_output_layout_destroy(server.output_layout); } int LLVMFuzzerInitialize(int *argc, char ***argv) { - struct wl_event_loop *event_loop = NULL; struct wlr_backend *backend = NULL; struct wlr_compositor *compositor = NULL; struct wlr_data_device_manager *data_device_manager = NULL; @@ -135,13 +123,21 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager = NULL; struct wlr_screencopy_manager_v1 *screencopy_manager = NULL; struct wlr_data_control_manager_v1 *data_control_manager = NULL; + struct wlr_viewporter *viewporter = NULL; + struct wlr_presentation *presentation = NULL; struct wlr_xdg_output_manager_v1 *output_manager = NULL; struct wlr_gamma_control_manager_v1 *gamma_control_manager = NULL; - int ret = 0; + struct wlr_xdg_shell *xdg_shell = NULL; +#if CG_HAS_XWAYLAND + struct wlr_xwayland *xwayland = NULL; +#endif + wl_list_init(&server.input_config); + wl_list_init(&server.output_config); + wl_list_init(&server.output_priorities); + wl_list_init(&server.outputs); + wl_list_init(&server.disabled_outputs); - if(!parse_args(&server, *argc, *argv)) { - return 1; - } + int ret = 0; #ifdef DEBUG wlr_log_init(WLR_DEBUG, NULL); @@ -149,33 +145,63 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { wlr_log_init(WLR_ERROR, NULL); #endif - wl_list_init(&server.input_config); + server.modes = malloc(4 * sizeof(char *)); + if(!server.modes) { + wlr_log(WLR_ERROR, "Error allocating mode array"); + goto end; + } /* Wayland requires XDG_RUNTIME_DIR to be set. */ if(!getenv("XDG_RUNTIME_DIR")) { - wlr_log(WLR_ERROR, "XDG_RUNTIME_DIR is not set in the environment"); - return 1; + wlr_log(WLR_INFO, "XDG_RUNTIME_DIR is not set in the environment"); } server.wl_display = wl_display_create(); if(!server.wl_display) { wlr_log(WLR_ERROR, "Cannot allocate a Wayland display"); - return 1; + free(server.modes); + server.modes = NULL; + goto end; + } + + server.xcursor_size = XCURSOR_SIZE; + const char *env_cursor_size = getenv("XCURSOR_SIZE"); + if(env_cursor_size && strlen(env_cursor_size) > 0) { + errno = 0; + char *end; + unsigned size = strtoul(env_cursor_size, &end, 10); + if(!*end && errno == 0) { + server.xcursor_size = size; + } } server.running = true; - server.modes = malloc(4 * sizeof(char *)); server.modes[0] = strdup("top"); server.modes[1] = strdup("root"); server.modes[2] = strdup("resize"); server.modes[3] = NULL; + if(server.modes[0] == NULL || server.modes[1] == NULL || + server.modes[2] == NULL) { + wlr_log(WLR_ERROR, "Error allocating default modes"); + goto end; + } server.nws = 1; - server.message_timeout = 2; + server.views_curr_id = 1; + server.tiles_curr_id = 1; + server.message_config.fg_color[0] = 0.0; + server.message_config.fg_color[1] = 0.0; + server.message_config.fg_color[2] = 0.0; + server.message_config.fg_color[3] = 1.0; - event_loop = wl_display_get_event_loop(server.wl_display); - server.event_loop = event_loop; + server.message_config.bg_color[0] = 0.9; + server.message_config.bg_color[1] = 0.85; + server.message_config.bg_color[2] = 0.85; + server.message_config.bg_color[3] = 1.0; + + server.message_config.display_time = 2; + server.message_config.font = strdup("pango:Monospace 10"); backend = wlr_multi_backend_create(server.wl_display); if(!backend) { @@ -201,11 +227,6 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; }; - if(!drop_permissions()) { - ret = 1; - goto end; - } - server.keybindings = keybinding_list_init(); if(server.keybindings == NULL || server.keybindings->keybindings == NULL) { wlr_log(WLR_ERROR, "Unable to allocate keybindings"); @@ -213,14 +234,13 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; } - wl_list_init(&server.output_config); - server.renderer = wlr_renderer_autocreate(backend); if(!server.renderer) { wlr_log(WLR_ERROR, "Unable to create the wlroots renderer"); ret = 1; goto end; } + server.allocator = wlr_allocator_autocreate(server.backend, server.renderer); if(!server.allocator) { @@ -228,16 +248,10 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { ret = 1; goto end; } + wlr_renderer_init_wl_display(server.renderer, server.wl_display); - server.bg_color = malloc(4 * sizeof(float)); - server.bg_color[0] = 0; - server.bg_color[1] = 0; - server.bg_color[2] = 0; - server.bg_color[3] = 1; - wl_list_init(&server.outputs); - wl_list_init(&server.disabled_outputs); - + server.bg_color = (float[4]){0, 0, 0, 1}; server.output_layout = wlr_output_layout_create(); if(!server.output_layout) { wlr_log(WLR_ERROR, "Unable to create output layout"); @@ -245,6 +259,27 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; } + if(ipc_init(&server) != 0) { + wlr_log(WLR_ERROR, "Failed to initialize IPC"); + ret = 1; + goto end; + } + + server.scene = wlr_scene_create(); + if(!server.scene) { + wlr_log(WLR_ERROR, "Unable to create scene"); + ret = 1; + goto end; + } + wlr_scene_attach_output_layout(server.scene, server.output_layout); + + compositor = wlr_compositor_create(server.wl_display, server.renderer); + if(!compositor) { + wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); + ret = 1; + goto end; + } + data_device_manager = wlr_data_device_manager_create(server.wl_display); if(!data_device_manager) { wlr_log(WLR_ERROR, "Unable to create the data device manager"); @@ -293,7 +328,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { &server.new_idle_inhibitor_v1); wl_list_init(&server.inhibitors); - xdg_shell = wlr_xdg_shell_create(server.wl_display); + xdg_shell = wlr_xdg_shell_create(server.wl_display, 3); if(!xdg_shell) { wlr_log(WLR_ERROR, "Unable to create the XDG shell interface"); ret = 1; @@ -324,6 +359,21 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { wlr_server_decoration_manager_set_default_mode( server_decoration_manager, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER); + viewporter = wlr_viewporter_create(server.wl_display); + if(!viewporter) { + wlr_log(WLR_ERROR, "Unable to create the viewporter interface"); + ret = 1; + goto end; + } + + presentation = wlr_presentation_create(server.wl_display, server.backend); + if(!presentation) { + wlr_log(WLR_ERROR, "Unable to create the presentation interface"); + ret = 1; + goto end; + } + wlr_scene_set_presentation(server.scene, presentation); + export_dmabuf_manager = wlr_export_dmabuf_manager_v1_create(server.wl_display); if(!export_dmabuf_manager) { @@ -347,17 +397,17 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; } - gamma_control_manager = - wlr_gamma_control_manager_v1_create(server.wl_display); - if(!gamma_control_manager) { - wlr_log(WLR_ERROR, "Unable to create the gamma control manager"); + if(!wlr_primary_selection_v1_device_manager_create(server.wl_display)) { + wlr_log(WLR_ERROR, + "Unable to create the primary selection device manager"); ret = 1; goto end; } - compositor = wlr_compositor_create(server.wl_display, server.renderer); - if(!compositor) { - wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); + gamma_control_manager = + wlr_gamma_control_manager_v1_create(server.wl_display); + if(!gamma_control_manager) { + wlr_log(WLR_ERROR, "Unable to create the gamma control manager"); ret = 1; goto end; } @@ -372,13 +422,6 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { server.new_xwayland_surface.notify = handle_xwayland_surface_new; wl_signal_add(&xwayland->events.new_surface, &server.new_xwayland_surface); - xcursor_manager = wlr_xcursor_manager_create(DEFAULT_XCURSOR, XCURSOR_SIZE); - if(!xcursor_manager) { - wlr_log(WLR_ERROR, "Cannot create XWayland XCursor manager"); - ret = 1; - goto end; - } - if(setenv("DISPLAY", xwayland->display_name, true) < 0) { wlr_log_errno(WLR_ERROR, "Unable to set DISPLAY for XWayland.", "Clients may not be able to connect"); @@ -387,18 +430,15 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { xwayland->display_name); } - if(wlr_xcursor_manager_load(xcursor_manager, 1)) { - wlr_log(WLR_ERROR, "Cannot load XWayland XCursor theme"); - } - struct wlr_xcursor *xcursor = - wlr_xcursor_manager_get_xcursor(xcursor_manager, DEFAULT_XCURSOR, 1); + struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( + server.seat->xcursor_manager, DEFAULT_XCURSOR, 1); + if(xcursor) { struct wlr_xcursor_image *image = xcursor->images[0]; wlr_xwayland_set_cursor(xwayland, image->buffer, image->width * 4, image->width, image->height, image->hotspot_x, image->hotspot_y); } - #endif const char *socket = wl_display_add_socket_auto(server.wl_display); @@ -418,42 +458,32 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { wlr_log_errno(WLR_ERROR, "Unable to set WAYLAND_DISPLAY.", "Clients may not be able to connect"); } else { - wlr_log(WLR_DEBUG, - "Cagebreak " CG_VERSION " is running on Wayland display %s", + fprintf(stderr, + "Cagebreak " CG_VERSION " is running on Wayland display %s\n", socket); } +#if CG_HAS_XWAYLAND + wlr_xwayland_set_seat(xwayland, server.seat->seat); +#endif + + /* Place the cursor to the top left of the output layout. */ + wlr_cursor_warp(server.seat->cursor, NULL, 0, 0); + + if(!drop_permissions()) { + ret = 1; + goto end; + } + /* Place the cursor to the topl left of the output layout. */ wlr_cursor_warp(server.seat->cursor, NULL, 0, 0); atexit(cleanup); - // server.wl_display->run = 1; return 0; end: cleanup(); return ret; } -void -move_cursor(char *line, struct cg_server *server) { - return; // TODO - long del = 0; - char *delstr = strtok_r(NULL, ";", &line); - enum wlr_axis_orientation orientation = - (*(line++) == '0') ? WLR_AXIS_ORIENTATION_VERTICAL - : WLR_AXIS_ORIENTATION_HORIZONTAL; - if(delstr == NULL) { - return; - } - del = strtol(delstr, NULL, 10); - struct wlr_event_pointer_axis event = {.device = NULL, - .time_msec = 0, - .source = WLR_AXIS_SOURCE_WHEEL, - .orientation = orientation, - .delta = del * 15, - .delta_discrete = del}; - // TODO dispatch_cursor_axis(server->seat->cursor, &event); -} - void add_output_callback(struct wlr_backend *backend, void *data) { long *dims = data; @@ -485,73 +515,6 @@ create_output(char *line, struct cg_server *server) { wlr_multi_for_each_backend(server->backend, add_output_callback, dims); } -void -add_input_device_callback(struct wlr_backend *backend, void *data) { - enum wlr_input_device_type *type = data; - wlr_headless_add_input_device(backend, *type); -} - -void -create_input_device(char *line, struct cg_server *server) { - enum wlr_input_device_type type; - if(*line != '\0') { - if(strncmp(line, "kbd", 3) == 0) { - type = WLR_INPUT_DEVICE_KEYBOARD; - wlr_multi_for_each_backend(server->backend, - add_input_device_callback, &type); - } else if(strncmp(line, "ptr", 3) == 0) { - type = WLR_INPUT_DEVICE_POINTER; - wlr_multi_for_each_backend(server->backend, - add_input_device_callback, &type); - } else if(strncmp(line, "tch", 3) == 0) { - type = WLR_INPUT_DEVICE_TOUCH; - wlr_multi_for_each_backend(server->backend, - add_input_device_callback, &type); - } - } -} - -void -destroy_input_device(char *line, struct cg_server *server) { - long devn = 0; - if(line[0] != '\0') { - devn = strtol(line + 1, NULL, 10); - } - if(line != NULL) { - if(strncmp(line, "k", 1) == 0) { - if(wl_list_empty(&server->seat->keyboard_groups)) { - return; - } - devn = devn % wl_list_length(&server->seat->keyboard_groups); - struct cg_keyboard_group *group, *group_tmp; - wl_list_for_each_safe(group, group_tmp, - &server->seat->keyboard_groups, link) { - if(devn == 0) { - wl_list_remove(&group->link); - wlr_keyboard_group_destroy(group->wlr_group); - wl_event_source_remove(group->key_repeat_timer); - free(group); - break; - } - --devn; - } - } else if(strncmp(line, "p", 1) == 0) { - if(wl_list_empty(&server->input->devices)) { - return; - } - devn = devn % wl_list_length(&server->input->devices); - struct cg_input_device *dev, *dev_tmp; - wl_list_for_each_safe(dev, dev_tmp, &server->input->devices, link) { - if(devn == 0) { - dev->device_destroy.notify(&dev->device_destroy, NULL); - break; - } - --devn; - } - } - } -} - void destroy_output(char *line, struct cg_server *server) { if(wl_list_length(&server->outputs) < 2) { @@ -571,5 +534,4 @@ destroy_output(char *line, struct cg_server *server) { --outpn; } } - it->damage_destroy.notify(&it->damage_destroy, NULL); } diff --git a/fuzz/fuzz-lib.h b/fuzz/fuzz-lib.h index 7182a50..950f455 100644 --- a/fuzz/fuzz-lib.h +++ b/fuzz/fuzz-lib.h @@ -1,10 +1,5 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #ifndef CG_FUZZ_LIB_H #define CG_FUZZ_LIB_H diff --git a/fuzz/fuzz-parse.c b/fuzz/fuzz-parse.c index 8aded78..0fc060c 100644 --- a/fuzz/fuzz-parse.c +++ b/fuzz/fuzz-parse.c @@ -1,10 +1,5 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -38,7 +33,7 @@ set_configuration(struct cg_server *server, char *content) { (line = strtok_r(NULL, "\n", &content)) != NULL; ++line_num) { line[strcspn(line, "\n")] = '\0'; if(*line != '\0' && *line != '#') { - char *errstr; + char *errstr = NULL; server->running = true; if(parse_rc_line(server, line, &errstr) != 0) { if(errstr != NULL) { @@ -56,10 +51,9 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if(size == 0) { return 0; } - int max_line_size = 256 > size ? size : 256; - char *str = malloc(sizeof(char) * max_line_size); - strncpy(str, (char *)data, max_line_size); - str[max_line_size - 1] = 0; + char *str = malloc(sizeof(char) * size); + strncpy(str, (char *)data, size); + str[size - 1] = 0; set_configuration(&server, str); free(str); keybinding_list_free(server.keybindings); diff --git a/fuzz/meson.build b/fuzz/meson.build index b5ba1be..01fdd3e 100644 --- a/fuzz/meson.build +++ b/fuzz/meson.build @@ -1,3 +1,6 @@ +# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# SPDX -License-Identifier: MIT + fuzz_sources = [ 'fuzz-parse.c', 'fuzz-lib.c', @@ -19,7 +22,7 @@ endif override_lib = shared_library('execl_override', [ 'execl_override.c' ], - dependencies: [ pixman,cairo,pango,pangocairo ], + dependencies: [ cairo,pango,pangocairo ], install: false ) diff --git a/idle_inhibit_v1.c b/idle_inhibit_v1.c index 8ebc768..9bc3f7a 100644 --- a/idle_inhibit_v1.c +++ b/idle_inhibit_v1.c @@ -1,11 +1,5 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2019 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #include #include diff --git a/idle_inhibit_v1.h b/idle_inhibit_v1.h index cd1a58d..f0dce64 100644 --- a/idle_inhibit_v1.h +++ b/idle_inhibit_v1.h @@ -1,3 +1,5 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #ifndef CG_IDLE_INHIBIT_H #define CG_IDLE_INHIBIT_H diff --git a/input.h b/input.h index 0b6eb7e..f7877c5 100644 --- a/input.h +++ b/input.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef _CG_INPUT_H #define _CG_INPUT_H @@ -13,9 +16,6 @@ cg_input_configure_libinput_device(struct cg_input_device *device); void cg_input_apply_config(struct cg_input_config *config, struct cg_server *server); -bool -cg_input_reset_libinput_device(struct cg_input_device *device); - bool cg_libinput_device_is_builtin(struct cg_input_device *device); diff --git a/input_manager.c b/input_manager.c index 2157b43..29e4d1d 100644 --- a/input_manager.c +++ b/input_manager.c @@ -1,11 +1,5 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -16,7 +10,9 @@ #include "server.h" #include +#include #include +#include #include #include #include @@ -25,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +61,7 @@ input_device_get_identifier(struct wlr_input_device *device) { char *identifier = malloc(len); if(!identifier) { wlr_log(WLR_ERROR, "Unable to allocate unique input device name"); + free(name); return NULL; } @@ -90,13 +88,217 @@ input_manager_handle_device_destroy(struct wl_listener *listener, void *data) { free(input_device); } -static void -handle_new_input(struct wl_listener *listener, void *data) { - struct cg_input_manager *input = - wl_container_of(listener, input, new_input); - struct cg_server *server = input->server; - struct wlr_input_device *device = data; +struct cg_input_config * +input_manager_create_empty_input_config() { + struct cg_input_config *cfg = calloc(1, sizeof(struct cg_input_config)); + if(cfg == NULL) { + return NULL; + } + /* Libinput devices */ + cfg->tap = INT_MIN; + cfg->tap_button_map = INT_MIN; + cfg->drag = INT_MIN; + cfg->drag_lock = INT_MIN; + cfg->dwt = INT_MIN; + cfg->send_events = INT_MIN; + cfg->click_method = INT_MIN; + cfg->middle_emulation = INT_MIN; + cfg->natural_scroll = INT_MIN; + cfg->accel_profile = INT_MIN; + cfg->pointer_accel = FLT_MIN; + cfg->scroll_factor = FLT_MIN; + cfg->scroll_button = INT_MIN; + cfg->scroll_method = INT_MIN; + cfg->left_handed = INT_MIN; + /*cfg->repeat_delay = INT_MIN; + cfg->repeat_rate = INT_MIN; + cfg->xkb_numlock = INT_MIN; + cfg->xkb_capslock = INT_MIN; + cfg->xkb_file_is_set = false; + wl_list_init(&cfg->tools);*/ + /* Keyboards */ + cfg->enable_keybindings = -1; + cfg->repeat_delay = -1; + cfg->repeat_rate = -1; + return cfg; +} + +/* cfg1 has precedence */ +struct cg_input_config * +input_manager_merge_input_configs(struct cg_input_config *cfg1, + struct cg_input_config *cfg2) { + struct cg_input_config *out_cfg = calloc(1, sizeof(struct cg_input_config)); + if(cfg1->identifier == NULL) { + if(cfg2->identifier != NULL) { + out_cfg->identifier = strdup(cfg2->identifier); + } + } else { + out_cfg->identifier = strdup(cfg1->identifier); + } + if(out_cfg == NULL) { + return NULL; + } + if(cfg1->tap == INT_MIN) { + out_cfg->tap = cfg2->tap; + } else { + out_cfg->tap = cfg1->tap; + } + if(cfg1->send_events == INT_MIN) { + out_cfg->send_events = cfg2->send_events; + } else { + out_cfg->send_events = cfg1->send_events; + } + if(cfg1->dwt == INT_MIN) { + out_cfg->dwt = cfg2->dwt; + } else { + out_cfg->dwt = cfg1->dwt; + } + if(cfg1->drag_lock == INT_MIN) { + out_cfg->drag_lock = cfg2->drag_lock; + } else { + out_cfg->drag_lock = cfg1->drag_lock; + } + if(cfg1->drag == INT_MIN) { + out_cfg->drag = cfg2->drag; + } else { + out_cfg->drag = cfg1->drag; + } + if(cfg1->tap_button_map == INT_MIN) { + out_cfg->tap_button_map = cfg2->tap_button_map; + } else { + out_cfg->tap_button_map = cfg1->tap_button_map; + } + if(cfg1->left_handed == INT_MIN) { + out_cfg->left_handed = cfg2->left_handed; + } else { + out_cfg->left_handed = cfg1->left_handed; + } + if(cfg1->scroll_method == INT_MIN) { + out_cfg->scroll_method = cfg2->scroll_method; + } else { + out_cfg->scroll_method = cfg1->scroll_method; + } + if(cfg1->scroll_button == INT_MIN) { + out_cfg->scroll_button = cfg2->scroll_button; + } else { + out_cfg->scroll_button = cfg1->scroll_button; + } + if(cfg1->scroll_factor == FLT_MIN) { + out_cfg->scroll_factor = cfg2->scroll_factor; + } else { + out_cfg->scroll_factor = cfg1->scroll_factor; + } + if(cfg1->pointer_accel == FLT_MIN) { + out_cfg->pointer_accel = cfg2->pointer_accel; + } else { + out_cfg->pointer_accel = cfg1->pointer_accel; + } + if(cfg1->accel_profile == INT_MIN) { + out_cfg->accel_profile = cfg2->accel_profile; + } else { + out_cfg->accel_profile = cfg1->accel_profile; + } + if(cfg1->natural_scroll == INT_MIN) { + out_cfg->natural_scroll = cfg2->natural_scroll; + } else { + out_cfg->natural_scroll = cfg1->natural_scroll; + } + if(cfg1->middle_emulation == INT_MIN) { + out_cfg->middle_emulation = cfg2->middle_emulation; + } else { + out_cfg->middle_emulation = cfg1->middle_emulation; + } + if(cfg1->click_method == INT_MIN) { + out_cfg->click_method = cfg2->click_method; + } else { + out_cfg->click_method = cfg1->click_method; + } + if(cfg1->enable_keybindings == -1) { + out_cfg->enable_keybindings = cfg2->enable_keybindings; + } else { + out_cfg->enable_keybindings = cfg1->enable_keybindings; + } + if(cfg1->repeat_delay == -1) { + out_cfg->repeat_delay = cfg2->repeat_delay; + } else { + out_cfg->repeat_delay = cfg1->repeat_delay; + } + if(cfg1->repeat_rate == -1) { + out_cfg->repeat_rate = cfg2->repeat_rate; + } else { + out_cfg->repeat_rate = cfg1->repeat_rate; + } + return out_cfg; +} + +void +apply_keyboard_group_config(struct cg_input_config *config, + struct cg_keyboard_group *group) { + if(config->enable_keybindings != -1) { + group->enable_keybindings = config->enable_keybindings; + } + int repeat_delay = 600, repeat_rate = 25; + if(config->repeat_delay != -1) { + repeat_delay = config->repeat_delay; + } + if(config->repeat_rate != -1) { + repeat_rate = config->repeat_rate; + } + wlr_keyboard_set_repeat_info(&group->wlr_group->keyboard, repeat_rate, + repeat_delay); +} + +void +cg_input_manager_configure_keyboard_group(struct cg_keyboard_group *group) { + struct cg_server *server = group->seat->server; + struct cg_input_config *tot_cfg = input_manager_create_empty_input_config(); + if(tot_cfg == NULL) { + return; + } + + struct cg_input_config *tmp_cfg, *config = NULL; + wl_list_for_each(config, &server->input_config, link) { + if(strcmp(config->identifier, group->identifier) == 0 || + strcmp(config->identifier, "*") == 0 || + (strncmp(config->identifier, "type:", 5) == 0 && + strcmp(config->identifier + 5, "keyboard") == 0)) { + tmp_cfg = tot_cfg; + if(tot_cfg->identifier == NULL || + strcmp(tot_cfg->identifier, "*") == 0 || + strcmp(config->identifier, group->identifier)) { + tot_cfg = input_manager_merge_input_configs(config, tot_cfg); + } else { + tot_cfg = input_manager_merge_input_configs(tot_cfg, config); + } + if(tmp_cfg->identifier != NULL) { + free(tmp_cfg->identifier); + } + free(tmp_cfg); + } + } + apply_keyboard_group_config(tot_cfg, group); + if(tot_cfg->identifier != NULL) { + free(tot_cfg->identifier); + } + free(tot_cfg); +} + +void +cg_input_manager_configure(struct cg_server *server) { + struct cg_input_device *device = NULL; + wl_list_for_each(device, &server->input->devices, link) { + cg_input_configure_libinput_device(device); + } + struct cg_keyboard_group *group = NULL; + wl_list_for_each(group, &server->seat->keyboard_groups, link) { + cg_input_manager_configure_keyboard_group(group); + } +} + +static void +new_input(struct cg_input_manager *input, struct wlr_input_device *device, + bool virtual) { struct cg_input_device *input_device = calloc(1, sizeof(struct cg_input_device)); if(!input_device) { @@ -105,9 +307,10 @@ handle_new_input(struct wl_listener *listener, void *data) { } device->data = input_device; + input_device->is_virtual = virtual; input_device->wlr_device = device; input_device->identifier = input_device_get_identifier(device); - input_device->server = server; + input_device->server = input->server; input_device->pointer = NULL; input_device->touch = NULL; @@ -118,39 +321,28 @@ handle_new_input(struct wl_listener *listener, void *data) { wl_signal_add(&device->events.destroy, &input_device->device_destroy); input_device->device_destroy.notify = input_manager_handle_device_destroy; - struct cg_seat *seat = server->seat; + struct cg_seat *seat = input->server->seat; seat_add_device(seat, input_device); } +static void +handle_new_input(struct wl_listener *listener, void *data) { + struct cg_input_manager *input = + wl_container_of(listener, input, new_input); + struct wlr_input_device *device = data; + + new_input(input, device, false); +} + void handle_virtual_keyboard(struct wl_listener *listener, void *data) { - struct cg_input_manager *input_manager = - wl_container_of(listener, input_manager, virtual_keyboard_new); + + struct cg_input_manager *input = + wl_container_of(listener, input, virtual_keyboard_new); struct wlr_virtual_keyboard_v1 *keyboard = data; - struct wlr_input_device *device = &keyboard->input_device; + struct wlr_input_device *device = &keyboard->keyboard.base; - struct cg_seat *seat = input_manager->server->seat; - - struct cg_input_device *input_device = - calloc(1, sizeof(struct cg_input_device)); - if(!input_device) { - wlr_log(WLR_ERROR, "could not allocate input device"); - return; - } - device->data = input_device; - - input_device->is_virtual = true; - input_device->wlr_device = device; - input_device->identifier = input_device_get_identifier(device); - wl_list_insert(&input_manager->devices, &input_device->link); - input_device->server = input_manager->server; - input_device->pointer = NULL; - input_device->touch = NULL; - - wl_signal_add(&device->events.destroy, &input_device->device_destroy); - input_device->device_destroy.notify = input_manager_handle_device_destroy; - - seat_add_device(seat, input_device); + new_input(input, device, true); } void @@ -159,34 +351,13 @@ handle_virtual_pointer(struct wl_listener *listener, void *data) { wl_container_of(listener, input_manager, virtual_pointer_new); struct wlr_virtual_pointer_v1_new_pointer_event *event = data; struct wlr_virtual_pointer_v1 *pointer = event->new_pointer; - struct wlr_input_device *device = &pointer->input_device; + struct wlr_input_device *device = &pointer->pointer.base; - struct cg_seat *seat = input_manager->server->seat; - - struct cg_input_device *input_device = - calloc(1, sizeof(struct cg_input_device)); - if(!input_device) { - wlr_log(WLR_ERROR, "could not allocate input device"); - return; - } - device->data = input_device; - - input_device->is_virtual = true; - input_device->wlr_device = device; - input_device->identifier = input_device_get_identifier(device); - wl_list_insert(&input_manager->devices, &input_device->link); - input_device->server = input_manager->server; - input_device->pointer = NULL; - input_device->touch = NULL; - - wl_signal_add(&device->events.destroy, &input_device->device_destroy); - input_device->device_destroy.notify = input_manager_handle_device_destroy; - - seat_add_device(seat, input_device); + new_input(input_manager, device, true); if(event->suggested_output) { - wlr_cursor_map_input_to_output(seat->cursor, device, - event->suggested_output); + wlr_cursor_map_input_to_output(input_manager->server->seat->cursor, + device, event->suggested_output); } } diff --git a/input_manager.h b/input_manager.h index 35318f6..1def1df 100644 --- a/input_manager.h +++ b/input_manager.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_INPUT_MANAGER_H #define CG_INPUT_MANAGER_H @@ -8,12 +11,19 @@ struct cg_input_manager * input_manager_create(struct cg_server *server); -struct cg_input_config * -input_device_get_config(struct cg_input_device *device); void input_manager_handle_device_destroy(struct wl_listener *listener, void *data); uint32_t input_manager_get_mouse_button(const char *name, char **error); +struct cg_input_config * +input_manager_create_empty_input_config(); +struct cg_input_config * +input_manager_merge_input_configs(struct cg_input_config *cfg1, + struct cg_input_config *cfg2); +void +cg_input_manager_configure(struct cg_server *server); +void +cg_input_manager_configure_keyboard_group(struct cg_keyboard_group *group); struct cg_input_manager { struct wl_list devices; @@ -50,6 +60,7 @@ enum cg_input_config_mapped_to { struct cg_input_config { char *identifier; + /* Libinput devices */ int accel_profile; struct calibration_matrix calibration_matrix; int click_method; @@ -92,13 +103,18 @@ struct cg_input_config { bool capturable; struct wlr_box region; + + /* Keyboards */ + int enable_keybindings; + int repeat_delay; + int repeat_rate; }; struct cg_input_device { char *identifier; struct cg_server *server; struct wlr_input_device *wlr_device; - struct wl_list link; + struct wl_list link; // input_manager::devices struct wl_listener device_destroy; bool is_virtual; diff --git a/ipc_server.c b/ipc_server.c index 7301867..c5295e7 100644 --- a/ipc_server.c +++ b/ipc_server.c @@ -1,27 +1,28 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200112L +#define _DEFAULT_SOURCE #include "ipc_server.h" #include "message.h" #include "parse.h" #include "server.h" +#include "util.h" #include #include #include #include +#include #include #include #include +static const char ipc_magic[] = {'c', 'g', '-', 'i', 'p', 'c'}; + +#define IPC_HEADER_SIZE sizeof(ipc_magic) + static void handle_display_destroy(struct wl_listener *listener, void *data) { struct cg_ipc_handle *ipc = wl_container_of(listener, ipc, display_destroy); @@ -43,6 +44,9 @@ handle_display_destroy(struct wl_listener *listener, void *data) { int ipc_init(struct cg_server *server) { + if(server->enable_socket == false) { + return 0; + } struct cg_ipc_handle *ipc = &server->ipc; ipc->socket = socket(AF_UNIX, SOCK_STREAM, 0); if(ipc->socket == -1) { @@ -96,6 +100,7 @@ ipc_init(struct cg_server *server) { return -1; } + chmod(ipc->sockaddr->sun_path, 0700); setenv("CAGEBREAK_SOCKET", ipc->sockaddr->sun_path, 1); wl_list_init(&ipc->client_list); @@ -109,6 +114,50 @@ ipc_init(struct cg_server *server) { return 0; } +int +ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { + struct cg_ipc_client *client = data; + + if(mask & WL_EVENT_ERROR) { + ipc_client_disconnect(client); + return 0; + } + + if(mask & WL_EVENT_HANGUP) { + ipc_client_disconnect(client); + return 0; + } + + if(client->write_buffer_len <= 0) { + return 0; + } + + if(fcntl(client->fd, F_GETFD) == -1) { + return 0; + } + ssize_t written = + write(client->fd, client->write_buffer, client->write_buffer_len); + + if(written == -1 && errno == EAGAIN) { + return 0; + } else if(written == -1) { + wlr_log(WLR_ERROR, "Unable to send data from queue to IPC client"); + ipc_client_disconnect(client); + return 0; + } + + memmove(client->write_buffer, client->write_buffer + written, + client->write_buffer_len - written); + client->write_buffer_len -= written; + + if(client->write_buffer_len == 0 && client->writable_event_source) { + wl_event_source_remove(client->writable_event_source); + client->writable_event_source = NULL; + } + + return 0; +} + int ipc_handle_connection(int fd, uint32_t mask, void *data) { (void)fd; @@ -145,8 +194,8 @@ ipc_handle_connection(int fd, uint32_t mask, void *data) { close(client_fd); return 0; } - // +1 for \n and +1 for \0 - client->read_buffer = malloc(sizeof(char) * (MAX_LINE_SIZE + 2)); + client->read_buf_cap = 64; + client->read_buffer = calloc(client->read_buf_cap, sizeof(char)); client->read_buf_len = 0; client->read_discard = 0; client->server = server; @@ -154,7 +203,9 @@ ipc_handle_connection(int fd, uint32_t mask, void *data) { client->event_source = wl_event_loop_add_fd(server->event_loop, client_fd, WL_EVENT_READABLE, ipc_client_handle_readable, client); - client->writable_event_source = NULL; + client->writable_event_source = + wl_event_loop_add_fd(server->event_loop, client_fd, WL_EVENT_WRITABLE, + ipc_client_handle_writable, client); client->write_buffer_size = 128; client->write_buffer_len = 0; @@ -191,12 +242,22 @@ ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) { return 0; } - int read_size = read_available < MAX_LINE_SIZE + 1 - client->read_buf_len - ? read_available - : MAX_LINE_SIZE + 1 - client->read_buf_len; + while(read_available + client->read_buf_len > + (int32_t)client->read_buf_cap - 1) { + client->read_buf_cap *= 2; + client->read_buffer = reallocarray(client->read_buffer, + client->read_buf_cap, sizeof(char)); + if(client->read_buffer == NULL) { + wlr_log(WLR_ERROR, "Unable to allocate buffer large enough to hold " + "client read data"); + ipc_client_disconnect(client); + return 0; + } + } // Append to buffer - ssize_t received = recv( - client_fd, client->read_buffer + client->read_buf_len, read_size, 0); + ssize_t received = + recv(client_fd, client->read_buffer + client->read_buf_len, + read_available, 0); if(received == -1) { wlr_log(WLR_ERROR, "Unable to receive data from IPC client"); ipc_client_disconnect(client); @@ -224,8 +285,12 @@ ipc_client_disconnect(struct cg_ipc_client *client) { wl_event_source_remove(client->writable_event_source); } wl_list_remove(&client->link); - free(client->write_buffer); - free(client->read_buffer); + if(client->write_buffer != NULL) { + free(client->write_buffer); + } + if(client->read_buffer != NULL) { + free(client->read_buffer); + } close(client->fd); free(client); } @@ -262,16 +327,78 @@ ipc_client_handle_command(struct cg_ipc_client *client) { } offset = (nl_pos - client->read_buffer) + 1; } - if(offset == 0) { - wlr_log(WLR_ERROR, "Line received was longer that %d, discarding it", - MAX_LINE_SIZE); - client->read_buf_len = 0; - client->read_discard = 1; - return; - } if(offset < client->read_buf_len) { memmove(client->read_buffer, client->read_buffer + offset, client->read_buf_len - offset); } client->read_buf_len -= offset; } + +void +ipc_send_event_client(struct cg_ipc_client *client, const char *payload, + uint32_t payload_length) { + char data[IPC_HEADER_SIZE]; + + memcpy(data, ipc_magic, sizeof(ipc_magic)); + + // +1 for terminating null character + while(client->write_buffer_len + IPC_HEADER_SIZE + payload_length + 1 >= + client->write_buffer_size) { + client->write_buffer_size *= 2; + } + + if(client->write_buffer_size > 4e6) { // 4 MB + wlr_log(WLR_ERROR, + "Client write buffer too big (%zu), disconnecting client", + client->write_buffer_size); + ipc_client_disconnect(client); + return; + } + + char *new_buffer = realloc(client->write_buffer, client->write_buffer_size); + if(!new_buffer) { + wlr_log(WLR_ERROR, "Unable to reallocate ipc client write buffer"); + ipc_client_disconnect(client); + return; + } + client->write_buffer = new_buffer; + + memcpy(client->write_buffer + client->write_buffer_len, data, + IPC_HEADER_SIZE); + client->write_buffer_len += IPC_HEADER_SIZE; + memcpy(client->write_buffer + client->write_buffer_len, payload, + payload_length); + client->write_buffer_len += payload_length; + memcpy(client->write_buffer + client->write_buffer_len, "\0", 1); + client->write_buffer_len += 1; +} + +void +ipc_send_event(struct cg_server *server, const char *fmt, ...) { + if(server->enable_socket == false) { + return; + } + if(wl_list_empty(&server->ipc.client_list)) { + return; + } + va_list args; + va_start(args, fmt); + char *msg = malloc_vsprintf_va_list(fmt, args); + if(msg == NULL) { + wlr_log(WLR_ERROR, "Unable to allocate memory for ipc event"); + va_end(args); + return; + } + va_end(args); + struct cg_ipc_client *it, *tmp; + uint32_t len = strlen(msg); + wl_list_for_each_safe(it, tmp, &server->ipc.client_list, link) { + if(it->writable_event_source == NULL) { + it->writable_event_source = wl_event_loop_add_fd( + server->event_loop, it->fd, WL_EVENT_WRITABLE, + ipc_client_handle_writable, it); + } + ipc_send_event_client(it, msg, len); + } + free(msg); +} diff --git a/ipc_server.h b/ipc_server.h index 60339df..2c66b83 100644 --- a/ipc_server.h +++ b/ipc_server.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_IPC_SERVER_H #define CG_IPC_SERVER_H @@ -21,6 +24,7 @@ struct cg_ipc_client { char *write_buffer; // The following is for storing data between event_loop calls uint16_t read_buf_len; + size_t read_buf_cap; uint8_t read_discard; // 1 if the current line is to be discarded char *read_buffer; }; @@ -33,6 +37,8 @@ struct cg_ipc_handle { struct sockaddr_un *sockaddr; }; +void +ipc_send_event(struct cg_server *server, const char *fmt, ...); int ipc_init(struct cg_server *server); int diff --git a/keybinding.c b/keybinding.c index ec83acc..0c96d4b 100644 --- a/keybinding.c +++ b/keybinding.c @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #define _POSIX_C_SOURCE 200809L #include @@ -6,8 +9,12 @@ #include #include #include +#include +#include #include #include +#include +#include #include #include "input.h" @@ -17,9 +24,12 @@ #include "output.h" #include "seat.h" #include "server.h" +#include "util.h" #include "view.h" #include "workspace.h" +char *keybinding_action_string[] = {FOREACH_KEYBINDING(GENERATE_STRING)}; + int keybinding_resize(struct keybinding_list *list) { if(list->length == list->capacity) { @@ -82,6 +92,10 @@ keybinding_free(struct keybinding *keybinding, bool recursive) { free(keybinding->data.m_cfg->font); } break; + case KEYBINDING_DISPLAY_MESSAGE: + if(keybinding->data.c != NULL) { + free(keybinding->data.c); + } default: break; } @@ -132,56 +146,79 @@ keybinding_list_free(struct keybinding_list *list) { free(list); } +// Returns whether x is between a and b (a exclusive, b exclusive) where +// anext; - while(it != tile && it->tile.x != tile->tile.x + tile->tile.width) { + int center = tile->tile.y + tile->tile.height / 2; + while(it != tile) { + if(it->tile.x == tile->tile.x + tile->tile.width) { + if(is_between_strict(it->tile.y, it->tile.y + it->tile.height, + center) || + it->tile.y + it->tile.height == center) { + return it; + } + } it = it->next; } - if(it == tile) { - return NULL; - } else { - return it; - } + return NULL; } struct cg_tile * find_left_tile(const struct cg_tile *tile) { - struct cg_tile *it = tile->prev; - while(it != tile && it->tile.x + it->tile.width != tile->tile.x) { - it = it->prev; - } - if(it == tile) { - return NULL; - } else { - return it; + struct cg_tile *it = tile->next; + int center = tile->tile.y + tile->tile.height / 2; + while(it != tile) { + if(it->tile.x + it->tile.width == tile->tile.x) { + if(is_between_strict(it->tile.y, it->tile.y + it->tile.height, + center) || + it->tile.y + it->tile.height == center) { + return it; + } + } + it = it->next; } + return NULL; } struct cg_tile * find_top_tile(const struct cg_tile *tile) { - struct cg_tile *it = tile->prev; - while(it != tile && it->tile.y + it->tile.height != tile->tile.y) { - it = it->prev; - } - if(it == tile) { - return NULL; - } else { - return it; + struct cg_tile *it = tile->next; + int center = tile->tile.x + tile->tile.width / 2; + while(it != tile) { + if(it->tile.y + it->tile.height == tile->tile.y) { + if(is_between_strict(it->tile.x, it->tile.x + it->tile.width, + center) || + it->tile.x + it->tile.width == center) { + return it; + } + } + it = it->next; } + return NULL; } struct cg_tile * find_bottom_tile(const struct cg_tile *tile) { struct cg_tile *it = tile->next; - while(it != tile && it->tile.y != tile->tile.y + tile->tile.height) { + int center = tile->tile.x + tile->tile.width / 2; + while(it != tile) { + if(it->tile.y == tile->tile.y + tile->tile.height) { + if(is_between_strict(it->tile.x, it->tile.x + it->tile.width, + center) || + it->tile.x + it->tile.width == center) { + return it; + } + } it = it->next; } - if(it == tile) { - return NULL; - } else { - return it; - } + return NULL; } void @@ -193,26 +230,21 @@ swap_tile(struct cg_tile *tile, return; } struct cg_view *tmp_view = tile->view; - tile->view = swap_tile->view; - swap_tile->view = tmp_view; - if(tile->view != NULL) { - view_maximize(tile->view, tile); - view_damage_whole(tile->view); - } else { - wlr_output_damage_add_box(tile->workspace->output->damage, &tile->tile); - } + struct cg_view *tmp_swap_view = swap_tile->view; + workspace_tile_update_view(tile, NULL); + workspace_tile_update_view(swap_tile, tmp_view); + workspace_tile_update_view(tile, tmp_swap_view); workspace_focus_tile( server->curr_output->workspaces[server->curr_output->curr_workspace], swap_tile); - if(swap_tile->view != NULL) { - view_maximize(swap_tile->view, swap_tile); - view_damage_whole(swap_tile->view); - } else { - wlr_output_damage_add_box(tile->workspace->output->damage, - &swap_tile->tile); - } - seat_set_focus(server->seat, swap_tile->view); + ipc_send_event( + tile->workspace->output->server, + "{\"event_name\":\"swap_tile\",\"tile_id\":%d,\"swap_" + "tile_id\":%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", + tile->id, swap_tile->id, tile->workspace->num + 1, + tile->workspace->output->wlr_output->name, + output_get_num(tile->workspace->output)); } void @@ -267,13 +299,6 @@ focus_tile_bottom(struct cg_tile *tile) { focus_tile(tile, find_bottom_tile); } -// Returns whether x is between a and b (a exclusive, b exclusive) where -// atile.x + tile->tile.y - *get_coord(tile); @@ -355,18 +380,23 @@ resize(struct cg_tile *tile, const struct cg_tile *parent, int coord_offset, } } - int old_x = tile->tile.x, old_y = tile->tile.y; + int old_x = tile->tile.x, old_y = tile->tile.y, + old_height = tile->tile.height, old_width = tile->tile.width; *get_coord(tile) += coord_offset; *get_dim(tile) += dim_offset; - struct wlr_box damage_box = { - .x = old_x, - .y = old_y, - .width = tile->tile.x - old_x == 0 ? tile->tile.width : coord_offset, - .height = tile->tile.y == 0 ? tile->tile.height : coord_offset}; - wlr_output_damage_add_box(tile->workspace->output->damage, &damage_box); + if(tile->view != NULL) { view_maximize(tile->view, tile); } + ipc_send_event(tile->workspace->output->server, + "{\"event_name\":\"resize_tile\",\"tile_id\":%d,\"old_" + "dims\":\"[%d,%d,%d,%d]\",\"new_dims\":\"[%d,%d,%d,%d]\"," + "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", + tile->id, old_x, old_y, old_height, old_width, tile->tile.x, + tile->tile.y, tile->tile.height, tile->tile.width, + tile->workspace->num + 1, + tile->workspace->output->wlr_output->name, + output_get_num(tile->workspace->output)); } int * @@ -420,17 +450,18 @@ resize_vertical(struct cg_tile *tile, struct cg_tile *parent, int y_offset, void resize_tile(struct cg_server *server, int hpixs, int vpixs) { struct cg_output *output = server->curr_output; - struct wlr_box *output_box = wlr_output_layout_get_box( - output->server->output_layout, output->wlr_output); + struct wlr_box output_box; + wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, + &output_box); struct cg_tile *focused = output->workspaces[output->curr_workspace]->focused_tile; /* First do the horizontal adjustment */ - if(hpixs != 0 && focused->tile.width < output_box->width && - is_between_strict(0, output_box->width, focused->tile.width + hpixs)) { + if(hpixs != 0 && focused->tile.width < output_box.width && + is_between_strict(0, output_box.width, focused->tile.width + hpixs)) { int x_offset = 0; /* In case we are on the total right, move the left edge of the tile */ - if(focused->tile.x + focused->tile.width == output_box->width) { + if(focused->tile.x + focused->tile.width == output_box.width) { x_offset = -hpixs; } bool resize_allowed = @@ -440,10 +471,10 @@ resize_tile(struct cg_server *server, int hpixs, int vpixs) { } } /* Repeat for vertical */ - if(vpixs != 0 && focused->tile.height < output_box->height && - is_between_strict(0, output_box->height, focused->tile.height + vpixs)) { + if(vpixs != 0 && focused->tile.height < output_box.height && + is_between_strict(0, output_box.height, focused->tile.height + vpixs)) { int y_offset = 0; - if(focused->tile.y + focused->tile.height == output_box->height) { + if(focused->tile.y + focused->tile.height == output_box.height) { y_offset = -vpixs; } bool resize_allowed = @@ -456,37 +487,15 @@ resize_tile(struct cg_server *server, int hpixs, int vpixs) { void keybinding_workspace_fullscreen(struct cg_server *server) { - struct cg_view *current_view = seat_get_focus(server->seat); + output_make_workspace_fullscreen(server->curr_output, + server->curr_output->curr_workspace); struct cg_output *output = server->curr_output; - - /* We are focused on the background */ - if(current_view == NULL) { - struct cg_view *it = NULL; - wl_list_for_each(it, &output->workspaces[output->curr_workspace]->views, - link) { - if(view_is_visible(it)) { - current_view = it; - break; - } - } - } - - workspace_free_tiles(output->workspaces[output->curr_workspace]); - if(full_screen_workspace_tiles( - server->output_layout, output->wlr_output, - output->workspaces[output->curr_workspace]) != 0) { - wlr_log(WLR_ERROR, "Failed to allocate space for fullscreen workspace"); - return; - } - - struct cg_view *it_view; - wl_list_for_each(it_view, - &output->workspaces[output->curr_workspace]->views, link) { - it_view->tile = - output->workspaces[output->curr_workspace]->focused_tile; - } - - seat_set_focus(server->seat, current_view); + ipc_send_event(server, + "{\"event_name\":\"fullscreen\",\"tile_id\":%d," + "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", + output->workspaces[output->curr_workspace]->focused_tile->id, + output->workspaces[output->curr_workspace]->num + 1, + output->wlr_output->name, output_get_num(output)); } // Switch to a differerent virtual terminal @@ -551,13 +560,15 @@ keybinding_split_output(struct cg_output *output, bool vertical) { wlr_log(WLR_ERROR, "Failed to allocate new tile for splitting"); return; } + new_tile->id = output->server->tiles_curr_id; + ++output->server->tiles_curr_id; new_tile->tile.x = new_x; new_tile->tile.y = new_y; new_tile->tile.width = x + width - new_x; new_tile->tile.height = y + height - new_y; new_tile->prev = curr_workspace->focused_tile; new_tile->next = curr_workspace->focused_tile->next; - new_tile->view = next_view; + workspace_tile_update_view(new_tile, next_view); new_tile->workspace = curr_workspace; curr_workspace->focused_tile->next->prev = new_tile; curr_workspace->focused_tile->next = new_tile; @@ -573,6 +584,13 @@ keybinding_split_output(struct cg_output *output, bool vertical) { if(original_view != NULL) { view_maximize(original_view, curr_workspace->focused_tile); } + ipc_send_event( + output->server, + "{\"event_name\":\"split\",\"tile_id\":%d,\"new_tile_id\":%d," + "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d,\"vertical\":%d}", + curr_workspace->focused_tile->id, new_tile->id, curr_workspace->num + 1, + curr_workspace->output->wlr_output->name, + output_get_num(curr_workspace->output), vertical); } static void @@ -580,7 +598,18 @@ keybinding_close_view(struct cg_view *view) { if(view == NULL) { return; } + struct cg_output *outp = view->workspace->output; + uint32_t view_id = view->id; + uint32_t view_pid = view->impl->get_pid(view); + uint32_t tile_id = view->id; + uint32_t ws = view->workspace->num; view->impl->close(view); + ipc_send_event( + outp->server, + "{\"event_name\":\"close\",\"view_id\":%d,\"view_pid\":%d,\"tile_id\":" + "%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", + view_id, view_pid, tile_id, ws + 1, outp->wlr_output->name, + output_get_num(outp)); } static void @@ -610,8 +639,10 @@ set_output(struct cg_server *server, struct cg_output *output) { } void -keybinding_cycle_outputs(struct cg_server *server, bool reverse) { +keybinding_cycle_outputs(struct cg_server *server, bool reverse, + bool trigger_event) { struct cg_output *output = NULL; + struct cg_output *old_output = server->curr_output; if(reverse) { output = wl_container_of(server->curr_output->link.prev, server->curr_output, link); @@ -627,36 +658,38 @@ keybinding_cycle_outputs(struct cg_server *server, bool reverse) { } } set_output(server, output); + if(trigger_event) { + ipc_send_event( + output->server, + "{\"event_name\":\"cycle_outputs\",\"old_output\":\"%s\",\"old_" + "output_id\":%d," + "\"new_output\":\"%s\",\"new_output_id\":%d,\"reverse\":%d}", + old_output->wlr_output->name, output_get_num(old_output), + output->wlr_output->name, output_get_num(output), reverse); + } } /* Cycle through views, whereby the workspace does not change */ void -keybinding_cycle_views(struct cg_server *server, bool reverse) { +keybinding_cycle_views(struct cg_server *server, bool reverse, bool ipc) { struct cg_workspace *curr_workspace = server->curr_output->workspaces[server->curr_output->curr_workspace]; struct cg_view *current_view = curr_workspace->focused_tile->view; - if(current_view == NULL) { - current_view = - wl_container_of(&curr_workspace->views, current_view, link); - } struct cg_view *it_view, *next_view = NULL; if(reverse) { - next_view = view_get_prev_view(current_view); - } else { - struct wl_list *it; - it = current_view->link.next; - while(it != ¤t_view->link) { - if(it == &curr_workspace->views) { - it = it->next; - continue; - } - it_view = wl_container_of(it, it_view, link); + wl_list_for_each(it_view, &curr_workspace->views, link) { + if(!view_is_visible(it_view)) { + next_view = it_view; + break; + } + } + } else { + wl_list_for_each_reverse(it_view, &curr_workspace->views, link) { if(!view_is_visible(it_view)) { next_view = it_view; break; } - it = it->next; } } @@ -664,12 +697,50 @@ keybinding_cycle_views(struct cg_server *server, bool reverse) { return; } - wlr_output_damage_add_box(curr_workspace->output->damage, - &curr_workspace->focused_tile->tile); - /* Prevent seat_set_focus from reordering the views */ - curr_workspace->focused_tile->view = wl_container_of( - next_view->link.prev, curr_workspace->focused_tile->view, link); seat_set_focus(server->seat, next_view); + if(ipc) { + ipc_send_event( + curr_workspace->output->server, + "{\"event_name\":\"cycle_views\",\"old_view_id\":%d,\"old_view_" + "pid\":%d," + "\"new_view_id\":%d,\"new_view_pid\":%d,\"tile_id\":%d," + "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", + current_view->link.next == curr_workspace->views.next + ? -1 + : (int)current_view->id, + current_view->link.next == curr_workspace->views.next + ? -1 + : (int)current_view->impl->get_pid(current_view), + next_view == NULL ? -1 : (int)next_view->id, + next_view == NULL ? -1 : (int)next_view->impl->get_pid(next_view), + next_view->tile->id, curr_workspace->num + 1, + curr_workspace->output->wlr_output->name, + output_get_num(curr_workspace->output)); + } +} + +void +keybinding_focus_tile(struct cg_server *server, uint32_t tile_id) { + struct cg_output *output = server->curr_output; + struct cg_workspace *workspace = output->workspaces[output->curr_workspace]; + struct cg_tile *old_tile = workspace->focused_tile; + bool first = true; + for(struct cg_tile *tile = workspace->focused_tile; + first || tile != workspace->focused_tile; tile = tile->next) { + first = false; + if(tile->id == tile_id) { + workspace_focus_tile(workspace, tile); + struct cg_view *next_view = workspace->focused_tile->view; + seat_set_focus(server->seat, next_view); + ipc_send_event( + output->server, + "{\"event_name\":\"focus_tile\",\"old_tile_id\":%d,\"new_tile_" + "id\":%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", + old_tile->id, workspace->focused_tile->id, workspace->num + 1, + output->wlr_output->name, output_get_num(output)); + break; + } + } } void @@ -677,13 +748,10 @@ keybinding_cycle_tiles(struct cg_server *server, bool reverse) { struct cg_output *output = server->curr_output; struct cg_workspace *workspace = output->workspaces[output->curr_workspace]; if(reverse) { - workspace_focus_tile(workspace, workspace->focused_tile->prev); + keybinding_focus_tile(server, workspace->focused_tile->prev->id); } else { - workspace_focus_tile(workspace, workspace->focused_tile->next); + keybinding_focus_tile(server, workspace->focused_tile->next->id); } - struct cg_view *next_view = workspace->focused_tile->view; - - seat_set_focus(server->seat, next_view); } int @@ -695,11 +763,16 @@ keybinding_switch_ws(struct cg_server *server, uint32_t ws) { return -1; } struct cg_output *output = server->curr_output; - output->curr_workspace = ws; + uint32_t old_ws = server->curr_output->curr_workspace; + workspace_focus(output, ws); seat_set_focus(server->seat, server->curr_output->workspaces[ws]->focused_tile->view); - wlr_output_damage_add_whole(output->damage); message_printf(server->curr_output, "Workspace %d", ws + 1); + ipc_send_event(output->server, + "{\"event_name\":\"switch_ws\",\"old_workspace\":%d," + "\"new_workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", + old_ws + 1, ws + 1, output->wlr_output->name, + output_get_num(output)); return 0; } @@ -717,6 +790,430 @@ keybinding_show_time(struct cg_server *server) { free(msg); } +struct dyn_str { + uint32_t len; + uint32_t cur_pos; + char **str_arr; +}; + +/*Note that inp is in an invalid state after calling the function * and should + * no longer be used.*/ +char * +dyn_str_to_str(struct dyn_str *inp) { + char *outp = calloc(inp->len + 1, sizeof(char)); + if(outp == NULL) { + return NULL; + } + outp[inp->len] = '\0'; + uint32_t tmp_pos = 0; + for(uint32_t i = 0; i < inp->cur_pos; ++i) { + strcat(outp + tmp_pos, inp->str_arr[i]); + tmp_pos += strlen(inp->str_arr[i]); + free(inp->str_arr[i]); + } + free(inp->str_arr); + return outp; +} + +int +print_str(struct dyn_str *outp, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + char *ret = malloc_vsprintf_va_list(fmt, args); + if(ret == NULL) { + return -1; + } + outp->str_arr[outp->cur_pos] = ret; + ++outp->cur_pos; + outp->len += strlen(ret); + return 0; +} + +void +print_modes(struct dyn_str *str, char **modes) { + uint32_t len = 0; + char **tmp = modes; + uint32_t nmemb = 0; + while(*tmp != NULL) { + len += strlen(*tmp); + ++nmemb; + ++tmp; + } + if(nmemb == 0) { + wlr_log(WLR_ERROR, + "This is a bug: Cagebreak has no valid modes. This should not " + "occur, since default modes are defined on startup."); + return; + } + /* We are assuming here that we have at least one mode, which is given by + * the initialization of cagebreak */ + char *modes_str = calloc(len + 3 * (nmemb - 1) + 1, sizeof(char)); + modes_str[len + nmemb - 1] = '\0'; + uint32_t tmp_pos = 0; + for(uint32_t i = 0; i < nmemb; ++i) { + if(i != 0) { + strcat(modes_str + tmp_pos, "\",\""); + tmp_pos += 3; + } + strcat(modes_str + tmp_pos, modes[i]); + tmp_pos += strlen(modes[i]); + } + print_str(str, "\"modes\":[\"%s\"],\n", modes_str); + free(modes_str); +} + +char * +print_view(struct cg_view *view) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nmemb = 4; + outp_str.str_arr = calloc(nmemb, sizeof(char *)); + print_str(&outp_str, "\"id\": %d,\n", view->id); + print_str(&outp_str, "\"pid\": %d,\n", view->impl->get_pid(view)); + print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n", view->ox, + view->oy); +#if CG_HAS_XWAYLAND + print_str(&outp_str, "\"type\": \"%s\"\n", + view->type == CG_XWAYLAND_VIEW ? "xwayland" : "xdg"); +#else + print_str(&outp_str, "\"type\": \"xdg\"\n"); +#endif + return dyn_str_to_str(&outp_str); +} + +char * +print_tile(struct cg_tile *tile) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nmemb = 4; + outp_str.str_arr = calloc(nmemb, sizeof(char *)); + print_str(&outp_str, "\"id\": %d,\n", tile->id); + print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n", tile->tile.x, + tile->tile.y); + print_str(&outp_str, "\"size\": {\"width\":%d,\"height\":%d},\n", + tile->tile.width, tile->tile.height); + print_str(&outp_str, "\"view_id\": %d\n", + tile->view == NULL ? -1 : (int)tile->view->id); + return dyn_str_to_str(&outp_str); +} + +char * +print_views(struct cg_workspace *ws) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nviews = wl_list_length(&ws->views); + if(nviews == 0) { + return strdup("{}"); + } + outp_str.str_arr = calloc(2 * nviews - 1, sizeof(char *)); + struct cg_view *it; + uint32_t count = 0; + wl_list_for_each(it, &ws->views, link) { + if(count != 0) { + print_str(&outp_str, ","); + } + ++count; + char *view_str = print_view(it); + if(view_str != NULL) { + print_str(&outp_str, "{\n%s\n}", view_str); + free(view_str); + } + } + return dyn_str_to_str(&outp_str); +} + +char * +print_tiles(struct cg_workspace *ws) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t ntiles = 0; + bool first = true; + for(struct cg_tile *tile = ws->focused_tile; + first || tile != ws->focused_tile; tile = tile->next) { + first = false; + ++ntiles; + } + if(ntiles == 0) { + return strdup("{}"); + } + outp_str.str_arr = calloc(2 * ntiles - 1, sizeof(char *)); + first = true; + for(struct cg_tile *tile = ws->focused_tile; + first || tile != ws->focused_tile; tile = tile->next) { + if(first == false) { + print_str(&outp_str, ","); + } + first = false; + char *tile_str = print_tile(tile); + if(tile_str != NULL) { + print_str(&outp_str, "{\n%s\n}", tile_str); + free(tile_str); + } + } + return dyn_str_to_str(&outp_str); +} + +char * +print_workspace(struct cg_workspace *ws) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nmemb = 6; + outp_str.str_arr = calloc(nmemb, sizeof(char *)); + print_str(&outp_str, "\"views\": ["); + char *views_str = print_views(ws); + if(views_str != NULL) { + print_str(&outp_str, "%s", views_str); + free(views_str); + } + print_str(&outp_str, "],"); + print_str(&outp_str, "\"tiles\": ["); + char *tiles_str = print_tiles(ws); + if(tiles_str != NULL) { + print_str(&outp_str, "%s", tiles_str); + free(tiles_str); + } + print_str(&outp_str, "]"); + return dyn_str_to_str(&outp_str); +} + +char * +print_workspaces(struct cg_output *outp) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + outp_str.str_arr = calloc((2 * outp->server->nws - 1) + 2, sizeof(char *)); + print_str(&outp_str, "\"workspaces\": ["); + for(int i = 0; i < outp->server->nws; ++i) { + if(i != 0) { + print_str(&outp_str, ","); + } + char *ws = print_workspace(outp->workspaces[i]); + if(ws != NULL) { + print_str(&outp_str, "{%s}", ws); + free(ws); + } + } + print_str(&outp_str, "]\n"); + return dyn_str_to_str(&outp_str); +} + +char * +print_output(struct cg_output *outp) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nmemb = 8; + struct wlr_box outp_box; + wlr_output_layout_get_box(outp->server->output_layout, outp->wlr_output, + &outp_box); + outp_str.str_arr = calloc(nmemb, sizeof(char *)); + print_str(&outp_str, "\"%s\": {\n", outp->wlr_output->name); + print_str(&outp_str, "\"priority\": %d,\n", outp->priority); + print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n", outp_box.x, + outp_box.y); + print_str(&outp_str, "\"size\": {\"width\":%d,\"height\":%d},\n", + outp->wlr_output->width, outp->wlr_output->height); + print_str(&outp_str, "\"refresh_rate\": %f,\n", + (float)outp->wlr_output->refresh / 1000.0); + print_str(&outp_str, "\"curr_workspace\": %d,\n", outp->curr_workspace + 1); + char *workspaces_str = print_workspaces(outp); + if(workspaces_str != NULL) { + print_str(&outp_str, "%s", workspaces_str); + free(workspaces_str); + } + print_str(&outp_str, "}"); + return dyn_str_to_str(&outp_str); +} + +char * +print_outputs(struct cg_server *server) { + uint32_t noutps = wl_list_length(&server->outputs); + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + outp_str.str_arr = calloc((2 * noutps - 1) + 2, sizeof(char *)); + print_str(&outp_str, "\"outputs\": {"); + struct cg_output *it; + uint32_t count = 0; + wl_list_for_each(it, &server->outputs, link) { + if(count != 0) { + print_str(&outp_str, ","); + } + ++count; + char *outp = print_output(it); + if(outp == NULL) { + continue; + } + print_str(&outp_str, "%s", outp); + free(outp); + } + print_str(&outp_str, "}\n"); + return dyn_str_to_str(&outp_str); +} + +char * +print_keyboard_group(struct cg_keyboard_group *grp) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nmemb = 5; + outp_str.str_arr = calloc(nmemb, sizeof(char *)); + if(grp->identifier != NULL) { + print_str(&outp_str, "\"%s\": {\n", grp->identifier); + } else { + print_str(&outp_str, "\"NULL\": {\n"); + } + print_str(&outp_str, "\"commands_enabled\": %d,\n", + grp->enable_keybindings); + print_str(&outp_str, "\"repeat_delay\": %d,\n", + grp->wlr_group->keyboard.repeat_info.delay); + print_str(&outp_str, "\"repeat_rate\": %d\n", + grp->wlr_group->keyboard.repeat_info.rate); + print_str(&outp_str, "}"); + return dyn_str_to_str(&outp_str); +} + +char * +print_keyboard_groups(struct cg_server *server) { + uint32_t ninps = wl_list_length(&server->seat->keyboard_groups); + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + outp_str.str_arr = calloc((2 * ninps - 1) + 3, sizeof(char *)); + print_str(&outp_str, "\"keyboards\": {"); + struct cg_keyboard_group *it; + uint32_t count = 0; + wl_list_for_each(it, &server->seat->keyboard_groups, link) { + if(count != 0) { + print_str(&outp_str, ","); + } + ++count; + char *outp = print_keyboard_group(it); + if(outp == NULL) { + continue; + } + print_str(&outp_str, "%s", outp); + free(outp); + } + print_str(&outp_str, "}\n"); + return dyn_str_to_str(&outp_str); +} + +char * +print_input_device(struct cg_input_device *dev) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nmemb = 4; + outp_str.str_arr = calloc(nmemb, sizeof(char *)); + if(dev->identifier != NULL) { + print_str(&outp_str, "\"%s\": {\n", dev->identifier); + } else { + print_str(&outp_str, "\"NULL\": {\n"); + } + print_str(&outp_str, "\"is_virtual\": %d,\n", dev->is_virtual); + print_str( + &outp_str, "\"type\": \"%s\"\n", + dev->wlr_device->type == WLR_INPUT_DEVICE_POINTER ? "pointer" + : dev->wlr_device->type == WLR_INPUT_DEVICE_SWITCH ? "switch" + : dev->wlr_device->type == WLR_INPUT_DEVICE_TABLET_PAD ? "tablet pad" + : dev->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL ? "tablet tool" + : dev->wlr_device->type == WLR_INPUT_DEVICE_TOUCH ? "touch" + : dev->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD ? "keyboard" + : "unknown"); + print_str(&outp_str, "}"); + return dyn_str_to_str(&outp_str); +} + +char * +print_input_devices(struct cg_server *server) { + uint32_t ninps = wl_list_length(&server->input->devices); + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + outp_str.str_arr = calloc((2 * ninps - 1) + 3, sizeof(char *)); + print_str(&outp_str, "\"input_devices\": {"); + struct cg_input_device *it; + uint32_t count = 0; + wl_list_for_each(it, &server->input->devices, link) { + if(count != 0) { + print_str(&outp_str, ","); + } + ++count; + char *outp = print_input_device(it); + if(outp == NULL) { + continue; + } + print_str(&outp_str, "%s", outp); + free(outp); + } + print_str(&outp_str, "}\n"); + return dyn_str_to_str(&outp_str); +} + +char * +get_mode_name(char **modes, unsigned int mode_nr) { + unsigned int i; + for(i = 0; i < mode_nr && modes[i] != NULL; ++i) { + } + if(modes[i] != NULL) { + return modes[i]; + } else { + return "NULL"; + } +} + +void +keybinding_dump(struct cg_server *server) { + struct dyn_str str; + str.len = 0; + str.cur_pos = 0; + uint32_t nmemb = 13; + str.str_arr = calloc(nmemb, sizeof(char *)); + + print_str(&str, "{\"event_name\":\"dump\","); + print_str(&str, "\"nws\":%d,\n", server->nws); + print_str(&str, "\"bg_color\":[%f,%f,%f],\n", server->bg_color[0], + server->bg_color[1], server->bg_color[2]); + print_str(&str, "\"views_curr_id\":%d,\n", server->views_curr_id); + print_str(&str, "\"tiles_curr_id\":%d,\n", server->tiles_curr_id); + print_str(&str, "\"curr_output\":\"%s\",\n", + server->curr_output->wlr_output->name); + print_str(&str, "\"default_mode\":\"%s\",\n", + get_mode_name(server->modes, server->seat->default_mode)); + print_modes(&str, server->modes); + char *outps_str = print_outputs(server); + if(outps_str != NULL) { + print_str(&str, "%s,", outps_str); + free(outps_str); + } + char *keyboards_str = print_keyboard_groups(server); + if(keyboards_str != NULL) { + print_str(&str, "%s,", keyboards_str); + free(keyboards_str); + } + char *input_dev_str = print_input_devices(server); + if(input_dev_str != NULL) { + print_str(&str, "%s,", input_dev_str); + free(input_dev_str); + } + print_str(&str, "\"cursor_coords\":{\"x\":%f,\"y\":%f}\n", + server->seat->cursor->x, server->seat->cursor->y); + print_str(&str, "}"); + + char *send_str = dyn_str_to_str(&str); + if(send_str == NULL) { + wlr_log(WLR_ERROR, "Unable to create output string for \"dump\"."); + } + ipc_send_event(server, send_str); + free(send_str); +} + void keybinding_show_info(struct cg_server *server) { char *msg = server_show_info(server); @@ -739,6 +1236,7 @@ keybinding_move_view_to_cycle_output(struct cg_server *server, bool reverse) { if(wl_list_length(&server->outputs) <= 1) { return; } + struct cg_output *old_outp = server->curr_output; struct cg_view *view = server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view; @@ -746,34 +1244,49 @@ keybinding_move_view_to_cycle_output(struct cg_server *server, bool reverse) { wl_list_remove(&view->link); server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view = NULL; - keybinding_cycle_views(server, false); - view_damage_whole(view); + keybinding_cycle_views(server, false, false); if(server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view == NULL) { seat_set_focus(server->seat, NULL); } } - keybinding_cycle_outputs(server, false); + keybinding_cycle_outputs(server, reverse, false); if(view != NULL) { - wl_list_insert(&server->curr_output - ->workspaces[server->curr_output->curr_workspace] - ->views, - &view->link); - server->curr_output->workspaces[server->curr_output->curr_workspace] - ->focused_tile->view = view; - view->workspace = server->curr_output - ->workspaces[server->curr_output->curr_workspace]; - view->tile = view->workspace->focused_tile; - view_maximize(view, view->tile); + struct cg_workspace *ws = + server->curr_output + ->workspaces[server->curr_output->curr_workspace]; + wl_list_insert(&ws->views, &view->link); + wlr_scene_node_reparent(&view->scene_tree->node, ws->scene); + workspace_tile_update_view(ws->focused_tile, view); + view->workspace = ws; seat_set_focus(server->seat, view); } + int id = -1; + int pid = -1; + if(view != NULL) { + id = view->id; + pid = view->impl->get_pid(view); + } + ipc_send_event( + server, + "{\"event_name\":\"move_view_to_cycle_output\",\"view_id\":%d,\"view_" + "pid\":%d,\"old_output\":\"%s\",\"old_output_id\":%d,\"new_output\":\"%" + "s\",\"new_output_id\":%d,\"old_tile_id\":%d,\"new_tile_id\":%d}", + id, pid, old_outp->wlr_output->name, output_get_num(old_outp), + server->curr_output->wlr_output->name, + output_get_num(server->curr_output), + old_outp->workspaces[old_outp->curr_workspace]->focused_tile->id, + server->curr_output->workspaces[server->curr_output->curr_workspace] + ->focused_tile->id); } void keybinding_set_nws(struct cg_server *server, int nws) { struct cg_output *output; + unsigned int old_nws = server->nws; + server->nws = nws; wl_list_for_each(output, &server->outputs, link) { - for(unsigned int i = nws; i < server->nws; ++i) { + for(unsigned int i = nws; i < old_nws; ++i) { struct cg_view *view, *tmp; wl_list_for_each_safe(view, tmp, &output->workspaces[i]->views, link) { @@ -798,8 +1311,9 @@ keybinding_set_nws(struct cg_server *server, int nws) { return; } output->workspaces = new_workspaces; - for(int i = server->nws; i < nws; ++i) { + for(int i = old_nws; i < nws; ++i) { output->workspaces[i] = full_screen_workspace(output); + output->workspaces[i]->num = i; if(!output->workspaces[i]) { wlr_log(WLR_ERROR, "Failed to allocate additional workspaces"); return; @@ -810,14 +1324,17 @@ keybinding_set_nws(struct cg_server *server, int nws) { } if(output->curr_workspace >= nws) { - output->curr_workspace = nws - 1; + output->curr_workspace = 0; + workspace_focus(output, nws - 1); } } - server->nws = nws; seat_set_focus( server->seat, server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view); + ipc_send_event(server, + "{\"event_name\":\"set_nws\",\"old_nws\":%d,\"new_nws\":%d}", + old_nws, server->nws); } void @@ -834,27 +1351,53 @@ keybinding_definemode(struct cg_server *server, char *mode) { server->modes[length] = NULL; server->modes[length - 1] = strdup(mode); + ipc_send_event(server, "{\"event_name\":\"definemode\",\"mode\":\"%s\"}", + mode); } void keybinding_definekey(struct cg_server *server, struct keybinding *kb) { keybinding_list_push(server->keybindings, kb); + ipc_send_event(server, + "{\"event_name\":\"definekey\",\"modifiers\":%d,\"key\":" + "%d,\"command\":\"%s\"}", + kb->modifiers, kb->key, + keybinding_action_string[kb->action]); } void keybinding_set_background(struct cg_server *server, float *bg) { + ipc_send_event(server, + "{\"event_name\":\"background\",\"old_bg\":[%f,%f,%f]," + "\"new_bg\":[%f,%f,%f]}", + server->bg_color[0], server->bg_color[1], + server->bg_color[2], bg[0], bg[1], bg[2]); server->bg_color[0] = bg[0]; server->bg_color[1] = bg[1]; server->bg_color[2] = bg[2]; + struct cg_output *it = NULL; + wl_list_for_each(it, &server->outputs, link) { + wlr_scene_rect_set_color(it->bg, server->bg_color); + } + wl_list_for_each(it, &server->disabled_outputs, link) { + wlr_scene_rect_set_color(it->bg, server->bg_color); + } } void keybinding_switch_output(struct cg_server *server, int output) { + struct cg_output *old_outp = server->curr_output; struct cg_output *it; int count = 1; wl_list_for_each(it, &server->outputs, link) { if(count == output) { set_output(server, it); + ipc_send_event(server, + "{\"event_name\":\"switch_output\",\"old_output\":" + "\"%s\",\"old_output_id\":%d,\"new_output\":\"%s\"," + "\"new_output_id\":%d}", + old_outp->wlr_output->name, output_get_num(old_outp), + it->wlr_output->name, output_get_num(it)); return; } ++count; @@ -865,14 +1408,17 @@ keybinding_switch_output(struct cg_server *server, int output) { void keybinding_move_view_to_output(struct cg_server *server, int output_num) { + struct cg_output *old_outp = server->curr_output; struct cg_view *view = server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view; if(view != NULL) { + workspace_tile_update_view( + server->curr_output->workspaces[server->curr_output->curr_workspace] + ->focused_tile, + NULL); wl_list_remove(&view->link); - server->curr_output->workspaces[server->curr_output->curr_workspace] - ->focused_tile->view = NULL; - keybinding_cycle_views(server, false); + keybinding_cycle_views(server, false, false); if(server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view == NULL) { seat_set_focus(server->seat, NULL); @@ -885,14 +1431,25 @@ keybinding_move_view_to_output(struct cg_server *server, int output_num) { ->workspaces[server->curr_output->curr_workspace]; view->workspace = ws; wl_list_insert(&ws->views, &view->link); - ws->focused_tile->view = view; - view_maximize(view, ws->focused_tile); + wlr_scene_node_reparent(&view->scene_tree->node, ws->scene); + workspace_tile_update_view(ws->focused_tile, view); seat_set_focus(server->seat, view); } + int view_id = -1; + if(view != NULL) { + view_id = view->id; + } + ipc_send_event( + server, + "{\"event_name\":\"move_view_to_output\",\"view_id\":%d,\"old_" + "output\":\"%s\",\"new_output\":\"%s\"}", + view_id, old_outp->wlr_output->name, + server->curr_output->wlr_output->name); } void keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) { + uint32_t old_ws = server->curr_output->curr_workspace; struct cg_view *view = server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view; @@ -900,7 +1457,7 @@ keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) { wl_list_remove(&view->link); server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view = NULL; - keybinding_cycle_views(server, false); + keybinding_cycle_views(server, false, false); if(server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view == NULL) { seat_set_focus(server->seat, NULL); @@ -913,10 +1470,18 @@ keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) { ->workspaces[server->curr_output->curr_workspace]; view->workspace = ws; wl_list_insert(&ws->views, &view->link); - ws->focused_tile->view = view; - view_maximize(view, ws->focused_tile); + wlr_scene_node_reparent(&view->scene_tree->node, ws->scene); + workspace_tile_update_view(ws->focused_tile, view); seat_set_focus(server->seat, view); } + ipc_send_event(server, + "{\"event_name\":\"move_view_to_ws\",\"view_id\":%d," + "\"old_workspace\":%d,\"new_workspace\":%d," + "\"output\":\"%s\",\"output_id\":%d,\"view_pid\":%d}", + view == NULL ? -1 : (int)view->id, old_ws + 1, ws + 1, + server->curr_output->wlr_output->name, + output_get_num(server->curr_output), + view == NULL ? 0 : view->impl->get_pid(view)); } void @@ -965,12 +1530,20 @@ keybinding_configure_output(struct cg_server *server, wl_list_for_each_safe(output, tmp_output, &server->outputs, link) { if(strcmp(config->output_name, output->wlr_output->name) == 0) { output_configure(server, output); + ipc_send_event(output->server, + "{\"event_name\":\"configure_output\",\"output\":\"%" + "s\",\"output_id\":%d}", + cfg->output_name, output_get_num(output)); return; } } wl_list_for_each_safe(output, tmp_output, &server->disabled_outputs, link) { if(strcmp(config->output_name, output->wlr_output->name) == 0) { output_configure(server, output); + ipc_send_event( + output->server, + "{\"event_name\":\"configure_output\",\"output\":\"%s\"}", + cfg->output_name); return; } } @@ -979,7 +1552,24 @@ keybinding_configure_output(struct cg_server *server, void keybinding_configure_input(struct cg_server *server, struct cg_input_config *cfg) { - cg_input_apply_config(cfg, server); + struct cg_input_config *tcfg = input_manager_create_empty_input_config(); + if(tcfg == NULL) { + wlr_log(WLR_ERROR, + "Could not allocate temporary empty input configuration."); + return; + } + struct cg_input_config *ocfg = input_manager_merge_input_configs(cfg, tcfg); + free(tcfg); + if(ocfg == NULL) { + wlr_log(WLR_ERROR, + "Could not allocate input configuration for merging."); + return; + } + wl_list_insert(&server->input_config, &ocfg->link); + cg_input_manager_configure(server); + ipc_send_event(server, + "{\"event_name\":\"configure_input\",\"input\":\"%s\"}", + cfg->identifier); } void @@ -1004,11 +1594,20 @@ keybinding_configure_message(struct cg_server *server, server->message_config.fg_color[2] = config->fg_color[2]; server->message_config.fg_color[3] = config->fg_color[3]; } + ipc_send_event(server, "{\"event_name\":\"configure_message\"}"); } void -keybinding_configure_input_dev(struct cg_server *server, - struct cg_input_config *cfg) {} +set_cursor(bool enabled, struct cg_seat *seat) { + if(enabled == true) { + seat->enable_cursor = true; + wlr_xcursor_manager_set_cursor_image(seat->xcursor_manager, + DEFAULT_XCURSOR, seat->cursor); + } else { + seat->enable_cursor = false; + wlr_cursor_set_image(seat->cursor, NULL, 0, 0, 0, 0, 0, 0); + } +} /* Hint: see keybinding.h for details on "data" */ int @@ -1017,9 +1616,13 @@ run_action(enum keybinding_action action, struct cg_server *server, switch(action) { case KEYBINDING_QUIT: display_terminate(server); + server->running = false; break; case KEYBINDING_CHANGE_TTY: return keybinding_switch_vt(server->backend, data.u); + case KEYBINDING_CURSOR: + set_cursor(data.i, server->seat); + break; case KEYBINDING_LAYOUT_FULLSCREEN: keybinding_workspace_fullscreen(server); break; @@ -1041,13 +1644,13 @@ run_action(enum keybinding_action action, struct cg_server *server, } } break; case KEYBINDING_CYCLE_VIEWS: - keybinding_cycle_views(server, data.b); + keybinding_cycle_views(server, data.b, true); break; case KEYBINDING_CYCLE_TILES: keybinding_cycle_tiles(server, data.b); break; case KEYBINDING_CYCLE_OUTPUT: - keybinding_cycle_outputs(server, data.b); + keybinding_cycle_outputs(server, data.b, true); break; case KEYBINDING_SWITCH_WORKSPACE: keybinding_switch_ws(server, data.u); @@ -1056,9 +1659,22 @@ run_action(enum keybinding_action action, struct cg_server *server, keybinding_switch_output(server, data.u); break; case KEYBINDING_SWITCH_MODE: + if(data.u != server->seat->default_mode) { + wlr_seat_pointer_notify_clear_focus(server->seat->seat); + if(server->seat->enable_cursor == true) { + wlr_xcursor_manager_set_cursor_image( + server->seat->xcursor_manager, "dot_box_mask", + server->seat->cursor); + } + } server->seat->mode = data.u; break; case KEYBINDING_SWITCH_DEFAULT_MODE: + ipc_send_event(server, + "{\"event_name\":\"switch_default_mode\",\"old_mode\":" + "\"%s\",\"mode\":\"%s\"}", + get_mode_name(server->modes, server->seat->default_mode), + get_mode_name(server->modes, data.u)); server->seat->mode = data.u; server->seat->default_mode = data.u; break; @@ -1067,6 +1683,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_SHOW_TIME: keybinding_show_time(server); break; + case KEYBINDING_DUMP: + keybinding_dump(server); + break; case KEYBINDING_SHOW_INFO: keybinding_show_info(server); break; @@ -1165,6 +1784,9 @@ run_action(enum keybinding_action action, struct cg_server *server, server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view); break; + case KEYBINDING_FOCUS_TILE: + keybinding_focus_tile(server, data.u); + break; default: { wlr_log(WLR_ERROR, "run_action was called with a value not present in \"enum " diff --git a/keybinding.h b/keybinding.h index ebbfae9..872f12d 100644 --- a/keybinding.h +++ b/keybinding.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef KEYBINDING_H #define KEYBINDING_H @@ -10,57 +13,87 @@ struct cg_server; +#define FOREACH_KEYBINDING(KEYBINDING) \ + KEYBINDING(KEYBINDING_RUN_COMMAND, \ + exec) /* data.c is the string to execute */ \ + KEYBINDING(KEYBINDING_CLOSE_VIEW, close) \ + KEYBINDING(KEYBINDING_SPLIT_VERTICAL, vsplit) \ + KEYBINDING(KEYBINDING_SPLIT_HORIZONTAL, hsplit) \ + KEYBINDING(KEYBINDING_CHANGE_TTY, switchvt) /*data.u is the desired tty*/ \ + KEYBINDING(KEYBINDING_LAYOUT_FULLSCREEN, only) \ + KEYBINDING(KEYBINDING_CYCLE_VIEWS, \ + cycle_views) /* data.b is 0 if forward, 1 if reverse */ \ + KEYBINDING(KEYBINDING_CYCLE_TILES, \ + cycle_tiles) /* data.b is 0 if forward, 1 if reverse */ \ + KEYBINDING(KEYBINDING_CYCLE_OUTPUT, \ + cycle_outputs) /* data.b is 0 if forward, 1 if reverse */ \ + KEYBINDING(KEYBINDING_CONFIGURE_OUTPUT, \ + output) /* data.o_cfg is the desired output */ \ + \ + KEYBINDING(KEYBINDING_CONFIGURE_MESSAGE, \ + configure_message) /* data.m_cfg is the desired config */ \ + KEYBINDING(KEYBINDING_CONFIGURE_INPUT, \ + input) /* data.i_cfg is the desired input configuration */ \ + \ + KEYBINDING(KEYBINDING_QUIT, quit) \ + KEYBINDING(KEYBINDING_NOOP, abort) \ + KEYBINDING(KEYBINDING_SWITCH_OUTPUT, \ + screen) /* data.u is the desired output */ \ + KEYBINDING(KEYBINDING_SWITCH_WORKSPACE, \ + workspace) /* data.u is the desired workspace */ \ + KEYBINDING(KEYBINDING_SWITCH_MODE, mode) /* data.u is the desired mode */ \ + KEYBINDING(KEYBINDING_SWITCH_DEFAULT_MODE, \ + setmode) /* data.u is the desired mode */ \ + KEYBINDING( \ + KEYBINDING_RESIZE_TILE_HORIZONTAL, \ + resize_tile_horizontal) /* data.i is the number of pixels to add */ \ + \ + KEYBINDING( \ + KEYBINDING_RESIZE_TILE_VERTICAL, \ + resize_tile_vertical) /* data.i is the number of pixels to add to */ \ + \ + KEYBINDING(KEYBINDING_MOVE_VIEW_TO_WORKSPACE, \ + movetoworkspace) /* data.u is the desired workspace */ \ + KEYBINDING(KEYBINDING_MOVE_VIEW_TO_OUTPUT, \ + movetoscreen) /* data.u is the desired output */ \ + KEYBINDING(KEYBINDING_MOVE_VIEW_TO_CYCLE_OUTPUT, \ + move_view_to_cycle_output) /* data.b is 0 if forward, 1 if */ \ + \ + KEYBINDING(KEYBINDING_DUMP, dump) \ + KEYBINDING(KEYBINDING_SHOW_TIME, time) \ + KEYBINDING(KEYBINDING_SHOW_INFO, show_info) \ + KEYBINDING(KEYBINDING_DISPLAY_MESSAGE, message) \ + KEYBINDING(KEYBINDING_CURSOR, cursor) \ + \ + KEYBINDING(KEYBINDING_SWAP_LEFT, exchangeleft) \ + KEYBINDING(KEYBINDING_SWAP_RIGHT, exchangeright) \ + KEYBINDING(KEYBINDING_SWAP_TOP, exchangeup) \ + KEYBINDING(KEYBINDING_SWAP_BOTTOM, exchangedown) \ + \ + KEYBINDING(KEYBINDING_FOCUS_LEFT, focusleft) \ + KEYBINDING(KEYBINDING_FOCUS_RIGHT, focusright) \ + KEYBINDING(KEYBINDING_FOCUS_TOP, focusup) \ + KEYBINDING(KEYBINDING_FOCUS_BOTTOM, focusdown) \ + KEYBINDING(KEYBINDING_FOCUS_TILE, focus_tile) \ + \ + KEYBINDING(KEYBINDING_DEFINEKEY, \ + definekey) /* data.kb is the keybinding definition */ \ + KEYBINDING(KEYBINDING_BACKGROUND, \ + background) /* data.color is the background color */ \ + KEYBINDING(KEYBINDING_DEFINEMODE, \ + definemode) /* data.c is the mode name */ \ + KEYBINDING(KEYBINDING_WORKSPACES, \ + workspaces) /* data.i is the number of workspaces */ + +#define GENERATE_ENUM(ENUM, NAME) ENUM, +#define GENERATE_STRING(STRING, NAME) #NAME, + /* Important: if you add a keybinding which uses data.c or requires "free" * to be called, don't forget to add it to the function "keybinding_list_free" * in keybinding.c */ -enum keybinding_action { - KEYBINDING_RUN_COMMAND, // data.c is the string to execute - KEYBINDING_CLOSE_VIEW, - KEYBINDING_SPLIT_VERTICAL, - KEYBINDING_SPLIT_HORIZONTAL, - KEYBINDING_CHANGE_TTY, // data.u is the desired tty - KEYBINDING_LAYOUT_FULLSCREEN, - KEYBINDING_CYCLE_VIEWS, // data.b is 0 if forward, 1 if reverse - KEYBINDING_CYCLE_TILES, // data.b is 0 if forward, 1 if reverse - KEYBINDING_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if reverse - KEYBINDING_CONFIGURE_OUTPUT, // data.o_cfg is the desired output - // configuration - KEYBINDING_CONFIGURE_MESSAGE, // data.m_cfg is the desired config - KEYBINDING_CONFIGURE_INPUT, // data.i_cfg is the desired input - // configuration - KEYBINDING_QUIT, - KEYBINDING_NOOP, - KEYBINDING_SWITCH_OUTPUT, // data.u is the desired output - KEYBINDING_SWITCH_WORKSPACE, // data.u is the desired workspace - KEYBINDING_SWITCH_MODE, // data.u is the desired mode - KEYBINDING_SWITCH_DEFAULT_MODE, // data.u is the desired mode - KEYBINDING_RESIZE_TILE_HORIZONTAL, // data.i is the number of pixels to add - // to the current width - KEYBINDING_RESIZE_TILE_VERTICAL, // data.i is the number of pixels to add to - // the current height - KEYBINDING_MOVE_VIEW_TO_WORKSPACE, // data.u is the desired workspace - KEYBINDING_MOVE_VIEW_TO_OUTPUT, // data.u is the desired output - KEYBINDING_MOVE_VIEW_TO_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if - // reverse - KEYBINDING_SHOW_TIME, - KEYBINDING_SHOW_INFO, - KEYBINDING_DISPLAY_MESSAGE, +enum keybinding_action { FOREACH_KEYBINDING(GENERATE_ENUM) }; - KEYBINDING_SWAP_LEFT, - KEYBINDING_SWAP_RIGHT, - KEYBINDING_SWAP_TOP, - KEYBINDING_SWAP_BOTTOM, - - KEYBINDING_FOCUS_LEFT, - KEYBINDING_FOCUS_RIGHT, - KEYBINDING_FOCUS_TOP, - KEYBINDING_FOCUS_BOTTOM, - - KEYBINDING_DEFINEKEY, // data.kb is the keybinding definition - KEYBINDING_BACKGROUND, // data.color is the background color - KEYBINDING_DEFINEMODE, // data.c is the mode name - KEYBINDING_WORKSPACES, // data.i is the number of workspaces -}; +extern char *keybinding_action_string[]; union keybinding_params { char *c; @@ -94,7 +127,8 @@ keybinding_list_push(struct keybinding_list *list, void keybinding_list_free(struct keybinding_list *list); void -keybinding_cycle_outputs(struct cg_server *server, bool reverse); +keybinding_cycle_outputs(struct cg_server *server, bool reverse, + bool trigger_event); struct keybinding ** find_keybinding(const struct keybinding_list *list, const struct keybinding *keybinding); diff --git a/libinput.c b/libinput.c index 2510857..dcb9d1f 100644 --- a/libinput.c +++ b/libinput.c @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #include "input.h" #include "input_manager.h" #include "output.h" @@ -262,89 +265,70 @@ input_device_get_type(struct cg_input_device *device) { void apply_config_to_device(struct cg_input_config *config, struct cg_input_device *input_device) { - if(!wlr_input_device_is_libinput(input_device->wlr_device)) { - return; - } - struct libinput_device *device = - wlr_libinput_get_device_handle(input_device->wlr_device); - if(config->mapped_to_output && - !output_by_name_or_id(config->mapped_to_output, input_device->server)) { - wlr_log(WLR_DEBUG, - "'%s' is mapped to offline output '%s'; disabling input", - config->identifier, config->mapped_to_output); - set_send_events(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); - } else if(config->send_events != INT_MIN) { - set_send_events(device, config->send_events); - } else { - // Have to reset to the default mode here, otherwise if ic->send_events - // is unset and a mapped output just came online after being disabled, - // we'd remain stuck sending no events. - set_send_events( - device, - libinput_device_config_send_events_get_default_mode(device)); - } - - if(config->tap != INT_MIN) { - set_tap(device, config->tap); - } - if(config->tap_button_map != INT_MIN) { - set_tap_button_map(device, config->tap_button_map); - } - if(config->drag != INT_MIN) { - set_tap_drag(device, config->drag); - } - if(config->drag_lock != INT_MIN) { - set_tap_drag_lock(device, config->drag_lock); - } - if(config->pointer_accel != FLT_MIN) { - set_accel_speed(device, config->pointer_accel); - } - if(config->accel_profile != INT_MIN) { - set_accel_profile(device, config->accel_profile); - } - if(config->natural_scroll != INT_MIN) { - set_natural_scroll(device, config->natural_scroll); - } - if(config->left_handed != INT_MIN) { - set_left_handed(device, config->left_handed); - } - if(config->click_method != INT_MIN) { - set_click_method(device, config->click_method); - } - if(config->middle_emulation != INT_MIN) { - set_middle_emulation(device, config->middle_emulation); - } - if(config->scroll_method != INT_MIN) { - set_scroll_method(device, config->scroll_method); - } - if(config->scroll_button != INT_MIN) { - set_scroll_button(device, config->scroll_button); - } - if(config->dwt != INT_MIN) { - set_dwt(device, config->dwt); - } - if(config->calibration_matrix.configured) { - set_calibration_matrix(device, config->calibration_matrix.matrix); - } -} - -void -cg_input_apply_config(struct cg_input_config *config, - struct cg_server *server) { - struct cg_input_device *device = NULL; - wl_list_for_each(device, &server->input->devices, link) { - if(strcmp(config->identifier, device->identifier) != 0 && - strcmp(config->identifier, "*") != 0) { - continue; + if(wlr_input_device_is_libinput(input_device->wlr_device)) { + struct libinput_device *device = + wlr_libinput_get_device_handle(input_device->wlr_device); + if(config->mapped_to_output && + !output_by_name_or_id(config->mapped_to_output, + input_device->server)) { + wlr_log(WLR_DEBUG, + "'%s' is mapped to offline output '%s'; disabling input", + config->identifier, config->mapped_to_output); + set_send_events(device, LIBINPUT_CONFIG_SEND_EVENTS_DISABLED); + } else if(config->send_events != INT_MIN) { + set_send_events(device, config->send_events); + } else { + // Have to reset to the default mode here, otherwise if + // ic->send_events is unset and a mapped output just came online + // after being disabled, we'd remain stuck sending no events. + set_send_events( + device, + libinput_device_config_send_events_get_default_mode(device)); } - const char *device_type = input_device_get_type(device); - if(strncmp(config->identifier, "type:", 5) == 0 && - strcmp(config->identifier + 5, device_type) != 0) { - continue; + if(config->tap != INT_MIN) { + set_tap(device, config->tap); + } + if(config->tap_button_map != INT_MIN) { + set_tap_button_map(device, config->tap_button_map); + } + if(config->drag != INT_MIN) { + set_tap_drag(device, config->drag); + } + if(config->drag_lock != INT_MIN) { + set_tap_drag_lock(device, config->drag_lock); + } + if(config->pointer_accel != FLT_MIN) { + set_accel_speed(device, config->pointer_accel); + } + if(config->accel_profile != INT_MIN) { + set_accel_profile(device, config->accel_profile); + } + if(config->natural_scroll != INT_MIN) { + set_natural_scroll(device, config->natural_scroll); + } + if(config->left_handed != INT_MIN) { + set_left_handed(device, config->left_handed); + } + if(config->click_method != INT_MIN) { + set_click_method(device, config->click_method); + } + if(config->middle_emulation != INT_MIN) { + set_middle_emulation(device, config->middle_emulation); + } + if(config->scroll_method != INT_MIN) { + set_scroll_method(device, config->scroll_method); + } + if(config->scroll_button != INT_MIN) { + set_scroll_button(device, config->scroll_button); + } + if(config->dwt != INT_MIN) { + set_dwt(device, config->dwt); + } + if(config->calibration_matrix.configured) { + set_calibration_matrix(device, config->calibration_matrix.matrix); } - apply_config_to_device(config, device); } } @@ -354,71 +338,16 @@ cg_input_configure_libinput_device(struct cg_input_device *input_device) { struct cg_input_config *config = NULL; wl_list_for_each(config, &server->input_config, link) { - if(strcmp(config->identifier, input_device->identifier) != 0 && - strcmp(config->identifier, "*") != 0) { - continue; - } - const char *device_type = input_device_get_type(input_device); - if(!(strncmp(config->identifier, "type:", 5) && - strcmp(config->identifier + 5, device_type) == 0)) { - continue; + if(strcmp(config->identifier, input_device->identifier) == 0 || + strcmp(config->identifier, "*") == 0 || + (strncmp(config->identifier, "type:", 5) == 0 && + strcmp(config->identifier + 5, device_type) == 0)) { + apply_config_to_device(config, input_device); } - apply_config_to_device(config, input_device); } } -bool -cg_input_reset_libinput_device(struct cg_input_device *input_device) { - if(!wlr_input_device_is_libinput(input_device->wlr_device)) { - return false; - } - - struct libinput_device *device = - wlr_libinput_get_device_handle(input_device->wlr_device); - wlr_log(WLR_DEBUG, "cg_input_reset_libinput_device(%s)", - input_device->identifier); - bool changed = false; - - changed |= set_send_events( - device, libinput_device_config_send_events_get_default_mode(device)); - changed |= - set_tap(device, libinput_device_config_tap_get_default_enabled(device)); - changed |= set_tap_button_map( - device, libinput_device_config_tap_get_default_button_map(device)); - changed |= set_tap_drag( - device, libinput_device_config_tap_get_default_drag_enabled(device)); - changed |= set_tap_drag_lock( - device, - libinput_device_config_tap_get_default_drag_lock_enabled(device)); - changed |= set_accel_speed( - device, libinput_device_config_accel_get_default_speed(device)); - changed |= set_accel_profile( - device, libinput_device_config_accel_get_default_profile(device)); - changed |= set_natural_scroll( - device, - libinput_device_config_scroll_get_default_natural_scroll_enabled( - device)); - changed |= set_left_handed( - device, libinput_device_config_left_handed_get_default(device)); - changed |= set_click_method( - device, libinput_device_config_click_get_default_method(device)); - changed |= set_middle_emulation( - device, - libinput_device_config_middle_emulation_get_default_enabled(device)); - changed |= set_scroll_method( - device, libinput_device_config_scroll_get_default_method(device)); - changed |= set_scroll_button( - device, libinput_device_config_scroll_get_default_button(device)); - changed |= - set_dwt(device, libinput_device_config_dwt_get_default_enabled(device)); - - float matrix[6]; - libinput_device_config_calibration_get_default_matrix(device, matrix); - changed |= set_calibration_matrix(device, matrix); - return changed; -} - bool cg_libinput_device_is_builtin(struct cg_input_device *cg_device) { if(!wlr_input_device_is_libinput(cg_device->wlr_device)) { diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 541e713..a93734f 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 1.9.1" "Cagebreak Manual" +cagebreak-config(5) "Version 2.0.0" "Cagebreak Manual" # NAME @@ -17,6 +17,10 @@ are parsed sequentially but independently from the rest of the file. Each line starting with a "#" is a comment. +Note that nesting of commands is limited to 50 times, though lines +are arbitrarily long in practice, though a reasonable limit of 4Mb has +been set. + See *KEY DEFINITIONS* for details on modifier keys and *MODES* for details on modes. @@ -48,7 +52,7 @@ definekey root Close current window - This may be useful for windows of applications which do not offer any method of closing them. -configure_message [font |[f|b]g_color b> |display_time ] +*configure_message [font |[f|b]g_color b> |display_time ]* Configure message characteristics - - font sets - is @@ -75,6 +79,11 @@ configure_message bg_color 1.0 0.0 0.0 1.0 configure_message display_time 4 ``` +*cursor [enable|disable]* + Enable or disable cursor + This simply hides the cursor. Pointing and clicking is + still possible. + *definekey * Bind to execute if pressed in - *definekey* is a more general version of *bind*. @@ -89,6 +98,9 @@ definemode foo definekey foo C-t abort ``` +*dump* + Triggers the *dump* event, see *cagebreak-socket(7)* for details + *escape * Set to switch to root mode to execute one command @@ -170,10 +182,13 @@ definekey top mode root Enable or disable disable-while-typing for specified input device - *event enabled|disabled|disabled_on_external_mouse* + *events enabled|disabled|disabled_on_external_mouse* Enable or disable send_events for specified input device - Disabling send_events disables the input device. + *keybindings [enabled|disabled]* + Enable or disable keybinding interpretation for a specific keyboard. + *left_handed enabled|disabled* Enable or disable left handed mode for specified input device @@ -200,6 +215,12 @@ definekey top mode root *scroll_method none|two_finger|edge|on_button_down* Change scroll method for specified input device + *repeat_delay * + Repeat delay in ms for keyboards only + + *repeat_rate * + Repeat rate in 1/s for keyboards only + *tap enabled|disabled* Enable or disable tap for specified input device @@ -218,31 +239,37 @@ message *movetonextscreen* Move currently focused window to next screen + See *output* for differences between screen and output. *movetoprevscreen* Move currently focused window to previous screen + See *output* for differences between screen and output. *movetoscreen * Move currently focused window to -th screen + See *output* for differences between screen and output. *movetoworkspace * Move currently focused window to -th workspace + See *output* for differences between screen and output. *next* Focus next window in current tile *nextscreen* Focus next screen + See *output* for differences between screen and output. *only* Remove all splits and make current window fill the entire screen -*output [[pos res x rate ] | enable | disable | prio ]* +*output [[pos res x rate [scale ]] | enable | disable | prio | rotate ]* Configure output "" - - and are the position of the monitor in pixels. The top-left monitor should have the coordinates 0 0. - and specify the resolution in pixels. - sets the refresh rate of the monitor (often this is 50 or 60). + - sets the output scale (default is 1.0) - enable and disable enable or disable . Note that if is the only enabled output, *output disable* has no effect. @@ -252,6 +279,30 @@ message to set priorities for outputs, where >= 1. The larger is, the higher the priority is, that is to say, the earlier the output will appear in the list of outputs. + - rotate is used to rotate the output by ` mod 4 x 90` degrees + counter-clockwise. + +``` +# Don't rotate +output DP-1 rotate 0 + +# rotate 90 degrees counter-clockwise +output DP-1 rotate 1 + +# rotate 180 degrees counter-clockwise +output DP-1 rotate 2 + +# rotate 270 degrees counter-clockwise +output DP-1 rotate 3 +``` + + *output* and the *screen* family of commands are similar in that they + both deal with monitors on some level. + - *output* addresses outputs by their name and is vaguely symmetric + to *input*. + - Any *screen* command deals with the number identifying a + monitor within a Cagebreak session either explicitly or + implicitly (i.e. the commands containing next and prev). *prev* Focus previous window in current tile @@ -276,6 +327,7 @@ message *screen * Change to -th screen + See *output* for differences between screen and output. *show_info* Display information about the current setup - In particular, print the identifiers @@ -355,6 +407,7 @@ is used. # SEE ALSO *cagebreak(1)* +*cagebreak-socket(7)* # BUGS @@ -370,7 +423,7 @@ GPG Fingerprints: # LICENSE -Copyright (c) 2020-2022 The Cagebreak authors +Copyright (c) 2020-2023 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md new file mode 100644 index 0000000..d21ce84 --- /dev/null +++ b/man/cagebreak-socket.7.md @@ -0,0 +1,606 @@ +cagebreak-socket(7) "Version 2.0.0" "Cagebreak Manual" + +# NAME + +*cagebreak-socket* — Cagebreak socket + +# SYNOPSIS + +*ipc-socket-capable-tool \$CAGEBREAK_SOCKET* + +# DESCRIPTION + +The cagebreak socket is an ipc socket. + +The socket is enabled if cagebreak is invoked with the `-e` flag. + +The socket accepts cagebreak commands as input (see *cagebreak-config(5)* for more information). + +Events are provided as output as specified in this man page. + +## EVENTS + +Events have a general structure as follows: + +``` +"cg-ipc"json object depending on the eventNULL +``` + +Here is an example of how this works using *only* as a command sent over the socket. + +``` +only +cg-ipc{"event_name":"fullscreen","tile_id":2,"workspace":1,"output":"eDP-1"} +``` + +This documentation describes the trigger for the events, the keys and the data +type of the values of each event. + +*background* + - Trigger: *background* command + - JSON + - event_name: "background" + - old_bg: list of three floating point numbers denoting the old background in rgb + - new_bg: list of three floating point numbers denoting the new background in rgb + +``` +background 0 1.0 0 +cg-ipc{"event_name":"background","old_bg":[0.000000,1.000000,1.000000],"new_bg":[0.000000,1.000000,0.000000]} +``` + +*close* + - Trigger: *close* command + - JSON + - event_name: "close" + - view_id: view id as an integer + - tile_id: tile id as an integer + - view_pid: pid of the process + - workspace: workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +close +cg-ipc{"event_name":"close","view_id":47,"view_pid":30456,"tile_id":47,"workspace":1,"output":"eDP-1","output_id":1} +``` + +*configure_input* + - Trigger: *input* command + - JSON + - event_name: "configure_input" + - input: the input as a string, as per cagebreak-config(5) + +``` +input * accel_profile flat +cg-ipc{"event_name":"configure_input","input":"*"} +``` + +*configure_message* + - Trigger: *configure_message* command + - JSON + - event_name: "configure_message" + +``` +configure_message fg_color 1.0 1.0 0 0 +cg-ipc{"event_name":"configure_message"} +``` + +*configure_output* + - Trigger: *output* command + - JSON + - event_name: "configure_output" + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +output eDP-1 rotate 0 +cg-ipc{"event_name":"configure_output","output":"eDP-1","output_id":1} +``` + +*cursor_switch_tile* + - Trigger: Cursor crosses the border between tiles + - JSON + - event_name: "cursor_switch_tile" + - old_output: name of the old output as a string + - old_output_id: old output id as an integer + - old_tile: number of the old tile as an integer + - new_output: name of the new output as a string + - new_output_id: new output id as an integer + - new_tile: number of the new tile as an integer + +``` +# Cursor switches tile +cg-ipc{"event_name":"cursor_switch_tile","old_output":"eDP-1","old_output_id":1,"old_tile":2,"new_output":"eDP-1","new_output_id":1,"new_tile":3} +``` + +*cycle_outputs* + - Trigger: *nextscreen* and *prevscreen* commands + - JSON + - event_name: "cycle_outputs" + - old_output: old output name as string + - old_output_id: old output id as an integer + - new_output: new output name as string + - new_output_id: new output id as an integer + - reverse: "0" if *nextscreen* or "1" if *prevscreen* + +``` +nextscreen +cg-ipc{"event_name":"cycle_outputs","old_output":"eDP-1","old_output_id":1,"new_output":"HDMI-A-1","new_output_id":2,"reverse":0} +``` + +*cycle_views* + - Trigger: *next* and *prev* commands + - JSON + - event_name: "cycle_views" + - old_view_id: old view id as an integer + - old_view_pid: pid of old view + - new_view_id: new view id as an interger + - new_view_pid: pid of new view + - tile_id: tile id as an integer + - workspace: workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +next +cg-ipc{"event_name":"cycle_views","old_view_id":11,"old_view_pid":32223,"new_view_id":4,"old_view_pid";53221,"tile_id":13,"workspace":1,"output":"eDP-1","output_id":1} +``` + +*definekey* + - Trigger: *definekey* command + - JSON + - event_name: "definekey" + - modifiers: number denoting the modifier as described below + - 0: no modifier + - 1: shift + - 2: alt + - 3: ctrl + - 4: logo key + - 5: modifier 2 + - 6: modifier 3 + - 7: modifier 5 + - key: key as a number + - command: command as a string - CAVEAT: This is an internal representation of + commands which is not in one-to-one correspondance with the commands available in the config file. The differences are as follows: + - "cycle_tiles": represents any *exchange* command (e.g. *exchangeright*) + - "cycle_views": represents both the *next* and the *prev* command + - "cycle_outputs": represents *nextscreen*, *movetoprevscreen* and *prevscreen* commands + - "resize_tile_vertical": represents *resizedown* and *resizeup* commands + - "resize_tile_horizontal": represents *resizeleft* and *resizeright* commands + +``` +definemode foo +cg-ipc{"event_name":"definemode","mode":"foo"} +definekey foo e only +cg-ipc{"event_name":"definekey","modifiers":0,"key":101,"command":"only"} +``` + +*definemode* + - Trigger: *definemode* command + - JSON + - event_name: "definemode" + - mode: name of mode as string + +``` +definemode foo +cg-ipc{"event_name":"definemode","mode":"foo"} +``` + +*destroy_output* + - Trigger: removal of an output + - JSON + - event_name: "destroy_output" + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +# remove output from the device +cg-ipc{"event_name":"destroy_output","output":"HDMI-A-1","output_id":2} +``` + +*dump* + - Trigger: *dump* command + - JSON + - event_name: "dump" + - nws: number of workspaces as an integer + - bg_color: list of three floating point numbers denoting the new background in rgb + - views_curr_id: id of the currently focussed view as an integer + - tiles_curr_id: id of the currently focussed tile as in integer + - curr_output: current output as a string + - default_mode: name of the default mode as a string + - modes: list of names of modes as strings + - outputs: object of objects for each output + - output name as string + - priority: priority as per *output* prio in *cagebreak-config(5)* or default + - coords: object of x and y coordinates of output + - size: object of width and height as integers + - refresh_rate: refresh rate as float + - curr_workspace: current workspace as an integer + - workspaces: list of objects for each workspace + - views: list of objects for each view + - id: view id as an integer + - pid: pid of the process which opened the view as an integer + - coords: object of x and y coordinates + - type: ["xdg"|"xwayland"] + - tiles: list of objects for all tiles + - id: tile id as an integer + - coords: object of x and y coordinates + - size: object of width and height + - view: view id as an integer + - keyboards: object of objects for each keyboard group + - keyboard name as a string + - commands_enabled: 0 if keybindings are disabled for the keyboard, 1 otherwise + - repeat_delay: repeat delay in milliseconds as an integer + - repeat_rate: repeat rate in 1/sec as an integer + - input_devices: object of objects for each keyboard + - identifier for a keyboard as a string + - is_virtual: 1 if virtual, 0 otherwise + - type: [keyboard|pointer|switch] + - cursor_coords: object of x and y coordinates + +``` +dump +cg-ipc{"event_name":"dump","nws":1, +"bg_color":[0.000000,0.000000,0.000000], +"views_curr_id":80, +"tiles_curr_id":8, +"curr_output":"eDP-1", +"default_mode":"top", +"modes":["top","root","resize"], +"outputs": {"eDP-1": { +"priority": -1, +"coords": {"x":0,"y":0}, +"size": {"width":2560,"height":1440}, +"refresh_rate": 60.012000, +"curr_workspace": 0, +"workspaces": [{"views": [{ +"id": 16, +"pid": 2505, +"coords": {"x":0,"y":0}, +"type": "xwayland" + +},{ +"id": 72, +"pid": 11243, +"coords": {"x":0,"y":0}, +"type": "xdg" + +},{ +"id": 56, +"pid": 6700, +"coords": {"x":1280,"y":0}, +"type": "xdg" + +}],"tiles": [{ +"id": 6, +"coords": {"x":0,"y":0}, +"size": {"width":1280,"height":1440}, +"view": 78 + +},{ +"id": 7, +"coords": {"x":1280,"y":0}, +"size": {"width":1280,"height":1440}, +"view": 42 + +}]}] +}} +,"keyboards": {"0:1:Power_Button": { +"commands_enabled": 1, +"repeat_delay": 600, +"repeat_rate": 25 +}} +,"input_devices": {"6058:20564:ThinkPad_Extra_Buttons": { +"is_virtual": 0, +"type": "switch", +},"6058:20564:ThinkPad_Extra_Buttons": { +"is_virtual": 0, +"type": "keyboard", +},"2:10:TPPS/2_Elan_TrackPoint": { +"is_virtual": 0, +"type": "pointer", +},"1:1:AT_Translated_Set_2_keyboard": { +"is_virtual": 0, +"type": "keyboard", +},"0:0:sof-hda-dsp_Headphone": { +"is_virtual": 0, +"type": "keyboard", +},"1739:52619:SYNA8004:00_06CB:CD8B_Touchpad": { +"is_virtual": 0, +"type": "pointer", +},"1739:52619:SYNA8004:00_06CB:CD8B_Mouse": { +"is_virtual": 0, +"type": "pointer", +},"0:3:Sleep_Button": { +"is_virtual": 0, +"type": "keyboard", +},"0:5:Lid_Switch": { +"is_virtual": 0, +"type": "switch", +},"0:6:Video_Bus": { +"is_virtual": 0, +"type": "keyboard", +},"0:1:Power_Button": { +"is_virtual": 0, +"type": "keyboard", +}} +,"cursor_coords":{"x":972.821761,"y":670.836215} +} +``` + +*focus_tile* + - Trigger: *focus* command + - JSON + - event_name: "focus_tile" + - old_tile_id: old tile id as an integer + - new_tile_id: new tile id as an integer + - workspace: workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +focus +cg-ipc{"event_name":"focus_tile","old_tile_id":14,"new_tile_id":13,"workspace":1,"output":"eDP-1","output_id":1} +``` + +*fullscreen* + - Trigger: *only* command + - JSON + - event_name: "fullscreen" + - tile_id: tile id as an integer + - workspace: workspace number as an integer + - output: output as a string + - output_id: id of the output as an integer + +``` +only +cg-ipc{"event_name":"fullscreen","tile_id":3,"workspace":1,"output":"eDP-1","output_id":1} +``` + +*move_view_to_cycle_output* + - Trigger: *movetonextscreen* and similar commands + - JSON + - event_name: "move_view_to_cycle_output" + - view_id: view id as an integer + - view_pid: pid of the process + - old_output: name of the old output as a string + - old_output_id: old output id as an integer + - new_output: name of the new output as a string + - old_output_id: old output id as an integer + +``` +movetonextscreen +cg-ipc{"event_name":"cycle_outputs","old_output":"eDP-1","new_output":"HDMI-A-1","reverse":0} +cg-ipc{"event_name":"move_view_to_cycle_output","view_id":11,"view_pid":43123,"old_output":"eDP-1","old_output_id":1,"new_output":"HDMI-A-1","new_output_id":2} +``` + +*move_view_to_output* + - Trigger: *movetoscreen* command + - JSON + - event_name: "move_view_to_output" + - view_id: view id as an integer + - old_output: old output name as string + - new_output: new output name as string + +``` +movetoscreen 2 +cg-ipc{"event_name":"switch_output","old_output":"eDP-1","new_output":"HDMI-A-1"} +cg-ipc{"event_name":"move_view_to_output","view_id":78,"old_output":"eDP-1","new_output":"HDMI-A-1"} +``` + +*move_view_to_ws* + - Trigger: *movetoworkspace* command + - JSON + - event_name: "move_view_to_ws" + - view_id: view id as an integer + - old_workspace: old workspace number as an integer + - new_workspace: new workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + - view_pid: pid of the process + +``` +movetoworkspace 1 +cg-ipc{"event_name":"switch_ws","old_workspace":1,"new_workspace":1,"output":"eDP-1"} +cg-ipc{"event_name":"move_view_to_ws","view_id":43,"old_workspace":0,"new_workspace":0,"output":"eDP-1","output_id":1,"view_pid":64908} +``` + +*new_output* + - Trigger: a new output is physically attached + - JSON + - event_name: "new_output" + - output: new output name as a string + - output_id: id of the new output as an integer + - priority: priority as per *output* prio in *cagebreak-config(5)* or default + +``` +# a new output is attached +cg-ipc{"event_name":"new_output","output":"HDMI-A-1","output_id":2,"priority":-1} +``` + +*resize_tile* + - Trigger: the *resize* family of commands + - JSON + - event_name: "resize_tile" + - tile_id: tile id as an integer + - old_dims: list of coordinates [x coordinate of lower left corner, y coordinate of lower left corner, x coordinate of upper right corner, y coordinate of upper right corner] + - new_dims: list of coordinate [x coordinate of lower left corner, y coordinate of lower left corner, x coordinate of upper right corner, y coordinate of upper right corner] + - workspace: workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +resizeleft +cg-ipc{"event_name":"resize_tile","tile_id":14,"old_dims":"[1280,0,1440,1280]","new_dims":"[1270,0,1440,1290]","workspace":1,"output":"eDP-1","output_id":1} +cg-ipc{"event_name":"resize_tile","tile_id":13,"old_dims":"[0,0,1440,1280]","new_dims":"[0,0,1440,1270]","workspace":1,"output":"eDP-1","output_id":1} +``` + +*set_nws* + - Trigger: *workspaces* command + - JSON + - event_name: "set_nws" + - old_nws: old number of workspaces as an integer + - new_nws: new number of workspaces as an integer + +``` +workspaces 2 +cg-ipc{"event_name":"set_nws","old_nws":1,"new_nws":2} +``` + +*split* + - Trigger: *split* command + - JSON + - event_name: "split" + - tile_id: old tile id as an integer + - new_tile_id: new tile id as an integer + - workspace: workspace number as an integer + - output: output as a string + - output_id: id of the output as an integer + - vertical: 0 if horizontal split, 1 if not + +``` +hsplit +cg-ipc{"event_name":"split","tile_id":11,"new_tile_id":12,"workspace":1,"output":"eDP-1","output_id":1,"vertical":0} +``` + +*swap_tile* + - Trigger: the *exchange* family of commands + - JSON + - event_name: "swap_tile" + - tile_id: previous tile id as an integer + - tile_pid: pid of previous tile + - swap_tile_id: swap tile id as an integer + - swap_tile_pid: pid of swap tile + - workspace: workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +exchangeright +cg-ipc{"event_name":"swap_tile","tile_id":1,"tile_pid":53478,"swap_tile_id":3,"swap_tile_pid":98234,"workspace":1,"output":"eDP-1"} +``` + +*switch_default_mode* + - Trigger: *setmode* command + - JSON + - event_name: "switch_default_mode" + - old_mode: old mode name + - mode: new mode name + +``` +setmode top +cg-ipc{"event_name":"switch_default_mode","old_mode":"top","mode":"root"} +``` + +switch_output + - Trigger. *screen* command + - JSON + - event_name: "switch_output" + - old_output: name of the old output as a string + - old_output_id: old output id as an integer + - new_output: name of the new output as a string + - new_output_id: new output id as an integer + +``` +screen 2 +cg-ipc{"event_name":"switch_output","old_output":"eDP-1","old_output_id":1,"new_output":"HDMI-A-1","new_output_id":2} +``` + +switch_ws + - Trigger: *workspace* command + - JSON + - event_name: "switch_ws" + - old_workspace: old workspace number as an integer + - new_workspace: new workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + +``` +workspace 2 +cg-ipc{"event_name":"switch_ws","old_workspace":1,"new_workspace":2,"output":"eDP-1","output_id":1} +``` + +*view_map* + - Trigger: view is opened by a process + - JSON + - event_name: "view_map" + - view_id: view id as an integer + - tile_id: tile id as an integer + - workspace: workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + - view_pid: pid of the process + +``` +# process opens a view +cg-ipc{"event_name":"view_map","view_id":28,"tile_id":14,"workspace":1,"output":"eDP-1","output_id":1,"view_pid":39827} +``` + +*view_unmap* + - Trigger: view is closed by a process + - JSON + - event_name: "view_unmap" + - view_id: view id as an integer + - tile_id: tile id as an integer + - workspace: workspace number as an integer + - output: name of the output as a string + - output_id: id of the output as an integer + - view_pid: pid of the process + +``` +# view is closed by the process +cg-ipc{"event_name":"view_unmap","view_id":24,"tile_id":13,"workspace":1,"output":"eDP-1","output_id":1,"view_pid":39544} +``` + +## SECURITY + +The socket has to be explicitly enabled using the `-e` flag. + +The socket is restricted to the user for reading, writing and execution (700). + +All user software can execute arbitrary code while the cagebreak socket is running. + +## EXAMPLES + +*nc -U $CAGEBREAK_SOCKET* + +*ncat -U $CAGEBREAK_SOCKET* + +# SEE ALSO + +*cagebreak(1)* +*cagebreak-config(5)* + +# BUGS + +See GitHub Issues: + +Mail contact: `cagebreak @ project-repo . co` + +GPG Fingerprints: + +- B15B92642760E11FE002DE168708D42451A94AB5 +- F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C +- 3ACEA46CCECD59E4C8222F791CBEB493681E8693 + +# LICENSE + +Copyright (c) 2022 - 2023 The Cagebreak authors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 7ef7963..7feccc1 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 1.9.1" "Cagebreak Manual" +cagebreak(1) "Version 2.0.0" "Cagebreak Manual" # NAME @@ -32,12 +32,15 @@ are displayed in a message box at the top right of the screen. # OPTIONS +*-c * + Load configuration file from + +*-e* + Enable socket + *-h* Display help message and exit -*-r* - Rotate the output 90 degrees clockwise, can be specified up to three times - *-s* Show all available inputs and outputs @@ -68,6 +71,7 @@ are displayed in a message box at the top right of the screen. # SEE ALSO *cagebreak-config(5)* +*cagebreak-socket(7)* # BUGS @@ -83,7 +87,7 @@ GPG Fingerprints: # LICENSE -Copyright (c) 2020-2022 The Cagebreak authors +Copyright (c) 2020-2023 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes diff --git a/meson.build b/meson.build index 172741f..9d2913f 100644 --- a/meson.build +++ b/meson.build @@ -1,10 +1,11 @@ -project('cagebreak', 'c', - version: '1.9.1', - license: 'MIT', - default_options: [ - 'c_std=c11', - 'warning_level=3', - ], +# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# SPDX -License-Identifier: MIT +project( + 'cagebreak', + 'c', +version : '2.0.0', +license : 'MIT', +default_options : ['c_std=c11', 'warning_level=3'] ) add_project_arguments( @@ -53,12 +54,11 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: ['>=0.14.1', '< 0.16.0']) +wlroots = dependency('wlroots', version: ['>=0.16.1', '< 0.17.0']) wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') wayland_client = dependency('wayland-client') -pixman = dependency('pixman-1') xkbcommon = dependency('xkbcommon') cairo = dependency('cairo') pango = dependency('pango') @@ -132,7 +132,6 @@ cagebreak_source_strings = [ 'workspace.c', 'output.c', 'parse.c', - 'render.c', 'seat.c', 'util.c', 'view.c', @@ -150,7 +149,6 @@ cagebreak_header_strings = [ 'workspace.h', 'output.h', 'parse.h', - 'render.h', 'seat.h', 'server.h', 'util.h', @@ -194,7 +192,6 @@ cagebreak_dependencies_dict = { 'libinput': [libinput,true], 'libevdev': [libevdev,true], 'libudev': [libudev,true], - 'pixman': [pixman,true], 'pango': [pango,true], 'cairo': [cairo,true], 'pangocairo': [pangocairo,true], @@ -206,16 +203,15 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.21.0', 'wayland_cursor': '1.21.0', - 'wlroots': '0.15.1', - 'xkbcommon': '1.4.1', - 'fontconfig': '2.14.0', - 'libinput': '1.21.0', - 'libevdev': '1.12.1', - 'libudev': '251', - 'pixman': '0.40.0', - 'pango': '1.50.8', + 'wlroots': '0.16.1', + 'xkbcommon': '1.5.0', + 'fontconfig': '2.14.1', + 'libinput': '1.22.0', + 'libevdev': '1.13.0', + 'libudev': '252', + 'pango': '1.50.12', 'cairo': '1.17.6', - 'pangocairo': '1.50.8', + 'pangocairo': '1.50.12', 'math': '-1' } @@ -229,11 +225,11 @@ foreach name, dep : cagebreak_dependencies_dict if reproducible_build_versions[name] != '-1' if dep[1] == false if dep[0].version() < reproducible_build_versions[name] - warning('The installed version of "' + name + '" on your machine (' + dep[0].version() + ') is older than the one used to generate the binary specified in the README section "Reproducible Builds" (' + reproducible_build_versions[name] + '). It is recommended to use an up-to-date version for compiling cagebreak.' + warning('The installed version of "' + name + '" on your machine (' + dep[0].version() + ') is older than the one used to generate the binary specified in Hashes.md (' + reproducible_build_versions[name] + '). It is recommended to use an up-to-date version for compiling cagebreak.' ) endif elif reproducible_build_versions[name] != dep[0].version() - warning('The installed version of "' + name + '" on your machine (' + dep[0].version() + ') differs from the one used to generate the binary specified in the README section "Reproducible Builds" (' + reproducible_build_versions[name] + '). Cagebreak does not guarantee a reproducible build for this configuration.' + warning('The installed version of "' + name + '" on your machine (' + dep[0].version() + ') differs from the one used to generate the binary specified in Hashes.md (' + reproducible_build_versions[name] + '). Cagebreak does not guarantee a reproducible build for this configuration.' ) break endif @@ -241,12 +237,12 @@ foreach name, dep : cagebreak_dependencies_dict endforeach reproducible_build_compiler = 'gcc' -reproducible_build_compiler_version = '12.1.0' +reproducible_build_compiler_version = '12.2.0' if cc.get_id() != reproducible_build_compiler - warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in the README section "Reproducible Builds" (' + reproducible_build_compiler + ').') + warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in Hashes.md (' + reproducible_build_compiler + ').') elif cc.version() != reproducible_build_compiler_version - warning('The version of ' + cc.get_id() + ' (' + cc.version() + ') differs from the one used to generate the binary specified in the README section "Reproducible Builds" ' + reproducible_build_compiler_version + '.') + warning('The version of ' + cc.get_id() + ' (' + cc.version() + ') differs from the one used to generate the binary specified in Hashes.md ' + reproducible_build_compiler_version + '.') endif executable( @@ -262,15 +258,18 @@ install_data('examples/config', install_dir : '/etc/xdg/cagebreak') if get_option('man-pages') scdoc = find_program('scdoc') + secssinceepoch = 1673193959 + shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') mandir5 = join_paths(get_option('mandir'), 'man5') + mandir7 = join_paths(get_option('mandir'), 'man7') cagebreak_man = custom_target('cagebreak_man', output : 'cagebreak.1', input : 'man/cagebreak.1.md', - capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1658688233 ; @0@ < @INPUT@'.format(scdoc.path())], + capture : true, + command : [sh, '-c', shcommand], install: true, install_dir: mandir1 ) @@ -278,11 +277,20 @@ if get_option('man-pages') cagebreak_man = custom_target('cagebreak_config_man', output : 'cagebreak-config.5', input : 'man/cagebreak-config.5.md', - capture : true, - command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1658688233 ; @0@ < @INPUT@'.format(scdoc.path())], + capture : true, + command : [sh, '-c', shcommand], install: true, install_dir: mandir5 ) + + cagebreak_man = custom_target('cagebreak_socket_man', + output : 'cagebreak-socket.7', + input : 'man/cagebreak-socket.7.md', + capture : true, + command : [sh, '-c', shcommand], + install: true, + install_dir: mandir7 + ) endif if get_option('fuzz') diff --git a/meson_options.txt b/meson_options.txt index b6dcb79..6d4a787 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,5 @@ +# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# SPDX -License-Identifier: MIT option('xwayland', type: 'boolean', value: 'false', description: 'Enable support for X11 applications') option('man-pages', type: 'boolean', value: 'false', description: 'Build man pages (requires pandoc)') option('fuzz', type: 'boolean', value: 'false', description: 'Enable building fuzzer targets') diff --git a/message.c b/message.c index 9e600bb..f0c2c64 100644 --- a/message.c +++ b/message.c @@ -1,11 +1,20 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #include #include #include +#include #include +#include #include +#include +#include +#include #include #include #include +#include #include #include "message.h" @@ -14,6 +23,67 @@ #include "server.h" #include "util.h" +struct msg_buffer { + struct wlr_buffer base; + void *data; + uint32_t format; + size_t stride; +}; + +static void +msg_buffer_destroy(struct wlr_buffer *wlr_buffer) { + struct msg_buffer *buffer = wl_container_of(wlr_buffer, buffer, base); + free(buffer->data); + free(buffer); +} + +static bool +msg_buffer_begin_data_ptr_access(struct wlr_buffer *wlr_buffer, uint32_t flags, + void **data, uint32_t *format, + size_t *stride) { + struct msg_buffer *buffer = wl_container_of(wlr_buffer, buffer, base); + if(data != NULL) { + *data = (void *)buffer->data; + } + if(format != NULL) { + *format = buffer->format; + } + if(stride != NULL) { + *stride = buffer->stride; + } + return true; +} + +static void +msg_buffer_end_data_ptr_access(struct wlr_buffer *wlr_buffer) { + // This space is intentionally left blank +} + +static const struct wlr_buffer_impl msg_buffer_impl = { + .destroy = msg_buffer_destroy, + .begin_data_ptr_access = msg_buffer_begin_data_ptr_access, + .end_data_ptr_access = msg_buffer_end_data_ptr_access, +}; + +static struct msg_buffer * +msg_buffer_create(uint32_t width, uint32_t height, uint32_t stride) { + struct msg_buffer *buffer = calloc(1, sizeof(*buffer)); + if(buffer == NULL) { + return NULL; + } + + wlr_buffer_init(&buffer->base, &msg_buffer_impl, width, height); + buffer->format = DRM_FORMAT_ARGB8888; + buffer->stride = stride; + + buffer->data = malloc(buffer->stride * height); + if(buffer->data == NULL) { + free(buffer); + return NULL; + } + + return buffer; +} cairo_subpixel_order_t to_cairo_subpixel_order(const enum wl_output_subpixel subpixel) { switch(subpixel) { @@ -31,12 +101,11 @@ to_cairo_subpixel_order(const enum wl_output_subpixel subpixel) { return CAIRO_SUBPIXEL_ORDER_DEFAULT; } -struct wlr_texture * +struct msg_buffer * create_message_texture(const char *string, const struct cg_output *output) { const int WIDTH_PADDING = 8; const int HEIGHT_PADDING = 2; - struct wlr_texture *texture; double scale = output->wlr_output->scale; int width = 0; int height = 0; @@ -75,7 +144,6 @@ create_message_texture(const char *string, const struct cg_output *output) { float *bg_col = output->server->message_config.bg_color; cairo_set_source_rgba(cairo, bg_col[0], bg_col[1], bg_col[2], bg_col[3]); cairo_paint(cairo); - PangoContext *pango = pango_cairo_create_context(cairo); float *fg_col = output->server->message_config.fg_color; cairo_set_source_rgba(cairo, fg_col[0], fg_col[1], fg_col[2], fg_col[3]); cairo_set_line_width(cairo, 2); @@ -89,13 +157,22 @@ create_message_texture(const char *string, const struct cg_output *output) { cairo_surface_flush(surface); unsigned char *data = cairo_image_surface_get_data(surface); int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); - texture = - wlr_texture_from_pixels(output->server->renderer, DRM_FORMAT_ARGB8888, - stride, width, height, data); + + struct msg_buffer *buf = msg_buffer_create(width, height, stride); + void *data_ptr; + + if(!wlr_buffer_begin_data_ptr_access(&buf->base, + WLR_BUFFER_DATA_PTR_ACCESS_WRITE, + &data_ptr, NULL, NULL)) { + wlr_log(WLR_ERROR, "Failed to get pointer access to message buffer"); + return NULL; + } + memcpy(data_ptr, data, stride * height); + wlr_buffer_end_data_ptr_access(&buf->base); + cairo_surface_destroy(surface); - g_object_unref(pango); cairo_destroy(cairo); - return texture; + return buf; } #if CG_HAS_FANALYZE @@ -111,8 +188,8 @@ message_set_output(struct cg_output *output, const char *string, free(box); return; } - message->message = create_message_texture(string, output); - if(!message->message) { + struct msg_buffer *buf = create_message_texture(string, output); + if(!buf) { wlr_log(WLR_ERROR, "Could not create message texture"); free(box); free(message); @@ -121,8 +198,9 @@ message_set_output(struct cg_output *output, const char *string, message->position = box; wl_list_insert(&output->messages, &message->link); - int width = message->message->width; - int height = message->message->height; + double scale = output->wlr_output->scale; + int width = buf->base.width / scale; + int height = buf->base.height / scale; message->position->width = width; message->position->height = height; switch(align) { @@ -148,7 +226,23 @@ message_set_output(struct cg_output *output, const char *string, default: break; } - wlr_output_damage_add_box(output->damage, message->position); + + struct wlr_scene_output *scene_output = + wlr_scene_get_scene_output(output->server->scene, output->wlr_output); + if(scene_output == NULL) { + return; + } + message->message = + wlr_scene_buffer_create(&scene_output->scene->tree, &buf->base); + wlr_scene_node_raise_to_top(&message->message->node); + wlr_scene_node_set_enabled(&message->message->node, true); + struct wlr_box outp_box; + wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, + &outp_box); + wlr_scene_buffer_set_dest_size(message->message, width, height); + wlr_scene_node_set_position(&message->message->node, + message->position->x + outp_box.x, + message->position->y + outp_box.y); } void @@ -168,10 +262,11 @@ message_printf(struct cg_output *output, const char *fmt, ...) { free(buffer); return; } - struct wlr_box *output_box = wlr_output_layout_get_box( - output->server->output_layout, output->wlr_output); + struct wlr_box output_box; + wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, + &output_box); - box->x = output_box->width; + box->x = output_box.width; box->y = 0; box->width = 0; box->height = 0; @@ -205,9 +300,10 @@ message_clear(struct cg_output *output) { struct cg_message *message, *tmp; wl_list_for_each_safe(message, tmp, &output->messages, link) { wl_list_remove(&message->link); - wlr_output_damage_add_box(output->damage, message->position); - wlr_texture_destroy(message->message); + struct wlr_buffer *buf = message->message->buffer; + wlr_scene_node_destroy(&message->message->node); free(message->position); + buf->impl->destroy(buf); free(message); } } diff --git a/message.h b/message.h index b1081ab..25bf692 100644 --- a/message.h +++ b/message.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef MESSAGE_H #define MESSAGE_H @@ -6,7 +9,7 @@ struct cg_output; struct wlr_box; -struct wlr_texture; +struct wlr_buffer; enum cg_message_align { CG_MESSAGE_TOP_LEFT, @@ -25,7 +28,8 @@ struct cg_message_config { struct cg_message { struct wlr_box *position; - struct wlr_texture *message; + struct wlr_scene_buffer *message; + struct wl_surface *surface; struct wl_list link; }; diff --git a/output.c b/output.c index 90f1f7e..b36d724 100644 --- a/output.c +++ b/output.c @@ -1,14 +1,7 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2020 Jente Hidskes - * Copyright (C) 2019 The Sway authors - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200809L #include "config.h" #include @@ -21,11 +14,12 @@ #if WLR_HAS_X11_BACKEND #include #endif +#include #include #include #include #include -#include +#include #include #include #include @@ -36,7 +30,6 @@ #include "keybinding.h" #include "message.h" #include "output.h" -#include "render.h" #include "seat.h" #include "server.h" #include "util.h" @@ -46,327 +39,395 @@ #include "xwayland.h" #endif -static void -output_for_each_surface(struct cg_output *output, - cg_surface_iterator_func_t iterator, void *user_data); - -struct surface_iterator_data { - cg_surface_iterator_func_t user_iterator; - void *user_data; - - struct cg_output *output; - - /* Output-local coordinates. */ - double ox, oy; -}; - -static bool -intersects_with_output(struct cg_output *output, - const struct wlr_output_layout *output_layout, - const struct wlr_box *surface_box) { - /* Since the surface_box's x- and y-coordinates are already output local, - * the x- and y-coordinates of this box need to be 0 for this function to - * work correctly. */ - struct wlr_box output_box = {0}; - wlr_output_effective_resolution(output->wlr_output, &output_box.width, - &output_box.height); - - struct wlr_box intersection; - return wlr_box_intersection(&intersection, &output_box, surface_box); -} - -static void -output_for_each_surface_iterator(struct wlr_surface *surface, int sx, int sy, - void *user_data) { - struct surface_iterator_data *data = user_data; - struct cg_output *output = data->output; - - if(!wlr_surface_has_buffer(surface)) { - return; - } - - struct wlr_box surface_box = { - .x = data->ox + sx + surface->sx, - .y = data->oy + sy + surface->sy, - .width = surface->current.width, - .height = surface->current.height, - }; - - if(!intersects_with_output(output, output->server->output_layout, - &surface_box)) { - return; - } - - data->user_iterator(data->output, surface, &surface_box, data->user_data); -} - void -output_surface_for_each_surface(struct cg_output *output, - struct wlr_surface *surface, double ox, - double oy, cg_surface_iterator_func_t iterator, - void *user_data) { - struct surface_iterator_data data = { - .user_iterator = iterator, - .user_data = user_data, - .output = output, - .ox = ox, - .oy = oy, - }; - - wlr_surface_for_each_surface(surface, output_for_each_surface_iterator, - &data); -} - -static void -output_view_for_each_surface(struct cg_output *output, struct cg_view *view, - cg_surface_iterator_func_t iterator, - void *user_data) { - struct surface_iterator_data data = { - .user_iterator = iterator, - .user_data = user_data, - .output = output, - .ox = view->ox, - .oy = view->oy, - }; - - view_for_each_surface(view, output_for_each_surface_iterator, &data); -} - -void -output_view_for_each_popup(struct cg_output *output, struct cg_view *view, - cg_surface_iterator_func_t iterator, - void *user_data) { - struct surface_iterator_data data = { - .user_iterator = iterator, - .user_data = user_data, - .output = output, - .ox = view->ox, - .oy = view->oy, - }; - - view_for_each_popup(view, output_for_each_surface_iterator, &data); -} - -void -output_drag_icons_for_each_surface(struct cg_output *output, - struct wl_list *drag_icons, - cg_surface_iterator_func_t iterator, - void *user_data) { - struct cg_drag_icon *drag_icon; - wl_list_for_each(drag_icon, drag_icons, link) { - if(drag_icon->wlr_drag_icon->mapped) { - double ox = drag_icon->lx; - double oy = drag_icon->ly; - wlr_output_layout_output_coords(output->server->output_layout, - output->wlr_output, &ox, &oy); - output_surface_for_each_surface(output, - drag_icon->wlr_drag_icon->surface, - ox, oy, iterator, user_data); - } - } -} - -static void -output_for_each_surface(struct cg_output *output, - cg_surface_iterator_func_t iterator, void *user_data) { - struct cg_view *view; - wl_list_for_each_reverse( - view, &output->workspaces[output->curr_workspace]->views, link) { - output_view_for_each_surface(output, view, iterator, user_data); - } - - wl_list_for_each_reverse( - view, &output->workspaces[output->curr_workspace]->unmanaged_views, - link) { - output_view_for_each_surface(output, view, iterator, user_data); - } - - output_drag_icons_for_each_surface( - output, &output->server->seat->drag_icons, iterator, user_data); -} - -struct send_frame_done_data { - struct timespec when; -}; - -static void -send_frame_done_iterator(struct cg_output *output, struct wlr_surface *surface, - struct wlr_box *box, void *user_data) { - struct send_frame_done_data *data = user_data; - wlr_surface_send_frame_done(surface, &data->when); -} - -static void -send_frame_done(struct cg_output *output, struct send_frame_done_data *data) { - output_for_each_surface(output, send_frame_done_iterator, data); -} - -struct damage_data { - bool whole; -}; - -static void -count_surface_iterator(struct cg_output *output, struct wlr_surface *surface, - struct wlr_box *_box, void *data) { - size_t *n = data; - (*n)++; -} - -static bool -scan_out_primary_view(struct cg_output *output) { +output_clear(struct cg_output *output) { struct cg_server *server = output->server; - struct wlr_output *wlr_output = output->wlr_output; + wlr_output_layout_remove(server->output_layout, output->wlr_output); - if(!wl_list_empty(&output->messages)) { - return false; + if(server->running && server->curr_output == output && + wl_list_length(&server->outputs) > 1) { + keybinding_cycle_outputs(server, false, true); } - struct cg_drag_icon *drag_icon; - wl_list_for_each(drag_icon, &server->seat->drag_icons, link) { - if(drag_icon->wlr_drag_icon->mapped) { - return false; + wl_list_remove(&output->link); + + message_clear(output); + + struct cg_view *view, *view_tmp; + if(server->running) { + for(unsigned int i = 0; i < server->nws; ++i) { + + bool first = true; + for(struct cg_tile *tile = output->workspaces[i]->focused_tile; + first || output->workspaces[i]->focused_tile != tile; + tile = tile->next) { + first = false; + workspace_tile_update_view(tile, NULL); + } + struct cg_workspace *ws = + server->curr_output + ->workspaces[server->curr_output->curr_workspace]; + wl_list_for_each_safe(view, view_tmp, &output->workspaces[i]->views, + link) { + wl_list_remove(&view->link); + if(wl_list_empty(&server->outputs)) { + view->impl->destroy(view); + } else { + wl_list_insert(&ws->views, &view->link); + wlr_scene_node_reparent(&view->scene_tree->node, ws->scene); + view->workspace = ws; + view->tile = ws->focused_tile; + if(server->seat->focused_view == NULL) { + seat_set_focus(server->seat, view); + } + } + } + wl_list_for_each_safe( + view, view_tmp, &output->workspaces[i]->unmanaged_views, link) { + wl_list_remove(&view->link); + if(wl_list_empty(&server->outputs)) { + view->impl->destroy(view); + } else { + wl_list_insert(&ws->unmanaged_views, &view->link); + wlr_scene_node_reparent(&view->scene_tree->node, ws->scene); + view->workspace = ws; + view->tile = ws->focused_tile; + } + } } } +} - struct cg_workspace *ws = output->workspaces[output->curr_workspace]; - if(ws->focused_tile->next != ws->focused_tile) { - return false; - } - - struct cg_view *view = ws->focused_tile->view; - if(view == NULL || view->wlr_surface == NULL) { - return false; - } - - size_t n_surfaces = 0; - output_view_for_each_surface(output, view, count_surface_iterator, - &n_surfaces); - if(n_surfaces > 1) { - return false; - } - -#if CG_HAS_XWAYLAND - if(view->type == CG_XWAYLAND_VIEW) { - struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); - if(!wl_list_empty(&xwayland_view->xwayland_surface->children) || - !wl_list_empty(&view->workspace->unmanaged_views)) { - return false; +int +output_get_num(const struct cg_output *output) { + struct cg_output *it; + int count = 1; + wl_list_for_each(it, &output->server->outputs, link) { + if(strcmp(output->wlr_output->name, it->wlr_output->name) == 0) { + return count; } + ++count; } -#endif - - struct wlr_surface *surface = view->wlr_surface; - - if(!surface->buffer) { - return false; - } - - if((float)surface->current.scale != wlr_output->scale || - surface->current.transform != wlr_output->transform) { - return false; - } - - wlr_output_attach_buffer(wlr_output, &surface->buffer->base); - if(!wlr_output_test(wlr_output)) { - return false; - } - return wlr_output_commit(wlr_output); + return -1; } static void -damage_surface_iterator(struct cg_output *output, struct wlr_surface *surface, - struct wlr_box *box, void *user_data) { - struct wlr_output *wlr_output = output->wlr_output; - struct damage_data *data = (struct damage_data *)user_data; - bool whole = data->whole; +output_destroy(struct cg_output *output) { + struct cg_server *server = output->server; + char *outp_name = strdup(output->wlr_output->name); + int outp_num = output_get_num(output); - scale_box(box, output->wlr_output->scale); + wl_list_remove(&output->destroy.link); + wl_list_remove(&output->mode.link); + wl_list_remove(&output->commit.link); + wl_list_remove(&output->frame.link); - if(whole) { - wlr_output_damage_add_box(output->damage, box); - } else if(pixman_region32_not_empty(&surface->buffer_damage)) { - pixman_region32_t damage; - pixman_region32_init(&damage); - wlr_surface_get_effective_damage(surface, &damage); + output_clear(output); - if(ceil(wlr_output->scale) > surface->current.scale) { - /* When scaling up a surface it'll become - blurry, so we need to expand the damage - region. */ - wlr_region_expand(&damage, &damage, - ceil(wlr_output->scale) - surface->current.scale); - } - pixman_region32_translate(&damage, box->x, box->y); - wlr_output_damage_add(output->damage, &damage); - pixman_region32_fini(&damage); + /*Important: due to unfortunate events, "workspace" and "output->workspace" + * have nothing in common. The former is the workspace of a single output, + * whereas the latter is the workspace of the outputs.*/ + for(unsigned int i = 0; i < server->nws; ++i) { + workspace_free(output->workspaces[i]); + } + free(output->workspaces); + + free(output); + + if(outp_name != NULL) { + ipc_send_event(server, + "{\"event_name\":\"destroy_output\",\"output\":\"%s\"," + "\"output_id\":%d}", + outp_name, outp_num); + free(outp_name); + } else { + wlr_log(WLR_ERROR, + "Failed to allocate memory for output name in output_destroy"); + } + if(wl_list_empty(&server->outputs)) { + wl_display_terminate(server->wl_display); } } -void -output_damage_surface(struct cg_output *output, struct wlr_surface *surface, - double ox, double oy, bool whole) { - struct damage_data data = { - .whole = whole, - }; - - output_surface_for_each_surface(output, surface, ox, oy, - damage_surface_iterator, &data); +static void +handle_output_destroy(struct wl_listener *listener, void *data) { + struct cg_output *output = wl_container_of(listener, output, destroy); + output_destroy(output); } static void -handle_output_damage_frame(struct wl_listener *listener, void *data) { - struct cg_output *output = wl_container_of(listener, output, damage_frame); - struct send_frame_done_data frame_data = {0}; - +handle_output_frame(struct wl_listener *listener, void *data) { + struct cg_output *output = wl_container_of(listener, output, frame); if(!output->wlr_output->enabled) { return; } + struct wlr_scene_output *scene_output = + wlr_scene_get_scene_output(output->server->scene, output->wlr_output); + if(scene_output == NULL) { + return; + } + wlr_scene_output_commit(scene_output); - bool scanned_out = scan_out_primary_view(output); + struct timespec now = {0}; + clock_gettime(CLOCK_MONOTONIC, &now); + wlr_scene_output_send_frame_done(scene_output, &now); +} - if(scanned_out && !output->last_scanned_out_view) { - wlr_log(WLR_DEBUG, "Scanning out primary view"); - } - if(output->last_scanned_out_view && !scanned_out) { - wlr_log(WLR_DEBUG, "Stopping primary view scan out"); - wlr_output_damage_add_whole(output->damage); - output->last_scanned_out_view = NULL; - } - if(output->last_scanned_out_view && - output->last_scanned_out_view != seat_get_focus(output->server->seat)) { - wlr_output_damage_add_whole(output->damage); - } - if(scanned_out) { - output->last_scanned_out_view = - output->workspaces[output->curr_workspace]->focused_tile->view; +static int +output_set_mode(struct wlr_output *output, int width, int height, + float refresh_rate) { + int mhz = (int)(refresh_rate * 1000); + + if(wl_list_empty(&output->modes)) { + wlr_log(WLR_DEBUG, "Assigning custom mode to %s", output->name); + wlr_output_set_custom_mode(output, width, height, + refresh_rate > 0 ? mhz : 0); + return 0; } - if(scanned_out) { - goto frame_done; + struct wlr_output_mode *mode, *best = NULL; + wl_list_for_each(mode, &output->modes, link) { + if(mode->width == width && mode->height == height) { + if(mode->refresh == mhz) { + best = mode; + break; + } + if(best == NULL || mode->refresh > best->refresh) { + best = mode; + } + } + } + if(!best) { + wlr_log(WLR_ERROR, "Configured mode for %s not available", + output->name); + wlr_log(WLR_INFO, "Picking preferred mode instead"); + best = wlr_output_preferred_mode(output); + } else { + wlr_log(WLR_DEBUG, "Assigning configured mode to %s", output->name); + } + wlr_output_set_mode(output, best); + wlr_output_commit(output); + if(!wlr_output_test(output)) { + wlr_log(WLR_ERROR, + "Unable to assign configured mode to %s, picking arbitrary " + "available mode", + output->name); + struct wlr_output_mode *mode; + wl_list_for_each(mode, &output->modes, link) { + if(mode == best) { + continue; + } + wlr_output_set_mode(output, mode); + wlr_output_commit(output); + if(wlr_output_test(output)) { + break; + } + } + if(!wlr_output_test(output)) { + return 1; + } + } + return 0; +} + +void +output_insert(struct cg_server *server, struct cg_output *output) { + struct cg_output *it, *prev_it = NULL; + bool first = true; + wl_list_for_each(it, &server->outputs, link) { + if(it->priority < output->priority) { + if(first == true) { + wl_list_insert(&server->outputs, &output->link); + } else { + wl_list_insert(it->link.prev, &output->link); + } + return; + } + first = false; + prev_it = it; + } + if(prev_it == NULL) { + wl_list_insert(&server->outputs, &output->link); + } else { + wl_list_insert(&prev_it->link, &output->link); + } +} + +void +output_apply_config(struct cg_server *server, struct cg_output *output, + struct cg_output_config *config) { + struct wlr_output *wlr_output = output->wlr_output; + + if(output->wlr_output->enabled) { + wlr_output_layout_remove(server->output_layout, wlr_output); } - bool needs_frame; - pixman_region32_t damage; - pixman_region32_init(&damage); - if(!wlr_output_damage_attach_render(output->damage, &needs_frame, - &damage)) { - wlr_log(WLR_ERROR, "Cannot make damage output current"); - goto damage_finish; + if(config->priority != -1) { + output->priority = config->priority; } - if(!needs_frame) { - wlr_output_rollback(output->wlr_output); - goto damage_finish; + if(config->angle != -1) { + wlr_output_set_transform(wlr_output, config->angle); + } + if(config->scale != -1) { + wlr_log(WLR_INFO, "Setting output scale to %f", config->scale); + wlr_output_set_scale(wlr_output, config->scale); + } + if(config->pos.x != -1) { + if(output_set_mode(wlr_output, config->pos.width, config->pos.height, + config->refresh_rate) != 0) { + wlr_log(WLR_ERROR, "Setting output mode failed, disabling output."); + output_clear(output); + wl_list_insert(&server->disabled_outputs, &output->link); + wlr_output_enable(wlr_output, false); + wlr_output_commit(wlr_output); + return; + } + wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x, + config->pos.y); + /* Since the size of the output may have changed, we + * reinitialize all workspaces with a fullscreen layout */ + for(unsigned int i = 0; i < output->server->nws; ++i) { + output_make_workspace_fullscreen(output, i); + } + } else { + wlr_output_layout_add_auto(server->output_layout, wlr_output); + + struct wlr_output_mode *preferred_mode = + wlr_output_preferred_mode(wlr_output); + if(preferred_mode) { + wlr_output_set_mode(wlr_output, preferred_mode); + } + } + /* Refuse to disable the only output */ + if(config->status == OUTPUT_DISABLE && + wl_list_length(&server->outputs) > 1) { + output_clear(output); + wl_list_insert(&server->disabled_outputs, &output->link); + wlr_output_enable(wlr_output, false); + wlr_output_commit(wlr_output); + } else { + wl_list_remove(&output->link); + output_insert(server, output); + wlr_output_enable(wlr_output, true); + wlr_output_commit(wlr_output); } - output_render(output, &damage); + if(output->bg != NULL) { + wlr_scene_node_destroy(&output->bg->node); + output->bg = NULL; + } + struct wlr_scene_output *scene_output = + wlr_scene_get_scene_output(output->server->scene, output->wlr_output); + if(scene_output == NULL) { + return; + } + output->bg = wlr_scene_rect_create( + &scene_output->scene->tree, output->wlr_output->width, + output->wlr_output->height, server->bg_color); + struct wlr_box box; + wlr_output_layout_get_box(server->output_layout, output->wlr_output, &box); + wlr_scene_node_set_position(&output->bg->node, box.x, box.y); + wlr_scene_node_lower_to_bottom(&output->bg->node); +} -damage_finish: - pixman_region32_fini(&damage); +struct cg_output_config * +empty_output_config() { + struct cg_output_config *cfg = calloc(1, sizeof(struct cg_output_config)); + if(cfg == NULL) { + wlr_log(WLR_ERROR, "Could not allocate output configuration."); + return NULL; + } -frame_done: - clock_gettime(CLOCK_MONOTONIC, &frame_data.when); - send_frame_done(output, &frame_data); + cfg->status = OUTPUT_DEFAULT; + cfg->pos.x = -1; + cfg->pos.y = -1; + cfg->pos.width = -1; + cfg->pos.height = -1; + cfg->output_name = NULL; + cfg->refresh_rate = 0; + cfg->priority = -1; + cfg->scale = -1; + cfg->angle = -1; + + return cfg; +} + +/* cfg1 has precedence over cfg2 */ +struct cg_output_config * +merge_output_configs(struct cg_output_config *cfg1, + struct cg_output_config *cfg2) { + struct cg_output_config *out_cfg = empty_output_config(); + if(cfg1->status == out_cfg->status) { + out_cfg->status = cfg2->status; + } else { + out_cfg->status = cfg1->status; + } + if(cfg1->pos.x == out_cfg->pos.x) { + out_cfg->pos.x = cfg2->pos.x; + out_cfg->pos.y = cfg2->pos.y; + out_cfg->pos.width = cfg2->pos.width; + out_cfg->pos.height = cfg2->pos.height; + } else { + out_cfg->pos.x = cfg1->pos.x; + out_cfg->pos.y = cfg1->pos.y; + out_cfg->pos.width = cfg1->pos.width; + out_cfg->pos.height = cfg1->pos.height; + } + if(cfg1->output_name == NULL) { + if(cfg2->output_name == NULL) { + out_cfg->output_name = NULL; + } else { + out_cfg->output_name = strdup(cfg2->output_name); + } + } else { + out_cfg->output_name = strdup(cfg1->output_name); + } + if(cfg1->refresh_rate == out_cfg->refresh_rate) { + out_cfg->refresh_rate = cfg2->refresh_rate; + } else { + out_cfg->refresh_rate = cfg1->refresh_rate; + } + if(cfg1->priority == out_cfg->priority) { + out_cfg->priority = cfg2->priority; + } else { + out_cfg->priority = cfg1->priority; + } + if(cfg1->scale == out_cfg->scale) { + out_cfg->scale = cfg2->scale; + } else { + out_cfg->scale = cfg1->scale; + } + if(cfg1->angle == out_cfg->angle) { + out_cfg->status = cfg2->angle; + } else { + out_cfg->angle = cfg1->angle; + } + return out_cfg; +} + +void +output_configure(struct cg_server *server, struct cg_output *output) { + struct cg_output_config *tot_config = empty_output_config(); + struct cg_output_config *config; + wl_list_for_each(config, &server->output_config, link) { + if(strcmp(config->output_name, output->wlr_output->name) == 0) { + if(tot_config == NULL) { + return; + } + struct cg_output_config *prev_config = tot_config; + tot_config = merge_output_configs(config, tot_config); + if(prev_config->output_name != NULL) { + free(prev_config->output_name); + } + free(prev_config); + } + } + if(tot_config != NULL) { + output_apply_config(server, output, tot_config); + } + free(tot_config->output_name); + free(tot_config); } static void @@ -408,203 +469,35 @@ handle_output_mode(struct wl_listener *listener, void *data) { } void -output_clear(struct cg_output *output) { +output_make_workspace_fullscreen(struct cg_output *output, int ws) { struct cg_server *server = output->server; - wlr_output_layout_remove(server->output_layout, output->wlr_output); + struct cg_view *current_view = seat_get_focus(server->seat); - if(server->running && server->curr_output == output && - wl_list_length(&server->outputs) > 1) { - keybinding_cycle_outputs(server, false); - } - - wl_list_remove(&output->link); - - message_clear(output); - - struct cg_view *view, *view_tmp; - if(server->running) { - for(unsigned int i = 0; i < server->nws; ++i) { - - bool first = true; - for(struct cg_tile *tile = output->workspaces[i]->focused_tile; - first || output->workspaces[i]->focused_tile != tile; - tile = tile->next) { - first = false; - tile->view = NULL; - } - wl_list_for_each_safe(view, view_tmp, &output->workspaces[i]->views, - link) { - wl_list_remove(&view->link); - if(wl_list_empty(&server->outputs)) { - view->impl->destroy(view); - } else { - wl_list_insert( - &server->curr_output - ->workspaces[server->curr_output->curr_workspace] - ->views, - &view->link); - view->workspace = - server->curr_output - ->workspaces[server->curr_output->curr_workspace]; - view->tile = - server->curr_output - ->workspaces[server->curr_output->curr_workspace] - ->focused_tile; - if(server->seat->focused_view == NULL) { - seat_set_focus(server->seat, view); - } - } - } - wl_list_for_each_safe( - view, view_tmp, &output->workspaces[i]->unmanaged_views, link) { - wl_list_remove(&view->link); - if(wl_list_empty(&server->outputs)) { - view->impl->destroy(view); - } else { - wl_list_insert( - &server->curr_output - ->workspaces[server->curr_output->curr_workspace] - ->unmanaged_views, - &view->link); - view->workspace = - server->curr_output - ->workspaces[server->curr_output->curr_workspace]; - view->tile = - server->curr_output - ->workspaces[server->curr_output->curr_workspace] - ->focused_tile; - } - } - } - } -} - -static void -output_destroy(struct cg_output *output) { - struct cg_server *server = output->server; - - wl_list_remove(&output->destroy.link); - wl_list_remove(&output->mode.link); - wl_list_remove(&output->commit.link); - wl_list_remove(&output->damage_frame.link); - wl_list_remove(&output->damage_destroy.link); - - output_clear(output); - - /*Important: due to unfortunate events, "workspace" and "output->workspace" - * have nothing in common. The former is the workspace of a single output, - * whereas the latter is the workspace of the outputs.*/ - for(unsigned int i = 0; i < server->nws; ++i) { - workspace_free(output->workspaces[i]); - } - free(output->workspaces); - - free(output); - - if(wl_list_empty(&server->outputs)) { - wl_display_terminate(server->wl_display); - } -} - -static void -handle_output_damage_destroy(struct wl_listener *listener, void *data) { - struct cg_output *output = - wl_container_of(listener, output, damage_destroy); - output_destroy(output); -} - -static void -handle_output_destroy(struct wl_listener *listener, void *data) { - struct cg_output *output = wl_container_of(listener, output, destroy); - wlr_output_damage_destroy(output->damage); - output_destroy(output); -} - -struct cg_output_config * -output_find_config(struct cg_server *server, struct wlr_output *output) { - struct cg_output_config *config; - wl_list_for_each(config, &server->output_config, link) { - if(strcmp(config->output_name, output->name) == 0) { - return config; - } - } - return NULL; -} - -static void -output_set_mode(struct wlr_output *output, int width, int height, - float refresh_rate) { - int mhz = (int)(refresh_rate * 1000); - - if(wl_list_empty(&output->modes)) { - wlr_log(WLR_DEBUG, "Assigning custom mode to %s", output->name); - wlr_output_set_custom_mode(output, width, height, - refresh_rate > 0 ? mhz : 0); - return; - } - - struct wlr_output_mode *mode, *best = NULL; - wl_list_for_each(mode, &output->modes, link) { - if(mode->width == width && mode->height == height) { - if(mode->refresh == mhz) { - best = mode; + if(current_view == NULL || ws != output->curr_workspace) { + struct cg_view *it = NULL; + wl_list_for_each(it, &output->workspaces[ws]->views, link) { + if(view_is_visible(it)) { + current_view = it; break; } - if(best == NULL || mode->refresh > best->refresh) { - best = mode; - } } } - if(!best) { - wlr_log(WLR_ERROR, "Configured mode for %s not available", - output->name); - wlr_log(WLR_INFO, "Picking preferred mode instead"); - best = wlr_output_preferred_mode(output); - } else { - wlr_log(WLR_DEBUG, "Assigning configured mode to %s", output->name); - } - wlr_output_set_mode(output, best); -} -void -output_configure(struct cg_server *server, struct cg_output *output) { - struct wlr_output *wlr_output = output->wlr_output; - struct cg_output_config *config = output_find_config(server, wlr_output); - /* Refuse to disable the only output */ - if(config != NULL && config->status == OUTPUT_DISABLE && - wl_list_length(&server->outputs) == 1) { + workspace_free_tiles(output->workspaces[ws]); + if(full_screen_workspace_tiles(server->output_layout, output->wlr_output, + output->workspaces[ws], + &server->tiles_curr_id) != 0) { + wlr_log(WLR_ERROR, "Failed to allocate space for fullscreen workspace"); return; } - if(output->wlr_output->enabled) { - wlr_output_layout_remove(server->output_layout, wlr_output); + + struct cg_view *it_view; + wl_list_for_each(it_view, &output->workspaces[ws]->views, link) { + it_view->tile = output->workspaces[ws]->focused_tile; } - if(config == NULL || config->status == OUTPUT_ENABLE) { - wlr_output_layout_add_auto(server->output_layout, wlr_output); - - struct wlr_output_mode *preferred_mode = - wlr_output_preferred_mode(wlr_output); - if(preferred_mode) { - wlr_output_set_mode(wlr_output, preferred_mode); - } - wl_list_remove(&output->link); - wl_list_insert(&server->outputs, &output->link); - wlr_output_enable(wlr_output, true); - wlr_output_commit(wlr_output); - } else if(config->status == OUTPUT_DISABLE) { - output_clear(output); - wl_list_insert(&server->disabled_outputs, &output->link); - wlr_output_enable(wlr_output, false); - wlr_output_commit(wlr_output); - } else { - wl_list_remove(&output->link); - wl_list_insert(&server->outputs, &output->link); - output_set_mode(wlr_output, config->pos.width, config->pos.height, - config->refresh_rate); - wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x, - config->pos.y); - wlr_output_enable(wlr_output, true); - wlr_output_commit(wlr_output); + if(ws == output->curr_workspace) { + seat_set_focus(server->seat, current_view); } } @@ -631,24 +524,19 @@ handle_new_output(struct wl_listener *listener, void *data) { output->wlr_output = wlr_output; output->server = server; - output->damage = wlr_output_damage_create(wlr_output); output->last_scanned_out_view = NULL; - output->mode.notify = handle_output_mode; - wl_signal_add(&wlr_output->events.mode, &output->mode); - output->commit.notify = handle_output_commit; - wl_signal_add(&wlr_output->events.commit, &output->commit); - output->destroy.notify = handle_output_destroy; - wl_signal_add(&wlr_output->events.destroy, &output->destroy); - output->damage_frame.notify = handle_output_damage_frame; - wl_signal_add(&output->damage->events.frame, &output->damage_frame); - output->damage_destroy.notify = handle_output_damage_destroy; - wl_signal_add(&output->damage->events.destroy, &output->damage_destroy); - - wlr_output_set_transform(wlr_output, server->output_transform); + struct cg_output_priorities *it; + int prio = -1; + wl_list_for_each(it, &server->output_priorities, link) { + if(strcmp(output->wlr_output->name, it->ident) == 0) { + prio = it->priority; + } + } + output->priority = prio; + wlr_output_set_transform(wlr_output, WL_OUTPUT_TRANSFORM_NORMAL); output->workspaces = NULL; - output->curr_workspace = 0; wl_list_init(&output->messages); if(!wlr_xcursor_manager_load(server->seat->xcursor_manager, @@ -658,9 +546,8 @@ handle_new_output(struct wl_listener *listener, void *data) { wlr_output->name, wlr_output->scale); } - wl_list_insert(&server->outputs, &output->link); + output_insert(server, output); output_configure(server, output); - wlr_output_damage_add_whole(output->damage); output->workspaces = malloc(server->nws * sizeof(struct cg_workspace *)); for(unsigned int i = 0; i < server->nws; ++i) { @@ -669,10 +556,14 @@ handle_new_output(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to allocate workspaces for output"); return; } + output->workspaces[i]->num = i; wl_list_init(&output->workspaces[i]->views); wl_list_init(&output->workspaces[i]->unmanaged_views); } + wlr_scene_node_raise_to_top(&output->workspaces[0]->scene->node); + workspace_focus(output, 0); + /* We are the first output. Set the current output to this one. */ if(server->curr_output == NULL) { server->curr_output = output; @@ -680,20 +571,21 @@ handle_new_output(struct wl_listener *listener, void *data) { wlr_xcursor_manager_set_cursor_image(server->seat->xcursor_manager, DEFAULT_XCURSOR, server->seat->cursor); wlr_cursor_warp(server->seat->cursor, NULL, 0, 0); + + output->destroy.notify = handle_output_destroy; + wl_signal_add(&wlr_output->events.destroy, &output->destroy); + output->frame.notify = handle_output_frame; + wl_signal_add(&wlr_output->events.frame, &output->frame); + output->commit.notify = handle_output_commit; + wl_signal_add(&wlr_output->events.commit, &output->commit); + output->mode.notify = handle_output_mode; + wl_signal_add(&wlr_output->events.mode, &output->mode); + ipc_send_event(server, + "{\"event_name\":\"new_output\",\"output\":\"%s\",\"output_" + "id\":%d,\"priority\":%d}", + output->wlr_output->name, output_get_num(output), + output->priority); } #if CG_HAS_FANALYZE #pragma GCC diagnostic pop #endif - -void -output_set_window_title(struct cg_output *output, const char *title) { - struct wlr_output *wlr_output = output->wlr_output; - - if(wlr_output_is_wl(wlr_output)) { - wlr_wl_output_set_title(wlr_output, title); -#if WLR_HAS_X11_BACKEND - } else if(wlr_output_is_x11(wlr_output)) { - wlr_x11_output_set_title(wlr_output, title); -#endif - } -} diff --git a/output.h b/output.h index ca44a6b..0a255df 100644 --- a/output.h +++ b/output.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_OUTPUT_H #define CG_OUTPUT_H @@ -7,19 +10,17 @@ struct cg_server; struct cg_view; struct wlr_output; -struct wlr_output_damage; struct wlr_surface; struct cg_output { struct cg_server *server; struct wlr_output *wlr_output; - struct wlr_output_damage *damage; + struct wlr_scene_rect *bg; struct wl_listener mode; struct wl_listener commit; struct wl_listener destroy; - struct wl_listener damage_frame; - struct wl_listener damage_destroy; + struct wl_listener frame; struct cg_workspace **workspaces; struct wl_list messages; int curr_workspace; @@ -42,7 +43,9 @@ struct cg_output_config { struct wlr_box pos; char *output_name; float refresh_rate; + float scale; int priority; + int angle; // enum wl_output_transform, -1 signifies "unspecified" struct wl_list link; // cg_server::output_config }; @@ -56,23 +59,9 @@ handle_new_output(struct wl_listener *listener, void *data); void output_configure(struct cg_server *server, struct cg_output *output); void -output_surface_for_each_surface(struct cg_output *output, - struct wlr_surface *surface, double ox, - double oy, cg_surface_iterator_func_t iterator, - void *user_data); -void -output_view_for_each_popup(struct cg_output *output, struct cg_view *view, - cg_surface_iterator_func_t iterator, - void *user_data); -void -output_drag_icons_for_each_surface(struct cg_output *output, - struct wl_list *drag_icons, - cg_surface_iterator_func_t iterator, - void *user_data); -void -output_damage_surface(struct cg_output *output, struct wlr_surface *surface, - double ox, double oy, bool whole); -void output_set_window_title(struct cg_output *output, const char *title); - +void +output_make_workspace_fullscreen(struct cg_output *output, int ws); +int +output_get_num(const struct cg_output *output); #endif diff --git a/pango.c b/pango.c index e9d04d3..c513f97 100644 --- a/pango.c +++ b/pango.c @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #include #include #include diff --git a/pango.h b/pango.h index fed8371..30f2865 100644 --- a/pango.h +++ b/pango.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef _SWAY_PANGO_H #define _SWAY_PANGO_H #include diff --git a/parse.c b/parse.c index 92a8943..d250439 100644 --- a/parse.c +++ b/parse.c @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #define _POSIX_C_SOURCE 200812L #include @@ -75,12 +78,13 @@ parse_key(struct keybinding *keybinding, const char *key_def, char **errstr) { int parse_command(struct cg_server *server, struct keybinding *keybinding, - char *saveptr, char **errstr); + char *saveptr, char **errstr, int nesting_level); /* Parse a keybinding definition and return it if successful, else return NULL */ struct keybinding * -parse_keybinding(struct cg_server *server, char **saveptr, char **errstr) { +parse_keybinding(struct cg_server *server, char **saveptr, char **errstr, + int nesting_level) { struct keybinding *keybinding = malloc(sizeof(struct keybinding)); if(keybinding == NULL) { *errstr = log_error( @@ -93,7 +97,8 @@ parse_keybinding(struct cg_server *server, char **saveptr, char **errstr) { free(keybinding); return NULL; } - if(parse_command(server, keybinding, *saveptr, errstr) != 0) { + if(parse_command(server, keybinding, *saveptr, errstr, nesting_level + 1) != + 0) { free(keybinding); return NULL; } @@ -116,9 +121,28 @@ parse_float(char **saveptr, const char *delim) { } } +int +parse_uint(char **saveptr, const char *delim) { + char *uint_str = strtok_r(NULL, delim, saveptr); + if(uint_str == NULL) { + wlr_log(WLR_ERROR, "Expected a non-negative integer, got nothing"); + return -1; + } + long uint = strtol(uint_str, NULL, 10); + if(uint >= 0 && uint <= INT_MAX) { + return uint; + } else { + wlr_log(WLR_ERROR, + "Error parsing non-negative integer. Must be a number larger " + "or equal to 0 and less or equal to %d", + INT_MAX); + return -1; + } +} + struct cg_input_config * parse_input_config(char **saveptr, char **errstr) { - struct cg_input_config *cfg = calloc(1, sizeof(struct cg_input_config)); + struct cg_input_config *cfg = input_manager_create_empty_input_config(); char *value = NULL; char *ident = NULL; if(cfg == NULL) { @@ -127,28 +151,6 @@ parse_input_config(char **saveptr, char **errstr) { goto error; } - cfg->tap = INT_MIN; - cfg->tap_button_map = INT_MIN; - cfg->drag = INT_MIN; - cfg->drag_lock = INT_MIN; - cfg->dwt = INT_MIN; - cfg->send_events = INT_MIN; - cfg->click_method = INT_MIN; - cfg->middle_emulation = INT_MIN; - cfg->natural_scroll = INT_MIN; - cfg->accel_profile = INT_MIN; - cfg->pointer_accel = FLT_MIN; - cfg->scroll_factor = FLT_MIN; - cfg->scroll_button = INT_MIN; - cfg->scroll_method = INT_MIN; - cfg->left_handed = INT_MIN; - /*cfg->repeat_delay = INT_MIN; - cfg->repeat_rate = INT_MIN; - cfg->xkb_numlock = INT_MIN; - cfg->xkb_capslock = INT_MIN; - cfg->xkb_file_is_set = false; - wl_list_init(&cfg->tools);*/ - ident = strtok_r(NULL, " ", saveptr); if(ident == NULL) { @@ -341,6 +343,32 @@ parse_input_config(char **saveptr, char **errstr) { "Invalid option \"%s\" to setting \"tap_button_map\"", value); goto error; } + } else if(strcmp(setting, "keybindings") == 0) { + if(strcmp(value, "enabled") == 0) { + cfg->enable_keybindings = true; + } else if(strcmp(value, "disabled") == 0) { + cfg->enable_keybindings = false; + } else { + *errstr = log_error( + "Invalid option \"%s\" to setting \"keybindings\"", value); + goto error; + } + } else if(strcmp(setting, "repeat_delay") == 0) { + cfg->repeat_delay = parse_uint(saveptr, " "); + if(cfg->repeat_delay < 0) { + *errstr = log_error("Invalid option \"%s\" to setting " + "\"repeat_delay\", expected positive integer", + value); + goto error; + } + } else if(strcmp(setting, "repeat_rate") == 0) { + cfg->repeat_rate = parse_uint(saveptr, " "); + if(cfg->repeat_rate < 0) { + *errstr = log_error("Invalid option \"%s\" to setting " + "\"repeat_rate\", expected positive integer", + value); + goto error; + } } else { *errstr = log_error("Invalid option to command \"input\""); goto error; @@ -365,8 +393,10 @@ error: } struct keybinding * -parse_bind(struct cg_server *server, char **saveptr, char **errstr) { - struct keybinding *keybinding = parse_keybinding(server, saveptr, errstr); +parse_bind(struct cg_server *server, char **saveptr, char **errstr, + int nesting_level) { + struct keybinding *keybinding = + parse_keybinding(server, saveptr, errstr, nesting_level); if(keybinding == NULL) { wlr_log(WLR_ERROR, "Could not parse keybinding for \"bind\"."); return NULL; @@ -376,7 +406,8 @@ parse_bind(struct cg_server *server, char **saveptr, char **errstr) { } struct keybinding * -parse_definekey(struct cg_server *server, char **saveptr, char **errstr) { +parse_definekey(struct cg_server *server, char **saveptr, char **errstr, + int nesting_level) { char *mode = strtok_r(NULL, " ", saveptr); if(mode == NULL) { *errstr = @@ -388,7 +419,8 @@ parse_definekey(struct cg_server *server, char **saveptr, char **errstr) { *errstr = log_error("Unknown mode \"%s\"", mode); return NULL; } - struct keybinding *keybinding = parse_keybinding(server, saveptr, errstr); + struct keybinding *keybinding = + parse_keybinding(server, saveptr, errstr, nesting_level); if(keybinding == NULL) { wlr_log(WLR_ERROR, "Could not parse keybinding for \"definekey\""); return NULL; @@ -454,6 +486,21 @@ parse_escape(char **saveptr, char **errstr) { return keybinding; } +int +parse_cursor(char **saveptr, char **errstr) { + if(strcmp(*saveptr, "enable") == 0) { + return 1; + } else if(strcmp(*saveptr, "disable") == 0) { + return 0; + } else { + wlr_log(WLR_ERROR, + "Invalid option \"%s\" for \"cursor\". Expected \"enable\" or " + "\"disable\".", + *saveptr); + return -1; + } +} + char * parse_definemode(char **saveptr, char **errstr) { char *mode = strtok_r(NULL, " ", saveptr); @@ -481,25 +528,6 @@ parse_workspaces(char **saveptr, char **errstr) { return nws; } -int -parse_uint(char **saveptr, const char *delim) { - char *uint_str = strtok_r(NULL, delim, saveptr); - if(uint_str == NULL) { - wlr_log(WLR_ERROR, "Expected a non-negative integer, got nothing"); - return -1; - } - long uint = strtol(uint_str, NULL, 10); - if(uint >= 0 && uint <= INT_MAX) { - return uint; - } else { - wlr_log(WLR_ERROR, - "Error parsing non-negative integer. Must be a number larger " - "or equal to 0 and less or equal to %d", - INT_MAX); - return -1; - } -} - int parse_output_config_keyword(char *key_str, enum output_status *status) { if(key_str == NULL) { @@ -509,6 +537,10 @@ parse_output_config_keyword(char *key_str, enum output_status *status) { *status = OUTPUT_DEFAULT; } else if(strcmp(key_str, "prio") == 0) { *status = OUTPUT_DEFAULT; + } else if(strcmp(key_str, "rotate") == 0) { + *status = OUTPUT_DEFAULT; + } else if(strcmp(key_str, "scale") == 0) { + *status = OUTPUT_DEFAULT; } else if(strcmp(key_str, "enable") == 0) { *status = OUTPUT_ENABLE; } else if(strcmp(key_str, "disable") == 0) { @@ -532,6 +564,8 @@ parse_output_config(char **saveptr, char **errstr) { cfg->output_name = NULL; cfg->refresh_rate = 0; cfg->priority = -1; + cfg->scale = -1; + cfg->angle = -1; char *name = strtok_r(NULL, " ", saveptr); if(name == NULL) { *errstr = @@ -550,6 +584,19 @@ parse_output_config(char **saveptr, char **errstr) { return cfg; } + if(strcmp(key_str, "rotate") == 0) { + uint32_t angle = parse_uint(saveptr, " "); + // 360 degrees is equivalent to 0 degrees + cfg->angle = angle % 4; + if(cfg->angle < 0) { + *errstr = + log_error("Error parsing option rotate for output %s", name); + goto error; + } + cfg->output_name = strdup(name); + return cfg; + } + if(strcmp(key_str, "prio") == 0) { cfg->priority = parse_uint(saveptr, " "); if(cfg->priority < 0) { @@ -562,6 +609,19 @@ parse_output_config(char **saveptr, char **errstr) { return cfg; } + if(strcmp(key_str, "scale") == 0) { + cfg->scale = parse_float(saveptr, " "); + if(cfg->scale <= 0.0) { + *errstr = + log_error("Error parsing scale of output configuration for " + "output %s, expected positive float", + name); + goto error; + } + cfg->output_name = strdup(name); + return cfg; + } + cfg->pos.x = parse_uint(saveptr, " "); if(cfg->pos.x < 0) { *errstr = log_error( @@ -692,6 +752,9 @@ parse_message_config(char **saveptr, char **errstr) { return cfg; error: + if(cfg != NULL) { + free(cfg); + } wlr_log(WLR_ERROR, "Message configuration must be of the form " "'configure_message '"); return NULL; @@ -699,8 +762,13 @@ error: int parse_command(struct cg_server *server, struct keybinding *keybinding, - char *saveptr, char **errstr) { + char *saveptr, char **errstr, int nesting_level) { char *action = strtok_r(NULL, " ", &saveptr); + if(nesting_level >= MAX_NESTING_LEVEL) { + *errstr = + log_error("Nesting level of commands is too deep. Giving up."); + return -1; + } if(action == NULL) { *errstr = log_error("Expexted an action to parse, got none."); return -1; @@ -712,10 +780,29 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, keybinding->action = KEYBINDING_SPLIT_HORIZONTAL; } else if(strcmp(action, "quit") == 0) { keybinding->action = KEYBINDING_QUIT; + } else if(strcmp(action, "dump") == 0) { + keybinding->action = KEYBINDING_DUMP; } else if(strcmp(action, "show_info") == 0) { keybinding->action = KEYBINDING_SHOW_INFO; } else if(strcmp(action, "close") == 0) { keybinding->action = KEYBINDING_CLOSE_VIEW; + } else if(strcmp(action, "focus_tile") == 0) { + keybinding->action = KEYBINDING_FOCUS_TILE; + char *nws_str = strtok_r(NULL, " ", &saveptr); + if(nws_str == NULL) { + *errstr = log_error( + "Expected argument for \"focus_tile\" action, got none."); + return -1; + } + + long tile_id = strtol(nws_str, NULL, 10); + if(tile_id < 1) { + *errstr = log_error( + "Tile id for focus_tile must be a positive integer. Got %l\n", + tile_id); + return -1; + } + keybinding->data.u = tile_id; } else if(strcmp(action, "focus") == 0) { keybinding->action = KEYBINDING_CYCLE_TILES; keybinding->data.b = false; @@ -899,13 +986,15 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, keybinding->data.u = (unsigned int)mode_idx; } else if(strcmp(action, "bind") == 0) { keybinding->action = KEYBINDING_DEFINEKEY; - keybinding->data.kb = parse_bind(server, &saveptr, errstr); + keybinding->data.kb = + parse_bind(server, &saveptr, errstr, nesting_level); if(keybinding->data.kb == NULL) { return -1; } } else if(strcmp(action, "definekey") == 0) { keybinding->action = KEYBINDING_DEFINEKEY; - keybinding->data.kb = parse_definekey(server, &saveptr, errstr); + keybinding->data.kb = + parse_definekey(server, &saveptr, errstr, nesting_level); if(keybinding->data.kb == NULL) { return -1; } @@ -921,6 +1010,12 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, if(keybinding->data.kb == NULL) { return -1; } + } else if(strcmp(action, "cursor") == 0) { + keybinding->action = KEYBINDING_CURSOR; + keybinding->data.i = parse_cursor(&saveptr, errstr); + if(keybinding->data.i < 0) { + return -1; + } } else if(strcmp(action, "definemode") == 0) { keybinding->action = KEYBINDING_DEFINEMODE; keybinding->data.c = parse_definemode(&saveptr, errstr); @@ -970,7 +1065,7 @@ parse_rc_line(struct cg_server *server, char *line, char **errstr) { free(saveptr); return -1; } - if(parse_command(server, keybinding, saveptr, errstr) != 0) { + if(parse_command(server, keybinding, saveptr, errstr, 1) != 0) { wlr_log(WLR_ERROR, "Error parsing command."); free(keybinding); free(saveptr); diff --git a/parse.h b/parse.h index 798d732..4e38ea9 100644 --- a/parse.h +++ b/parse.h @@ -1,9 +1,10 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef PARSE_H #define PARSE_H -#define MAX_LINE_SIZE 256 - #include struct cg_server; diff --git a/render.c b/render.c deleted file mode 100644 index 53ed0ea..0000000 --- a/render.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2020 Jente Hidskes - * Copyright (C) 2019 The Sway authors - * - * See the LICENSE file accompanying this file. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "message.h" -#include "output.h" -#include "seat.h" -#include "server.h" -#include "util.h" -#include "view.h" -#include "workspace.h" - -static void -scissor_output(struct wlr_output *output, pixman_box32_t *rect, - struct wlr_renderer *renderer) { - - struct wlr_box box = { - .x = rect->x1, - .y = rect->y1, - .width = rect->x2 - rect->x1, - .height = rect->y2 - rect->y1, - }; - - int output_width, output_height; - wlr_output_transformed_resolution(output, &output_width, &output_height); - enum wl_output_transform transform = - wlr_output_transform_invert(output->transform); - wlr_box_transform(&box, &box, transform, output_width, output_height); - - wlr_renderer_scissor(renderer, &box); -} - -struct render_data { - pixman_region32_t *damage; - int tile_width, tile_height; -}; - -static void -render_texture(struct wlr_output *wlr_output, pixman_region32_t *output_damage, - struct wlr_texture *texture, const struct wlr_box *box, - const float matrix[static 9], struct wlr_renderer *renderer) { - pixman_region32_t damage; - pixman_region32_init(&damage); - pixman_region32_union_rect(&damage, &damage, box->x, box->y, box->width, - box->height); - pixman_region32_intersect(&damage, &damage, output_damage); - if(!pixman_region32_not_empty(&damage)) { - goto damage_finish; - } - - int nrects; - pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects); - for(int i = 0; i < nrects; i++) { - scissor_output(wlr_output, &rects[i], renderer); - wlr_render_texture_with_matrix(renderer, texture, matrix, 1.0F); - } - -damage_finish: - pixman_region32_fini(&damage); -} - -static void -render_surface_iterator(struct cg_output *output, struct wlr_surface *surface, - struct wlr_box *box, void *user_data) { - struct render_data *data = user_data; - struct wlr_output *wlr_output = output->wlr_output; - pixman_region32_t *output_damage = data->damage; - - struct wlr_texture *texture = wlr_surface_get_texture(surface); - if(!texture) { - wlr_log(WLR_DEBUG, "Cannot obtain surface texture"); - return; - } - - scale_box(box, wlr_output->scale); - - float matrix[9]; - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - wlr_matrix_project_box(matrix, box, transform, 0.0F, - wlr_output->transform_matrix); - - if(data->tile_width != 0) { - box->width = - box->width > data->tile_width ? data->tile_width : box->width; - } - if(data->tile_height != 0) { - box->height = - box->height > data->tile_height ? data->tile_height : box->height; - } - render_texture(wlr_output, output_damage, texture, box, matrix, - output->server->renderer); -} - -static void -render_drag_icons(struct cg_output *output, pixman_region32_t *damage, - struct wl_list *drag_icons) { - struct render_data data = { - .damage = damage, - .tile_width = 0, - .tile_height = 0, - }; - output_drag_icons_for_each_surface(output, drag_icons, - render_surface_iterator, &data); -} - -/** - * Render all toplevels without descending into popups. - */ -static void -render_view_toplevels(struct cg_view *view, struct cg_output *output, - pixman_region32_t *damage) { - struct render_data data = { - .damage = damage, - .tile_width = 0, - .tile_height = 0, - }; - struct cg_tile *view_tile = view_get_tile(view); - if(view_tile != NULL) { - if(view_tile->tile.width != view->wlr_surface->current.width || - view_tile->tile.height != view->wlr_surface->current.height) { - view_damage_whole(view); - } - data.tile_width = view_tile->tile.width; - data.tile_height = view_tile->tile.height; - } - - double ox, oy; - ox = view->ox; - oy = view->oy; - output_surface_for_each_surface(output, view->wlr_surface, ox, oy, - render_surface_iterator, &data); -} - -static void -render_popup_iterator(struct cg_output *output, struct wlr_surface *surface, - struct wlr_box *box, void *data) { - /* Render this popup's surface. */ - render_surface_iterator(output, surface, box, data); - - /* Render this popup's child toplevels. */ - output_surface_for_each_surface(output, surface, box->x, box->y, - render_surface_iterator, data); -} - -static void -render_view_popups(struct cg_view *view, struct cg_output *output, - pixman_region32_t *damage) { - struct render_data data = { - .damage = damage, - .tile_width = 0, - .tile_height = 0, - }; - output_view_for_each_popup(output, view, render_popup_iterator, &data); -} - -void -output_render(struct cg_output *output, pixman_region32_t *damage) { - struct cg_server *server = output->server; - struct wlr_output *wlr_output = output->wlr_output; - - struct wlr_renderer *renderer = output->server->renderer; - if(!renderer) { - wlr_log(WLR_DEBUG, "Expected the output backend to have a renderer"); - return; - } - - wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); - - if(!pixman_region32_not_empty(damage)) { - wlr_log(WLR_DEBUG, "Output isn't damaged but needs a buffer swap"); - goto renderer_end; - } - -#ifdef DEBUG - if(server->debug_damage_tracking) { - wlr_renderer_clear(renderer, (float[]){1.0F, 0.0F, 0.0F, 1.0F}); - } -#endif - - int nrects; - pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects); - for(int i = 0; i < nrects; i++) { - scissor_output(wlr_output, &rects[i], renderer); - wlr_renderer_clear(renderer, server->bg_color); - } - - bool first = true; - for(struct cg_tile *tile = - output->workspaces[output->curr_workspace]->focused_tile; - first || - tile != output->workspaces[output->curr_workspace]->focused_tile; - tile = tile->next) { - first = false; - /* Only render visible views */ - if(tile->view != NULL) { - render_view_toplevels(tile->view, output, damage); - } - } - - struct cg_view *view; - wl_list_for_each_reverse( - view, &output->workspaces[output->curr_workspace]->unmanaged_views, - link) { - render_view_toplevels(view, output, damage); - } - - struct cg_view *focused_view = seat_get_focus(server->seat); - if(focused_view != NULL) { - render_view_popups(focused_view, output, damage); - } - - struct cg_message *message; - wl_list_for_each_reverse(message, &output->messages, link) { - float matrix[9]; - wlr_matrix_project_box(matrix, message->position, - WL_OUTPUT_TRANSFORM_NORMAL, 0.0F, - wlr_output->transform_matrix); - render_texture(output->wlr_output, damage, message->message, - message->position, matrix, renderer); - } - render_drag_icons(output, damage, &server->seat->drag_icons); - -renderer_end: - /* Draw software cursor in case hardware cursors aren't - available. This is a no-op when they are. */ - wlr_output_render_software_cursors(wlr_output, damage); - wlr_renderer_scissor(renderer, NULL); - wlr_renderer_end(renderer); - - int output_width, output_height; - wlr_output_transformed_resolution(wlr_output, &output_width, - &output_height); - - pixman_region32_t frame_damage; - pixman_region32_init(&frame_damage); - - enum wl_output_transform transform = - wlr_output_transform_invert(wlr_output->transform); - wlr_region_transform(&frame_damage, &output->damage->current, transform, - output_width, output_height); - -#ifdef DEBUG - if(server->debug_damage_tracking) { - pixman_region32_union_rect(&frame_damage, &frame_damage, 0, 0, - output_width, output_height); - } -#endif - - wlr_output_set_damage(wlr_output, &frame_damage); - pixman_region32_fini(&frame_damage); - - if(!wlr_output_commit(wlr_output)) { - wlr_log(WLR_ERROR, "Could not commit output"); - } -} diff --git a/render.h b/render.h deleted file mode 100644 index 0a883bd..0000000 --- a/render.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef CG_RENDER_H -#define CG_RENDER_H - -struct cg_output; - -void -output_render(struct cg_output *output, pixman_region32_t *damage); - -#endif diff --git a/seat.c b/seat.c index 5449aa4..a3e09a0 100644 --- a/seat.c +++ b/seat.c @@ -1,13 +1,7 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200812L #include "config.h" @@ -17,13 +11,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include -#include #include #include #include @@ -46,69 +41,6 @@ static void drag_icon_update_position(struct cg_drag_icon *drag_icon); -/* XDG toplevels may have nested surfaces, such as popup windows for context - * menus or tooltips. This function tests if any of those are underneath the - * coordinates lx and ly (in output Layout Coordinates). If so, it sets the - * surface pointer to that wlr_surface and the sx and sy coordinates to the - * coordinates relative to that surface's top-left corner. */ -static bool -view_at(const struct cg_view *view, double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy) { - struct wlr_box *output_layout_box = wlr_output_layout_get_box( - view->server->output_layout, view->workspace->output->wlr_output); - if(output_layout_box == NULL) { - return false; - } - - double view_sx = lx - view->ox - output_layout_box->x; - double view_sy = ly - view->oy - output_layout_box->y; - - double _sx, _sy; - struct wlr_surface *_surface = - view_wlr_surface_at(view, view_sx, view_sy, &_sx, &_sy); - if(_surface != NULL) { - *sx = _sx; - *sy = _sy; - *surface = _surface; - return true; - } - - return false; -} - -/* If desktop_view_at returns a view, there is also a - * surface. There cannot be a surface without a view, either. It's - * both or nothing. */ -static struct cg_view * -desktop_view_at(const struct cg_server *server, double lx, double ly, - struct wlr_surface **surface, double *sx, double *sy) { - struct cg_view *view; - wl_list_for_each( - view, - &server->curr_output->workspaces[server->curr_output->curr_workspace] - ->unmanaged_views, - link) { - if(view_at(view, lx, ly, surface, sx, sy)) { - return view; - } - } - - bool first = true; - for(struct cg_tile *tile = - server->curr_output->workspaces[server->curr_output->curr_workspace] - ->focused_tile; - first || - server->curr_output->workspaces[server->curr_output->curr_workspace] - ->focused_tile != tile; - tile = tile->next) { - first = false; - if(tile->view != NULL && view_at(tile->view, lx, ly, surface, sx, sy)) { - return tile->view; - } - } - return NULL; -} - static void update_capabilities(const struct cg_seat *seat) { uint32_t caps = 0; @@ -125,7 +57,8 @@ update_capabilities(const struct cg_seat *seat) { wlr_seat_set_capabilities(seat->seat, caps); /* Hide cursor if the seat doesn't have pointer capability. */ - if((caps & WL_SEAT_CAPABILITY_POINTER) == 0) { + if(((caps & WL_SEAT_CAPABILITY_POINTER) == 0) || + seat->enable_cursor == false) { wlr_cursor_set_image(seat->cursor, NULL, 0, 0, 0, 0, 0, 0); } else { wlr_xcursor_manager_set_cursor_image(seat->xcursor_manager, @@ -141,13 +74,12 @@ remove_touch(struct cg_seat *seat, struct cg_touch *touch) { wlr_cursor_detach_input_device(seat->cursor, touch->device->wlr_device); --seat->num_touch; free(touch); - - update_capabilities(seat); } static void new_touch(struct cg_seat *seat, struct cg_input_device *input_device) { struct wlr_input_device *device = input_device->wlr_device; + struct wlr_touch *wlr_touch = wlr_touch_from_input_device(device); struct cg_touch *touch = calloc(1, sizeof(struct cg_touch)); if(!touch) { wlr_log(WLR_ERROR, "Cannot allocate touch"); @@ -160,10 +92,10 @@ new_touch(struct cg_seat *seat, struct cg_input_device *input_device) { input_device->touch = touch; ++seat->num_touch; - if(device->output_name != NULL) { + if(wlr_touch->output_name != NULL) { struct cg_output *output; wl_list_for_each(output, &seat->server->outputs, link) { - if(strcmp(device->output_name, output->wlr_output->name) == 0) { + if(strcmp(wlr_touch->output_name, output->wlr_output->name) == 0) { wlr_cursor_map_input_to_output(seat->cursor, device, output->wlr_output); break; @@ -180,13 +112,12 @@ remove_pointer(struct cg_seat *seat, struct cg_pointer *pointer) { wlr_cursor_detach_input_device(seat->cursor, pointer->device->wlr_device); --seat->num_pointers; free(pointer); - - update_capabilities(seat); } static void new_pointer(struct cg_seat *seat, struct cg_input_device *input_device) { struct wlr_input_device *device = input_device->wlr_device; + struct wlr_pointer *wlr_pointer = wlr_pointer_from_input_device(device); struct cg_pointer *pointer = calloc(1, sizeof(struct cg_pointer)); if(!pointer) { wlr_log(WLR_ERROR, "Cannot allocate pointer"); @@ -199,10 +130,11 @@ new_pointer(struct cg_seat *seat, struct cg_input_device *input_device) { input_device->pointer = pointer; ++seat->num_pointers; - if(device->output_name != NULL) { + if(wlr_pointer->output_name != NULL) { struct cg_output *output; wl_list_for_each(output, &seat->server->outputs, link) { - if(strcmp(device->output_name, output->wlr_output->name) == 0) { + if(strcmp(wlr_pointer->output_name, output->wlr_output->name) == + 0) { wlr_cursor_map_input_to_output(seat->cursor, device, output->wlr_output); break; @@ -214,8 +146,7 @@ new_pointer(struct cg_seat *seat, struct cg_input_device *input_device) { static int handle_keyboard_repeat(void *data) { struct cg_keyboard_group *cg_group = data; - struct wlr_keyboard *wlr_device = - cg_group->wlr_group->input_device->keyboard; + struct wlr_keyboard *wlr_device = &cg_group->wlr_group->keyboard; if(cg_group->repeat_keybinding != NULL) { if(wlr_device->repeat_info.rate > 0) { if(wl_event_source_timer_update( @@ -234,9 +165,9 @@ handle_keyboard_repeat(void *data) { static void handle_modifier_event(struct wlr_input_device *device, struct cg_seat *seat) { - wlr_seat_set_keyboard(seat->seat, device); - wlr_seat_keyboard_notify_modifiers(seat->seat, - &device->keyboard->modifiers); + struct wlr_keyboard *keyboard = wlr_keyboard_from_input_device(device); + wlr_seat_set_keyboard(seat->seat, keyboard); + wlr_seat_keyboard_notify_modifiers(seat->seat, &keyboard->modifiers); wlr_idle_notify_activity(seat->server->idle, seat->seat); } @@ -256,24 +187,50 @@ static bool handle_command_key_bindings(struct cg_server *server, xkb_keysym_t sym, uint32_t modifiers, uint32_t mode, struct cg_keyboard_group *group) { + if(group->enable_keybindings == false) { + return false; + } struct keybinding **keybinding = find_keybinding( server->keybindings, &(struct keybinding){.key = sym, .mode = mode, .modifiers = modifiers}); - server->seat->mode = - server->seat - ->default_mode; // Return to mode we are currently in by default + if(server->seat->mode != server->seat->default_mode) { + server->seat->mode = + server->seat + ->default_mode; // Return to mode we are currently in by default + double sx, sy; + struct wlr_seat *wlr_seat = server->seat->seat; + struct wlr_surface *surface = NULL; + + struct wlr_scene_node *node = wlr_scene_node_at( + &server->scene->tree.node, server->seat->cursor->x, + server->seat->cursor->y, &sx, &sy); + if(server->seat->enable_cursor) { + wlr_xcursor_manager_set_cursor_image(server->seat->xcursor_manager, + "left_ptr", + server->seat->cursor); + if(node && node->type == WLR_SCENE_NODE_BUFFER) { + struct wlr_scene_surface *scene_surface = + wlr_scene_surface_from_buffer( + wlr_scene_buffer_from_node(node)); + if(scene_surface != NULL) { + surface = scene_surface->surface; + } + wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy); + } + } + } + if(keybinding) { wlr_log( WLR_DEBUG, "Recognized keybinding pressed (key: %d, mode: %d, modifiers: %d)", sym, mode, modifiers); - if(group->wlr_group->input_device->keyboard->repeat_info.delay > 0) { + if(group->wlr_group->keyboard.repeat_info.delay > 0) { group->repeat_keybinding = keybinding; - if(wl_event_source_timer_update(group->key_repeat_timer, - group->wlr_group->input_device - ->keyboard->repeat_info.delay) < - 0) { + if(wl_event_source_timer_update( + group->key_repeat_timer, + group->wlr_group->keyboard.repeat_info.delay) < 0) { wlr_log(WLR_DEBUG, "failed to set key repeat timer"); } } @@ -315,27 +272,25 @@ key_is_modifier(const xkb_keysym_t key) { static void handle_key_event(struct cg_keyboard_group *group, struct cg_seat *seat, void *data) { - struct wlr_event_keyboard_key *event = data; - struct wlr_input_device *device = group->wlr_group->input_device; + struct wlr_keyboard_key_event *event = data; + struct wlr_keyboard *keyboard = &group->wlr_group->keyboard; /* Translate from libinput keycode to an xkbcommon keycode. */ xkb_keycode_t keycode = event->keycode + 8; const xkb_keysym_t *syms; - int nsyms = - xkb_state_key_get_syms(device->keyboard->xkb_state, keycode, &syms); + int nsyms = xkb_state_key_get_syms(keyboard->xkb_state, keycode, &syms); bool handled = false; for(int i = 0; i < nsyms; ++i) { if(event->state == WL_KEYBOARD_KEY_STATE_PRESSED && !key_is_modifier(syms[i])) { - uint32_t modifiers = wlr_keyboard_get_modifiers(device->keyboard); + uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard); /* Get the consumed_modifiers and remove them from the modifier list */ xkb_mod_mask_t consumed_modifiers = - xkb_state_key_get_consumed_mods2(device->keyboard->xkb_state, - keycode, + xkb_state_key_get_consumed_mods2(keyboard->xkb_state, keycode, XKB_CONSUMED_MODE_GTK); if(handle_command_key_bindings(seat->server, syms[i], modifiers & ~consumed_modifiers, @@ -349,7 +304,7 @@ handle_key_event(struct cg_keyboard_group *group, struct cg_seat *seat, if(!handled) { /* Otherwise, we pass it along to the client. */ - wlr_seat_set_keyboard(seat->seat, device); + wlr_seat_set_keyboard(seat->seat, keyboard); wlr_seat_keyboard_notify_key(seat->seat, event->time_msec, event->keycode, event->state); } @@ -368,18 +323,32 @@ static void handle_keyboard_group_modifiers(struct wl_listener *listener, void *_data) { struct cg_keyboard_group *group = wl_container_of(listener, group, modifiers); - handle_modifier_event(group->wlr_group->input_device, group->seat); + handle_modifier_event(&group->wlr_group->keyboard.base, group->seat); +} + +static bool +repeat_info_match(struct wlr_keyboard *a, struct wlr_keyboard *b) { + return a->repeat_info.rate == b->repeat_info.rate && + a->repeat_info.delay == b->repeat_info.delay; } static void -cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) { - struct wlr_keyboard *wlr_keyboard = device->keyboard; - struct cg_keyboard_group *group; - wl_list_for_each(group, &seat->keyboard_groups, link) { - struct wlr_keyboard_group *wlr_group = group->wlr_group; - if(wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard)) { - wlr_log(WLR_DEBUG, "Adding keyboard to existing group."); - return; +cg_keyboard_group_add(struct cg_input_device *input_device, + struct cg_seat *seat) { + struct wlr_input_device *device = input_device->wlr_device; + struct wlr_keyboard *wlr_keyboard = wlr_keyboard_from_input_device(device); + // Virtual devices should not be grouped + if(!input_device->is_virtual) { + struct cg_keyboard_group *group; + wl_list_for_each(group, &seat->keyboard_groups, link) { + struct wlr_keyboard_group *wlr_group = group->wlr_group; + if(wlr_keyboard_keymaps_match(wlr_keyboard->keymap, + wlr_group->keyboard.keymap) && + repeat_info_match(wlr_keyboard, &wlr_group->keyboard) && + wlr_keyboard_group_add_keyboard(wlr_group, wlr_keyboard)) { + wlr_log(WLR_DEBUG, "Adding keyboard to existing group."); + return; + } } } /* This is reached if and only if the keyboard could not be inserted into @@ -399,10 +368,15 @@ cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) { cg_group->wlr_group->data = cg_group; wlr_keyboard_set_keymap(&cg_group->wlr_group->keyboard, - device->keyboard->keymap); + wlr_keyboard->keymap); wlr_keyboard_set_repeat_info(&cg_group->wlr_group->keyboard, - device->keyboard->repeat_info.rate, - device->keyboard->repeat_info.delay); + wlr_keyboard->repeat_info.rate, + wlr_keyboard->repeat_info.delay); + if(input_device->identifier != NULL) { + cg_group->identifier = strdup(input_device->identifier); + } else { + cg_group->identifier = NULL; + } wlr_log(WLR_DEBUG, "Created keyboard group."); wlr_keyboard_group_add_keyboard(cg_group->wlr_group, wlr_keyboard); @@ -418,12 +392,17 @@ cg_keyboard_group_add(struct wlr_input_device *device, struct cg_seat *seat) { seat->server->event_loop, handle_keyboard_repeat, cg_group); cg_group->modifiers.notify = handle_keyboard_group_modifiers; + cg_group->enable_keybindings = true; + cg_input_manager_configure_keyboard_group(cg_group); return; cleanup: if(cg_group && cg_group->wlr_group) { wlr_keyboard_group_destroy(cg_group->wlr_group); } + if(cg_group && cg_group->identifier) { + free(cg_group->identifier); + } free(cg_group); } @@ -445,16 +424,15 @@ new_keyboard(struct cg_seat *seat, struct cg_input_device *input_device) { return; } - wlr_keyboard_set_keymap(device->keyboard, keymap); + wlr_keyboard_set_keymap(wlr_keyboard_from_input_device(device), keymap); xkb_keymap_unref(keymap); xkb_context_unref(context); - wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); - cg_keyboard_group_add(device, seat); + cg_keyboard_group_add(input_device, seat); ++seat->num_keyboards; - wlr_seat_set_keyboard(seat->seat, device); + wlr_seat_set_keyboard(seat->seat, wlr_keyboard_from_input_device(device)); } void @@ -481,19 +459,46 @@ seat_add_device(struct cg_seat *seat, struct cg_input_device *device) { update_capabilities(seat); } +static void +destroy_empty_wlr_keyboard_group(void *data) { + wlr_keyboard_group_destroy(data); +} + void remove_keyboard(struct cg_seat *seat, struct cg_input_device *keyboard) { if(!keyboard) { return; } struct wlr_seat *wlr_seat = seat->seat; - struct wlr_keyboard *wlr_keyboard = keyboard->wlr_device->keyboard; - if(keyboard->wlr_device->keyboard->group) { - wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard); - } - if(wlr_seat_get_keyboard(wlr_seat) == wlr_keyboard) { - wlr_seat_set_keyboard(wlr_seat, NULL); + struct wlr_keyboard *wlr_keyboard = + wlr_keyboard_from_input_device(keyboard->wlr_device); + struct wlr_keyboard_group *wlr_group = wlr_keyboard->group; + if(wlr_group) { + wlr_keyboard_group_remove_keyboard(wlr_group, wlr_keyboard); + + if(wl_list_empty(&wlr_group->devices)) { + wlr_log(WLR_DEBUG, "Destroying empty keyboard group %p", + (void *)wlr_group); + struct cg_keyboard_group *group = wlr_group->data; + if(wlr_seat_get_keyboard(wlr_seat) == &wlr_group->keyboard) { + wlr_seat_set_keyboard(wlr_seat, NULL); + } + wlr_group->data = NULL; + wl_list_remove(&group->link); + wl_list_remove(&group->key.link); + wl_list_remove(&group->modifiers.link); + if(group->identifier != NULL) { + free(group->identifier); + } + free(group); + + // To prevent use-after-free conditions when handling key events, + // defer freeing the wlr_keyboard_group until idle + wl_event_loop_add_idle(seat->server->event_loop, + destroy_empty_wlr_keyboard_group, wlr_group); + } } + --seat->num_keyboards; } @@ -544,6 +549,9 @@ handle_request_set_selection(struct wl_listener *listener, void *data) { static void handle_request_set_cursor(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, request_set_cursor); + if(seat->enable_cursor == false || seat->mode != seat->default_mode) { + return; + } struct wlr_seat_pointer_request_set_cursor_event *event = data; struct wlr_surface *focused_surface = event->seat_client->seat->pointer_state.focused_surface; @@ -565,21 +573,25 @@ handle_request_set_cursor(struct wl_listener *listener, void *data) { static void handle_touch_down(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, touch_down); - struct wlr_event_touch_down *event = data; + struct wlr_touch_down_event *event = data; double lx, ly; - wlr_cursor_absolute_to_layout_coords(seat->cursor, event->device, event->x, - event->y, &lx, &ly); + wlr_cursor_absolute_to_layout_coords(seat->cursor, &event->touch->base, + event->x, event->y, &lx, &ly); double sx, sy; - struct wlr_surface *surface; - struct cg_view *view = - desktop_view_at(seat->server, lx, ly, &surface, &sx, &sy); + struct wlr_scene_node *node = + wlr_scene_node_at(&seat->server->scene->tree.node, lx, ly, &sx, &sy); uint32_t serial = 0; - if(view) { - serial = wlr_seat_touch_notify_down( - seat->seat, surface, event->time_msec, event->touch_id, sx, sy); + if(node && node->type == WLR_SCENE_NODE_BUFFER) { + struct wlr_scene_surface *scene_surface = + wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + if(scene_surface != NULL) { + serial = wlr_seat_touch_notify_down( + seat->seat, scene_surface->surface, event->time_msec, + event->touch_id, sx, sy); + } } if(serial && wlr_seat_touch_num_points(seat->seat) == 1) { @@ -594,7 +606,7 @@ handle_touch_down(struct wl_listener *listener, void *data) { static void handle_touch_up(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, touch_up); - struct wlr_event_touch_up *event = data; + struct wlr_touch_up_event *event = data; if(!wlr_seat_touch_get_point(seat->seat, event->touch_id)) { return; @@ -607,24 +619,29 @@ handle_touch_up(struct wl_listener *listener, void *data) { static void handle_touch_motion(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, touch_motion); - struct wlr_event_touch_motion *event = data; + struct wlr_touch_motion_event *event = data; if(!wlr_seat_touch_get_point(seat->seat, event->touch_id)) { return; } double lx, ly; - wlr_cursor_absolute_to_layout_coords(seat->cursor, event->device, event->x, - event->y, &lx, &ly); + wlr_cursor_absolute_to_layout_coords(seat->cursor, &event->touch->base, + event->x, event->y, &lx, &ly); double sx, sy; - struct wlr_surface *surface; - struct cg_view *view = - desktop_view_at(seat->server, lx, ly, &surface, &sx, &sy); + struct wlr_scene_node *node = + wlr_scene_node_at(&seat->server->scene->tree.node, lx, ly, &sx, &sy); - if(view) { - wlr_seat_touch_point_focus(seat->seat, surface, event->time_msec, - event->touch_id, sx, sy); + if(node && node->type == WLR_SCENE_NODE_BUFFER) { + struct wlr_scene_surface *scene_surface = + wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + if(scene_surface != NULL) { + + wlr_seat_touch_point_focus(seat->seat, scene_surface->surface, + event->time_msec, event->touch_id, sx, + sy); + } wlr_seat_touch_notify_motion(seat->seat, event->time_msec, event->touch_id, sx, sy); } else { @@ -651,7 +668,7 @@ handle_cursor_frame(struct wl_listener *listener, void *_data) { static void handle_cursor_axis(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, cursor_axis); - struct wlr_event_pointer_axis *event = data; + struct wlr_pointer_axis_event *event = data; wlr_seat_pointer_notify_axis(seat->seat, event->time_msec, event->orientation, event->delta, @@ -662,7 +679,7 @@ handle_cursor_axis(struct wl_listener *listener, void *data) { static void handle_cursor_button(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, cursor_button); - struct wlr_event_pointer_button *event = data; + struct wlr_pointer_button_event *event = data; wlr_seat_pointer_notify_button(seat->seat, event->time_msec, event->button, event->state); @@ -675,18 +692,24 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { struct wlr_seat *wlr_seat = seat->seat; struct wlr_surface *surface = NULL; - struct cg_view *view = desktop_view_at(seat->server, seat->cursor->x, - seat->cursor->y, &surface, &sx, &sy); + struct wlr_scene_node *node = + wlr_scene_node_at(&seat->server->scene->tree.node, seat->cursor->x, + seat->cursor->y, &sx, &sy); - if(!view) { - wlr_seat_pointer_clear_focus(wlr_seat); - } else { + if(node && node->type == WLR_SCENE_NODE_BUFFER) { + struct wlr_scene_surface *scene_surface = + wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + if(scene_surface != NULL) { + surface = scene_surface->surface; + } wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy); bool focus_changed = wlr_seat->pointer_state.focused_surface != surface; if(!focus_changed && time > 0) { wlr_seat_pointer_notify_motion(wlr_seat, time, sx, sy); } + } else { + wlr_seat_pointer_clear_focus(wlr_seat); } struct cg_drag_icon *drag_icon; @@ -695,15 +718,54 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { } wlr_idle_notify_activity(seat->server->idle, seat->seat); + + /* Check if cursor switched tile */ + struct wlr_output *c_outp = wlr_output_layout_output_at( + seat->server->output_layout, seat->cursor->x, seat->cursor->y); + struct cg_output *cg_outp = NULL; + wl_list_for_each(cg_outp, &seat->server->outputs, link) { + if(cg_outp->wlr_output == c_outp) { + break; + } + } + struct cg_tile *c_tile; + bool first = true; + for(c_tile = cg_outp->workspaces[cg_outp->curr_workspace]->focused_tile; + first || + c_tile != cg_outp->workspaces[cg_outp->curr_workspace]->focused_tile; + c_tile = c_tile->next) { + first = false; + double ox = seat->cursor->x, oy = seat->cursor->y; + wlr_output_layout_output_coords(seat->server->output_layout, c_outp, + &ox, &oy); + if(c_tile->tile.x <= ox && c_tile->tile.y <= oy && + c_tile->tile.x + c_tile->tile.width >= ox && + c_tile->tile.y + c_tile->tile.height >= oy) { + break; + } + } + if(seat->cursor_tile != NULL && seat->cursor_tile != c_tile) { + ipc_send_event(seat->server, + "{\"event_name\":\"cursor_switch_tile\",\"old_output\":" + "\"%s\",\"old_output_id\":%d," + "\"old_tile\":%d,\"new_output\":\"%s\",\"new_output_" + "id\":%d,\"new_tile\":%d}", + seat->cursor_tile->workspace->output->wlr_output->name, + output_get_num(seat->cursor_tile->workspace->output), + seat->cursor_tile->id, c_outp->name, + output_get_num(cg_outp), c_tile->id); + } + seat->cursor_tile = c_tile; } static void handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, cursor_motion_absolute); - struct wlr_event_pointer_motion_absolute *event = data; + struct wlr_pointer_motion_absolute_event *event = data; - wlr_cursor_warp_absolute(seat->cursor, event->device, event->x, event->y); + wlr_cursor_warp_absolute(seat->cursor, &event->pointer->base, event->x, + event->y); process_cursor_motion(seat, event->time_msec); wlr_idle_notify_activity(seat->server->idle, seat->seat); } @@ -711,34 +773,20 @@ handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { static void handle_cursor_motion(struct wl_listener *listener, void *data) { struct cg_seat *seat = wl_container_of(listener, seat, cursor_motion); - struct wlr_event_pointer_motion *event = data; + struct wlr_pointer_motion_event *event = data; - wlr_cursor_move(seat->cursor, event->device, event->delta_x, + wlr_cursor_move(seat->cursor, &event->pointer->base, event->delta_x, event->delta_y); process_cursor_motion(seat, event->time_msec); wlr_idle_notify_activity(seat->server->idle, seat->seat); } -static void -drag_icon_damage(struct cg_drag_icon *drag_icon) { - struct cg_output *output; - wl_list_for_each(output, &drag_icon->seat->server->outputs, link) { - struct wlr_box *output_layout_box = wlr_output_layout_get_box( - output->server->output_layout, output->wlr_output); - output_damage_surface(output, drag_icon->wlr_drag_icon->surface, - drag_icon->lx - output_layout_box->x, - drag_icon->ly - output_layout_box->y, true); - } -} - static void drag_icon_update_position(struct cg_drag_icon *drag_icon) { struct wlr_drag_icon *wlr_icon = drag_icon->wlr_drag_icon; struct cg_seat *seat = drag_icon->seat; struct wlr_touch_point *point; - drag_icon_damage(drag_icon); - switch(wlr_icon->drag->grab_type) { case WLR_DRAG_GRAB_KEYBOARD: return; @@ -755,8 +803,8 @@ drag_icon_update_position(struct cg_drag_icon *drag_icon) { drag_icon->ly = seat->touch_ly; break; } - - drag_icon_damage(drag_icon); + wlr_scene_node_set_position(&drag_icon->scene_tree->node, drag_icon->lx, + drag_icon->ly); } static void @@ -764,9 +812,9 @@ handle_drag_icon_destroy(struct wl_listener *listener, void *_data) { struct cg_drag_icon *drag_icon = wl_container_of(listener, drag_icon, destroy); - drag_icon_damage(drag_icon); wl_list_remove(&drag_icon->link); wl_list_remove(&drag_icon->destroy.link); + wlr_scene_node_destroy(&drag_icon->scene_tree->node); free(drag_icon); } @@ -789,7 +837,6 @@ handle_request_start_drag(struct wl_listener *listener, void *data) { return; } - // TODO: tablet grabs wlr_log(WLR_DEBUG, "Ignoring start_drag request: " "could not validate pointer/touch serial %" PRIu32, @@ -812,6 +859,12 @@ handle_start_drag(struct wl_listener *listener, void *data) { } drag_icon->seat = seat; drag_icon->wlr_drag_icon = wlr_drag_icon; + drag_icon->scene_tree = wlr_scene_subsurface_tree_create( + &seat->server->scene->tree, wlr_drag_icon->surface); + if(!drag_icon->scene_tree) { + free(drag_icon); + return; + } drag_icon->destroy.notify = handle_drag_icon_destroy; wl_signal_add(&wlr_drag_icon->events.destroy, &drag_icon->destroy); @@ -831,6 +884,9 @@ handle_destroy(struct wl_listener *listener, void *_data) { wl_list_remove(&group->link); wlr_keyboard_group_destroy(group->wlr_group); wl_event_source_remove(group->key_repeat_timer); + if(group->identifier) { + free(group->identifier); + } free(group); } @@ -865,6 +921,7 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) { return NULL; } + seat->enable_cursor = true; seat->seat = wlr_seat_create(server->wl_display, "seat0"); if(!seat->seat) { wlr_log(WLR_ERROR, "Cannot allocate seat0"); @@ -885,7 +942,8 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) { wlr_cursor_attach_output_layout(seat->cursor, server->output_layout); if(!seat->xcursor_manager) { - seat->xcursor_manager = wlr_xcursor_manager_create(NULL, XCURSOR_SIZE); + seat->xcursor_manager = + wlr_xcursor_manager_create(NULL, server->xcursor_size); if(!seat->xcursor_manager) { wlr_log(WLR_ERROR, "Cannot create XCursor manager"); wlr_cursor_destroy(seat->cursor); @@ -971,8 +1029,10 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { /* Focusing the background */ if(view == NULL) { - server->curr_output->workspaces[server->curr_output->curr_workspace] - ->focused_tile->view = NULL; + workspace_tile_update_view( + server->curr_output->workspaces[server->curr_output->curr_workspace] + ->focused_tile, + NULL); seat->focused_view = NULL; if(prev_view != NULL) { view_activate(prev_view, false); @@ -985,24 +1045,18 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { if(view->type != CG_XWAYLAND_VIEW || xwayland_view_should_manage(view)) #endif { - /* Always resize the view, even if prev_view == view */ struct cg_workspace *curr_workspace = server->curr_output ->workspaces[server->curr_output->curr_workspace]; - view_maximize(view, curr_workspace->focused_tile); - if(!view_is_visible(view)) { - wl_list_remove(&view->link); - if(curr_workspace->focused_tile->view != NULL) { - wl_list_insert(&curr_workspace->focused_tile->view->link, - &view->link); - } else { - wl_list_insert(curr_workspace->views.prev, &view->link); - } - curr_workspace->focused_tile->view = view; - } + workspace_tile_update_view(curr_workspace->focused_tile, view); + wl_list_remove(&curr_workspace->views); + wl_list_insert(&view->link, &curr_workspace->views); } #if CG_HAS_XWAYLAND + if(view->type == CG_XWAYLAND_VIEW) { + wlr_xwayland_set_seat(server->xwayland, seat->seat); + } if(view->type == CG_XWAYLAND_VIEW && !xwayland_view_should_manage(view)) { const struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); @@ -1021,10 +1075,6 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { } view_activate(view, true); - char *title = view_get_title(view); - - output_set_window_title(server->curr_output, title); - free(title); struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(wlr_seat); wlr_seat_keyboard_end_grab(wlr_seat); @@ -1037,5 +1087,11 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { NULL); } + wlr_scene_node_raise_to_top(&view->scene_tree->node); process_cursor_motion(seat, -1); + struct wlr_box box; + wlr_output_layout_get_box(server->output_layout, + view->workspace->output->wlr_output, &box); + wlr_scene_node_set_position(&view->workspace->output->bg->node, box.x, + box.y); } diff --git a/seat.h b/seat.h index 9331042..e44d808 100644 --- a/seat.h +++ b/seat.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_SEAT_H #define CG_SEAT_H @@ -11,6 +14,8 @@ struct cg_input_device; struct wlr_seat; struct wlr_xcursor_manager; struct wlr_backend; +struct wlr_surface; +struct cg_input_config; #define DEFAULT_XCURSOR "left_ptr" #define XCURSOR_SIZE 24 @@ -26,7 +31,9 @@ struct cg_seat { uint16_t num_pointers; uint16_t num_touch; + bool enable_cursor; struct wlr_cursor *cursor; + struct cg_tile *cursor_tile; struct wlr_xcursor_manager *xcursor_manager; struct wl_listener cursor_motion; struct wl_listener cursor_motion_absolute; @@ -60,6 +67,8 @@ struct cg_seat { struct cg_keyboard_group { struct wlr_keyboard_group *wlr_group; struct cg_seat *seat; + char *identifier; + int enable_keybindings; struct wl_listener key; struct wl_listener modifiers; @@ -85,6 +94,7 @@ struct cg_drag_icon { struct wl_list link; // seat::drag_icons struct cg_seat *seat; struct wlr_drag_icon *wlr_drag_icon; + struct wlr_scene_tree *scene_tree; /* The drag icon has a position in layout coordinates. */ double lx, ly; @@ -104,5 +114,4 @@ void seat_add_device(struct cg_seat *seat, struct cg_input_device *device); void seat_remove_device(struct cg_seat *seat, struct cg_input_device *device); - #endif diff --git a/server.c b/server.c index e554a3c..292d0b0 100644 --- a/server.c +++ b/server.c @@ -25,7 +25,6 @@ display_terminate(struct cg_server *server) { if(server == NULL) { return; } - server->running = false; wl_display_terminate(server->wl_display); } @@ -58,14 +57,15 @@ server_show_info(struct cg_server *server) { struct cg_input_device *input; wl_list_for_each(input, &server->input->devices, link) { if(!input_str) { + free(output_str); return NULL; } input_str_tmp = input_str; if(strcmp(input->identifier, "") != 0) { input_str = malloc_vsprintf("%s\t * %s\n", input_str, input->identifier); + free(input_str_tmp); } - free(input_str_tmp); } char *ret = malloc_vsprintf("Outputs:\n%sInputs:\n%s", output_str, input_str); diff --git a/server.h b/server.h index a5139f6..39d26f4 100644 --- a/server.h +++ b/server.h @@ -23,8 +23,6 @@ struct cg_server { struct cg_seat *seat; struct cg_input_manager *input; struct wlr_backend *backend; - struct wlr_renderer *renderer; - struct wlr_allocator *allocator; struct wlr_idle *idle; struct wlr_idle_inhibit_manager_v1 *idle_inhibit_v1; struct wl_listener new_idle_inhibitor_v1; @@ -35,11 +33,17 @@ struct cg_server { struct wl_list outputs; struct cg_output *curr_output; struct wl_listener new_output; + struct wl_list output_priorities; + + struct wlr_renderer *renderer; + struct wlr_allocator *allocator; + struct wlr_scene *scene; struct wl_listener xdg_toplevel_decoration; struct wl_listener new_xdg_shell_surface; #if CG_HAS_XWAYLAND struct wl_listener new_xwayland_surface; + struct wlr_xwayland *xwayland; #endif struct keybinding_list *keybindings; @@ -47,18 +51,16 @@ struct cg_server { struct wl_list input_config; struct cg_message_config message_config; - enum wl_output_transform output_transform; - struct cg_ipc_handle ipc; + bool enable_socket; bool running; char **modes; uint16_t nws; - uint16_t message_timeout; float *bg_color; -#ifdef DEBUG - bool debug_damage_tracking; -#endif + uint32_t views_curr_id; + uint32_t tiles_curr_id; + uint32_t xcursor_size; }; void diff --git a/signatures/1.9.1-cagebreak-config.sig b/signatures/1.9.1-cagebreak-config.sig new file mode 100644 index 0000000000000000000000000000000000000000..7349ebcab4fa32168646d48f892bcd5596a3192f GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%GJlF#rk)5TM6H zgo9>tYPA>a(B~!^>{#QM`;&Ks#9hY(iZU4k8V6+u7a|13x%(-a?xh zLZT+17sI6;Yl3Skve`me;ImzqMO%Nfz*_*j=t~S|@K%n0#0NbXgkj#=x5*t~E*td> zNsM2jL{#={Bdk~eU_)i&_fvD~)?ev)>^6K7LzObD45@&;A})&qQ@XPnzCINxvO<-* zySrj>7^!e`*Lhscg7zUkdY|RmIVN4{I&Y1nI3Z&s9wXm-)?w`T$TD7wS9-*n2Ih8f z7n87;Q?0k}@?xs0ERWIHqsFuyTyY*{aUC%woI;%z)|TCJTe)&s2`moz3V$2xSc%j7 zvnbt(W;`v}rVnBu2lRdjuw69ser;oE0!icWuHt>9l)6xjE$X=uzfI6;iT{2}M8AY& zN8^@X)bFtcg{lXgR8lKqAEmGmuW==XG;gd&N@P^`3QO02-OK2kOH|?%qrzo)?b=h- zLh29(45Y1EW*LgG2ZUJRpB;GzT&+AoDqtJK&?b#Fz!dA3T=Q*~6g{~PAu|j%4q>qt zPQv)iwo%o;{K47J($(o$abbd_zvjg|)+SN8uc~J{bP<+f7PT!o81aUMd)X(zx~6zV EzrwKw%m4rY literal 0 HcmV?d00001 diff --git a/signatures/1.9.1-cagebreak.1.sig b/signatures/1.9.1-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..e0a399bb986388fd35276fee09dbbf5ccac80832 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%GJlIRFX?5TM6H zgo|>`7|>GzW7G(eSg*~ zfTkz5Du3Oxjr6A1SZMx6YqzyeL8>)${n*zq2@$+z+J;KQM4^NB5B3)kO z>RmD9m{g=l-qrqVTr{j0XbFR{36~j$KY4j1xz41Oo2Vj~id<#<^pP=9l77((z>Y}f z+Nlu;%gUVse4ClfeV!n)#wmm|emr9DTr%OD;}Dvw8xOoAOJF9LFR%^=fB^LWYSLm@ z7qV{#W4*=i8c$wEVN;|H6Xg7@17m+ztOd1C-(Gr?7qs#$<$N;tVtSq_R4^uk*y;#v EW5~}ALjV8( literal 0 HcmV?d00001 diff --git a/signatures/1.9.1-cagebreak.sig b/signatures/1.9.1-cagebreak.sig new file mode 100644 index 0000000000000000000000000000000000000000..1813ed2426494a05f625ea4b7e3ab605ed4f8601 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%GJlH2?|;5TM6H zgo9ROudEg(73sF&{gAji%Mu!6xkWxIWi z-X<6Kgywn!hlTI#HRgK1`mwQd$H+9}mG=U&vNudZ*V%%pxZlNm488bpS@LB`3Iwz5 zQfkURVaPvFZA7GjUH&*>tqqgYtYQ0R1yz8m6XN(Oav;*5?Hp@THH2QuS*CNSqsVA~rE25)((-C@m%&1q>FB6Hq+*7!hLQ7L-+aLe)L5=S@ z$}y!zJmcmxsze_~47z#*o3tIBtDYb{+^mM!!_Dn;NVQi9%kp2?o0 z;h~`W_|OhSJ+%VWaWW;tck(^G zYhYe|dhWE0y_I%{W=xhBVuv;ixd=11gw)#^XtEH=c<`aXy*w(q)v5d$L(FlsEnd%m_B1OJ9|G zY+G(nU5L4jyR49Qq0+4q-T5>j0WD1rAO@3Vl5v+30OlLqNij*hoj~ECUMrZkGFI}X E$89nRGynhq literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index 7349ebcab4fa32168646d48f892bcd5596a3192f..0e839de1d6a4029c6b1906c9b74962341d1add5f 100644 GIT binary patch delta 543 zcmV+)0^t3&1hxc_B7bAMFjW8w2@s&iLxhTBiB$yI5C3TFTqwb9Ki}LpPi*fLRb5H1 zvac3^UBA@Q>V*g>Sy+c~ZYJPe;2%icduM2=ZCpUKiGi+%-Y_)ax-qjxOo zq6>!{+qCvC$n=I!VGiUy_Kv7qMDAD76Y>Z9A^SZ|3G>CD`G0ZlB~PxHYJfzPlFA)(3`EYRhr{CN4KHkJrUF;l|Z=jV#O4tH032lNT}+^Fx`cZ!~0A zZ_hmik$O{Sw|$G~w|NnsMeWfjr6m#Aq3t;a6tX4VNm7BwD%7j*JOSUtOGy5z4szY{ z0dV$QkUy`z8h>f|+|8lql6*k2E&Jl}bP*6S;BJhV++xYzq1p`KCDOd1gj}w#^ONc( zlrsLhNjf8ff-5~@w7ykjN59t?Bqgj8HEzSo2e{92L??nPk@|LHu~uTo7aBnmT_Q~e z=$T&kQ|su|58pow=6|PunNu)C$1u5po!I)nYJZlM{C_HE9)z0kM}k45Z8dji9bL_r ziL4a>UFDl@2~vN)41xxj>0Wkv89j=;{oGKX^A~tQ>S74ILHP>WV@`i(UJnzI_6ghU zGvSviq^gF9-;B}ZwsE4*kBy9-<)XZK{!@-*&hgGuZ9r%P+u`LAa@MFpzhROnVSl9{ hsv$bv!x-`~Zv;-NFU=S$l8pQwI)z=^;i1$CI#S6`5aj>> delta 543 zcmV+)0^t3&1hxc_B7b7!J23zX2@s&iLxhTBiB)A$5CD_%RyBr2k!jrc>_N3Qrn zd=f*IGOP@#fV?6uivv@-vl_lW6)CbpmAbpTVsRL$aC6srT+M>^AwGJa<=QzWUFkY+ zjifjsVUdc>Lr=5}xwldzXlt+(&;VydbvkI~qp#JT2I!4`Lt(^nM7iT{QE4ZDVNy zN#pRY;(er)x=@WR>bViWP0(tI|9(qEzl3B*qtPQv)iwo%o;{K47J($(o$abbd_zvjg| h)+SN8uNbOlI&=}1VivV6IT-PVg?rg2z`CY*MZew(0Q~>} diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..6c5048b79c2991fa9f1d0e86234926ebacf415f9 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N-{SpW(N5TM6H zgo@`h?n#LyK;!8^ONVafw0hZ759^be#Y5vvgbS%8( zr6n3>4_q-c_!#_23y|DeU*kv5#txLZxT816ne-fd-!;@V;T)X~gqMQ{iX%R67+OZ_ zI`x>h8*Sip|C8?buduzg8~y&`13b(lX32~JcTXu(TM$EK5w8pCL~ymwj?-6S)3yQ^ zB*#VzH%Kmu$?vl9b~bh7$E4ik!qrRt$Ed4TMQN}|OR6HW?UYr*g7DUnhJMgBw;nM* z1>Y0>*+l8s3*`{~IuLZXCSx|G<46>Ui8}k4@w0lPHpzL@@HTt9xFCK2;ANwxC`qm- zWjihvK~{&;PJ11k>O7vH*!jup2amsEe-67?M@iEJ1yQ=4ZQ%9d->9I;7X~(e5o?4y zPz7~!Orl)9PT|fOh`DE5V3_3~g3U@K`&jwfN_lbvSoDS4|7>tfbJbo97H7iFZAB`% z5U31S9^%K6x>%xCS((x^bfuuSTMjPZOQ+J!`*!ce7GUO z?As)9nZcoKyA>hlqBPC+$qBrL$?4S7HT$MGCAy3F?Ir8Z6hS>oQjwU<$y--2)xBBg zfKT`j8tN|YtvSI(xo}IO?>#DuJbdcngI4H~7WO^9Fd2xhI`RoId;=@YV5|dvbu@V1 EVY~ho;{X5v literal 0 HcmV?d00001 diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index e0a399bb986388fd35276fee09dbbf5ccac80832..3dfee2837dfb06f16aeb167a6ad00914d94a8ed8 100644 GIT binary patch delta 543 zcmV+)0^t3&1hxc_B7bAMFi-#r2@s&iLxhTBiB*>o5C3*G;_yuX=QbNI>wWbf;)=1j zo`_sXJfKg~LxkjcK2|gO@w(3t7D2fz$4FxmgqPdmLAK^p=Ut4cKto=)(C@X9jgNO0 z)aZ@0$fE^zeS@aY(ChcRo+90j;`2*SUd5g($W)9b7WjRqgMXQ7XT>a!Vyi|qy%J}} zn8W{>yZ5z6sm1~6hjbltL)R0afGVZzS8Iy$REgPr$@A&>1V8Kua9un+@!OYd`CJbl zfV2{f6TOwO=+Bo{F7U)}iYX9O;G{r%Qa#Mx$RoI0LS01r79>goe$xC5rDK_%+mN_R zRIAXfa|?yz9)Aa=LK$>VoSDpS9nb;?HncTuFe5#w9^UTC3Fg4xT0))>f^nGv1>5Jc zlc>$*36Gn8epysrROb;f%5#&9>!%P2kjR9x+W&VcdM0=BX?z$}-Tk?Um?cJa?|kMG zJ)Dws2n8H}|GDO+{Da!A1Bd$9NggHZ}3ILXX`N{g=8+J_HN1azWvA-$!xv$D{& h1B>8w&=?UmXiALLW{}eU!ULXWLCw+HcEAhM3uxUz6C(fs delta 543 zcmV+)0^t3&1hxc_B7b7!J2?Of2@s&iLxhTBiB$;Z5C3CIiYi}VZUk@rlFi%(5Z+s9 z;7*dSC%qB30#iT|^DEQjml6wdbH!J18V_hGA=&?v1+8xU-KTK-aDDk1|2K)t9w0t4 z@j>J+rfBQ1s`5%QHaGZ?5x9L#?4k)qBzAmpsg2!!V4@cdT7O@S(o33~m1+f{XBk^r zS6yol`ot%o&PYy2aUqAh@3P`si3(|47U2AnMxW30zY}f+Nlu;%gUVse4ClfeV!n)#wmm|emr9D zTr%OD;}Dvw8xOoAOJF9LFR%^=fB^LWYSLm@7qV{#W4*=i8c$wEVN;|H6Xg7@17m+z htOd1C-xywclNYq|EaiMM_hNdUDO4~fgV^c_ZDao^2y_4d diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 1813ed2426494a05f625ea4b7e3ab605ed4f8601..93517d0a5f58e4bcf66f09efccfcb8761670e9f0 100644 GIT binary patch delta 543 zcmV+)0^t3&1hxc_B7bAMFiZdn2@s&iLxhTBiB-XN5CEbD?kEzR4=bDqnBJ9d-G8X< z7noaHb@4b^Ejf~{H*ZK2Hfz>its(dZ<9(TxI`D||g~_`q6?(VP&I;_aXYnzEVm7=o zn{M!|EHe)bvjU#x5Miae)dDN0WhRy}`L19+QGsFtXSi~F_kWc*;{Z|T@JYtBFt1Ut ze3tP1ic<@=bXE|tFjb@O^@j>Qv6WvI^^WnC@-WB;Dz3m!*2DUX8&N4z<{JZD~aiCN5^sx9~MxcE=Iqs zf1H`We4FM6f`4s3vn-m(X=THfsc8;$G))sWg=etoxMdq!V=q%DJW!h(CAiuIRJ(XD z{FW=tIhg$B#!s;h$LmArjjt06H65ts#YOZrFj49!lhxYubf$=ik@!S;R}ONM=skK6Yjyb&Kq$nr-{b+x zY=cKV$th1ir4hb6?9Lf6k3y(_%5azjqq~UcP2f;<^+*2)PIG+ZO)Wo>H+A)SD85>g zw_hk(P4oeW@SZjvNW-0{+~+(hZ~p hNcuxxAQ(mv+VW-^oa-L%m^QMExNP*R*$BgmdKqx72l)U1 delta 543 zcmV+)0^t3&1hxc_B7b7!J2e0b2@s&iLxhTBiB*Cs5C2kfzEETm2p)N&+?5zZ;sYvI z>(v1V8)TJp6_9YKfvX(fGnEZoE`tj6jZ)Xj)7`G$8by96F$1pq)aK^MW-RWH+E7tgj!0WC$a@+dU=ei_#y$#AJBvRo^oqkPj5 zdV9>MSJN*OiGRJ^Q@EExOH*dsAOG_~jqf?iF{MU4(ns*#bf*k6}^lNN)|m zA*On(%6D{YEnQfaE%ZSuMc^b-g5G+b$)2O(p`j$HfO9@KKJ{xZlvR1f#Pmh!3g4Kz zegm<3WUCku0y)(9&<;dBwF1>~G9|-z@;$w4U|xNC?tiq5y_I%{W=xhBVuv;ixd=11gw)#^XtE zH=c<`aXy*w(q)v5d$L(FlsEnd%m_B1OJ9|GY+G(nU5L4jyR49Qq0+4q-T5>j0WD1r hAO@3Vk{EH95&-5K+(|J>yq!Sdp #include "util.h" +#include #include int diff --git a/util.h b/util.h index 01e403e..ef3f532 100644 --- a/util.h +++ b/util.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_UTIL_H #define CG_UTIL_H diff --git a/view.c b/view.c index 0bbd03b..74c31b8 100644 --- a/view.c +++ b/view.c @@ -1,11 +1,5 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -15,9 +9,11 @@ #include #include #include -#include +#include +#include #include +#include "ipc_server.h" #include "output.h" #include "seat.h" #include "server.h" @@ -49,127 +45,6 @@ view_get_prev_view(struct cg_view *view) { return prev; } -void -view_damage_child(struct cg_view_child *child, bool whole) { - if(child->view != NULL) { - view_damage_part(child->view); - } -} - -static void -view_child_handle_commit(struct wl_listener *listener, void *_data) { - struct cg_view_child *child = wl_container_of(listener, child, commit); - view_damage_child(child, false); -} - -static void -subsurface_create(struct cg_view_child *parent, struct cg_view *view, - struct wlr_subsurface *wlr_subsurface); - -static void -view_child_handle_new_subsurface(struct wl_listener *listener, void *data) { - struct cg_view_child *child = - wl_container_of(listener, child, new_subsurface); - struct wlr_subsurface *wlr_subsurface = data; - subsurface_create(child, child->view, wlr_subsurface); -} - -void -view_child_finish(struct cg_view_child *child) { - if(!child) { - return; - } - - if(child->view != NULL) { - view_damage_child(child, true); - } - - struct cg_view_child *subchild, *tmpchild; - wl_list_for_each_safe(subchild, tmpchild, &child->children, parent_link) { - subchild->parent = NULL; - wl_list_remove(&subchild->parent_link); - } - - wl_list_remove(&child->link); - if(child->parent != NULL) { - wl_list_remove(&child->parent_link); - } - wl_list_remove(&child->commit.link); - wl_list_remove(&child->new_subsurface.link); -} - -void -view_child_init(struct cg_view_child *child, struct cg_view_child *parent, - struct cg_view *view, struct wlr_surface *wlr_surface) { - child->view = view; - child->parent = parent; - if(parent != NULL) { - wl_list_insert(&parent->children, &child->parent_link); - } - child->wlr_surface = wlr_surface; - wl_list_init(&child->children); - - child->commit.notify = view_child_handle_commit; - wl_signal_add(&wlr_surface->events.commit, &child->commit); - child->new_subsurface.notify = view_child_handle_new_subsurface; - wl_signal_add(&wlr_surface->events.new_subsurface, &child->new_subsurface); - - wl_list_insert(&view->children, &child->link); -} - -static void -subsurface_destroy(struct cg_view_child *child) { - if(!child) { - return; - } - - struct cg_subsurface *subsurface = (struct cg_subsurface *)child; - wl_list_remove(&subsurface->destroy.link); - view_child_finish(&subsurface->view_child); - free(subsurface); -} - -static void -subsurface_handle_destroy(struct wl_listener *listener, void *_data) { - struct cg_subsurface *subsurface = - wl_container_of(listener, subsurface, destroy); - struct cg_view_child *view_child = (struct cg_view_child *)subsurface; - subsurface_destroy(view_child); -} - -static void -subsurface_create(struct cg_view_child *parent, struct cg_view *view, - struct wlr_subsurface *wlr_subsurface) { - struct cg_subsurface *subsurface = calloc(1, sizeof(struct cg_subsurface)); - if(!subsurface) { - return; - } - - view_child_init(&subsurface->view_child, parent, view, - wlr_subsurface->surface); - subsurface->view_child.destroy = subsurface_destroy; - subsurface->wlr_subsurface = wlr_subsurface; - - subsurface->destroy.notify = subsurface_handle_destroy; - wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); -} - -static void -handle_new_subsurface(struct wl_listener *listener, void *data) { - struct cg_view *view = wl_container_of(listener, view, new_subsurface); - struct wlr_subsurface *wlr_subsurface = data; - subsurface_create(NULL, view, wlr_subsurface); -} - -char * -view_get_title(const struct cg_view *view) { - const char *title = view->impl->get_title(view); - if(!title) { - return NULL; - } - return strndup(title, strlen(title)); -} - bool view_is_primary(const struct cg_view *view) { return view->impl->is_primary(view); @@ -195,28 +70,6 @@ view_is_visible(const struct cg_view *view) { return view_get_tile(view) != NULL; } -void -view_damage(struct cg_view *view, bool whole) { - struct cg_tile *view_tile = view_get_tile(view); - if(view_tile != NULL && - (view->wlr_surface->current.width != view_tile->tile.width || - view->wlr_surface->current.height != view_tile->tile.height)) { - view_maximize(view, view_tile); - } - output_damage_surface(view->workspace->output, view->wlr_surface, view->ox, - view->oy, whole); -} - -void -view_damage_part(struct cg_view *view) { - view_damage(view, false); -} - -void -view_damage_whole(struct cg_view *view) { - view_damage(view, true); -} - void view_activate(struct cg_view *view, bool activate) { if(view != NULL) { @@ -228,45 +81,42 @@ void view_maximize(struct cg_view *view, struct cg_tile *tile) { view->ox = tile->tile.x; view->oy = tile->tile.y; + struct wlr_box box; + wlr_output_layout_get_box(view->server->output_layout, + view->workspace->output->wlr_output, &box); + wlr_scene_node_set_position(&view->scene_tree->node, view->ox + box.x, + view->oy + box.y); view->impl->maximize(view, tile->tile.width, tile->tile.height); view->tile = tile; -} - -void -view_for_each_surface(struct cg_view *view, - wlr_surface_iterator_func_t iterator, void *data) { - view->impl->for_each_surface(view, iterator, data); -} - -void -view_for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, - void *data) { - if(!view->impl->for_each_popup) { - return; - } - view->impl->for_each_popup(view, iterator, data); + wlr_scene_node_raise_to_top(&view->scene_tree->node); } void view_unmap(struct cg_view *view) { + + uint32_t id = view->id; + uint32_t tile_id = 0; + uint32_t ws = view->workspace->num; + char *output_name = view->workspace->output->wlr_output->name; + int output_id = output_get_num(view->workspace->output); + pid_t pid = view->impl->get_pid(view); /* If the view is not mapped, do nothing */ if(view->wlr_surface == NULL) { return; } - struct cg_view_child *child, *tmp; - wl_list_for_each_safe(child, tmp, &view->children, link) { - child->destroy(child); + if(view->tile == NULL) { + tile_id = -1; + } else { + tile_id = view->tile->id; } + + wlr_scene_node_destroy(&view->scene_tree->node); + #if CG_HAS_XWAYLAND if((view->type != CG_XWAYLAND_VIEW || xwayland_view_should_manage(view))) #endif { - struct cg_tile *view_tile = view_get_tile(view); - if(view_tile != NULL) { - wlr_output_damage_add_box(view_tile->workspace->output->damage, - &view_tile->tile); - } struct cg_view *prev = view_get_prev_view(view); if(view == view->server->seat->focused_view) { seat_set_focus(view->server->seat, prev); @@ -276,19 +126,13 @@ view_unmap(struct cg_view *view) { seat_set_focus(view->server->seat, view->server->seat->focused_view); } - view_tile = view_get_tile(view); + struct cg_tile *view_tile = view_get_tile(view); if(view_tile != NULL) { - wlr_output_damage_add_box(view_tile->workspace->output->damage, - &view_tile->tile); - view_tile->view = prev; - if(prev != NULL) { - view_maximize(prev, view_tile); - } + workspace_tile_update_view(view_tile, prev); } } #if CG_HAS_XWAYLAND else { - view_damage_whole(view); if(view->server->seat->seat->keyboard_state.focused_surface == NULL || view->server->seat->seat->keyboard_state.focused_surface == view->wlr_surface) { @@ -300,8 +144,12 @@ view_unmap(struct cg_view *view) { wl_list_remove(&view->link); - wl_list_remove(&view->new_subsurface.link); view->wlr_surface = NULL; + ipc_send_event( + view->workspace->server, + "{\"event_name\":\"view_unmap\",\"view_id\":%d,\"tile_id\":%d," + "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d,\"view_pid\":%d}", + id, tile_id, ws + 1, output_name, output_id, pid); } void @@ -310,21 +158,12 @@ view_map(struct cg_view *view, struct wlr_surface *surface, struct cg_output *output = ws->output; view->wlr_surface = surface; - struct wlr_subsurface *subsurface; - wl_list_for_each(subsurface, &view->wlr_surface->current.subsurfaces_above, - current.link) { - subsurface_create(NULL, view, subsurface); + view->scene_tree = wlr_scene_subsurface_tree_create(ws->scene, surface); + if(!view->scene_tree) { + wl_resource_post_no_memory(surface->resource); + return; } - - wl_list_for_each(subsurface, &view->wlr_surface->current.subsurfaces_below, - current.link) { - subsurface_create(NULL, view, subsurface); - } - - view->new_subsurface.notify = handle_new_subsurface; - wl_signal_add(&view->wlr_surface->events.new_subsurface, - &view->new_subsurface); - + view->scene_tree->node.data = view; view->workspace = ws; #if CG_HAS_XWAYLAND @@ -332,14 +171,30 @@ view_map(struct cg_view *view, struct wlr_surface *surface, their own (x,y) coordinates in handle_wayland_surface_map. */ if(view->type == CG_XWAYLAND_VIEW && !xwayland_view_should_manage(view)) { wl_list_insert(&ws->unmanaged_views, &view->link); + struct wlr_box box; + wlr_output_layout_get_box(view->server->output_layout, + view->workspace->output->wlr_output, &box); + wlr_scene_node_set_position(&view->scene_tree->node, view->ox + box.x, + view->oy + box.y); } else #endif { - view->tile = view->workspace->focused_tile; - view_maximize(view, view->tile); wl_list_insert(&ws->views, &view->link); } seat_set_focus(output->server->seat, view); + int tile_id = 0; + if(view->tile == NULL) { + tile_id = -1; + } else { + tile_id = view->tile->id; + } + ipc_send_event( + output->server, + "{\"event_name\":\"view_map\",\"view_id\":%d,\"tile_id\":%d," + "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d,\"view_pid\":%d}", + view->id, tile_id, view->workspace->num + 1, + view->workspace->output->wlr_output->name, + output_get_num(view->workspace->output), view->impl->get_pid(view)); } void @@ -363,12 +218,6 @@ view_init(struct cg_view *view, enum cg_view_type type, view->server = server; view->type = type; view->impl = impl; - - wl_list_init(&view->children); -} - -struct wlr_surface * -view_wlr_surface_at(const struct cg_view *view, double sx, double sy, - double *sub_x, double *sub_y) { - return view->impl->wlr_surface_at(view, sx, sy, sub_x, sub_y); + view->id = server->views_curr_id; + ++server->views_curr_id; } diff --git a/view.h b/view.h index 62a1f32..99e3e65 100644 --- a/view.h +++ b/view.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_VIEW_H #define CG_VIEW_H @@ -5,7 +8,7 @@ #include #include -#include +#include struct cg_server; struct wlr_box; @@ -20,10 +23,10 @@ enum cg_view_type { struct cg_view { struct cg_workspace *workspace; struct cg_server *server; - struct wl_list link; // server::views - struct wl_list children; // cg_view_child::link + struct wl_list link; // server::views struct wlr_surface *wlr_surface; struct cg_tile *tile; + struct wlr_scene_tree *scene_tree; /* The view has a position in output coordinates. */ int ox, oy; @@ -31,48 +34,18 @@ struct cg_view { enum cg_view_type type; const struct cg_view_impl *impl; - struct wl_listener new_subsurface; + uint32_t id; }; struct cg_view_impl { - char *(*get_title)(const struct cg_view *view); + pid_t (*get_pid)(const struct cg_view *view); bool (*is_primary)(const struct cg_view *view); void (*activate)(struct cg_view *view, bool activate); void (*close)(struct cg_view *view); void (*maximize)(struct cg_view *view, int width, int height); void (*destroy)(struct cg_view *view); - void (*for_each_surface)(struct cg_view *view, - wlr_surface_iterator_func_t iterator, void *data); - void (*for_each_popup)(struct cg_view *view, - wlr_surface_iterator_func_t iterator, void *data); - struct wlr_surface *(*wlr_surface_at)(const struct cg_view *view, double sx, - double sy, double *sub_x, - double *sub_y); }; -struct cg_view_child { - struct cg_view *view; - struct cg_view_child *parent; - struct wl_list children; - struct wlr_surface *wlr_surface; - struct wl_list link; - struct wl_list parent_link; - - struct wl_listener commit; - struct wl_listener new_subsurface; - - void (*destroy)(struct cg_view_child *child); -}; - -struct cg_subsurface { - struct cg_view_child view_child; - struct wlr_subsurface *wlr_subsurface; - - struct wl_listener destroy; -}; - -char * -view_get_title(const struct cg_view *view); struct cg_tile * view_get_tile(const struct cg_view *view); bool @@ -80,20 +53,8 @@ view_is_primary(const struct cg_view *view); bool view_is_visible(const struct cg_view *view); void -view_damage_part(struct cg_view *view); -void -view_damage_whole(struct cg_view *view); -void -view_damage_child(struct cg_view_child *view, bool whole); -void view_activate(struct cg_view *view, bool activate); void -view_for_each_surface(struct cg_view *view, - wlr_surface_iterator_func_t iterator, void *data); -void -view_for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, - void *data); -void view_unmap(struct cg_view *view); void view_maximize(struct cg_view *view, struct cg_tile *tile); @@ -105,16 +66,6 @@ view_destroy(struct cg_view *view); void view_init(struct cg_view *view, enum cg_view_type type, const struct cg_view_impl *impl, struct cg_server *server); - -struct wlr_surface * -view_wlr_surface_at(const struct cg_view *view, double sx, double sy, - double *sub_x, double *sub_y); - -void -view_child_finish(struct cg_view_child *child); -void -view_child_init(struct cg_view_child *child, struct cg_view_child *parent, - struct cg_view *view, struct wlr_surface *wlr_surface); struct cg_view * view_get_prev_view(struct cg_view *view); diff --git a/workspace.c b/workspace.c index 1b701e8..1caff0d 100644 --- a/workspace.c +++ b/workspace.c @@ -1,24 +1,34 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2019 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200809L #include #include #include +#include #include #include "message.h" #include "output.h" +#include "seat.h" #include "server.h" +#include "view.h" #include "workspace.h" +void +workspace_tile_update_view(struct cg_tile *tile, struct cg_view *view) { + if(tile->view != NULL) { + wlr_scene_node_set_enabled(&tile->view->scene_tree->node, false); + tile->view->tile = NULL; + } + tile->view = view; + if(view != NULL) { + view_maximize(view, tile); + wlr_scene_node_set_enabled(&view->scene_tree->node, true); + } +} + #if CG_HAS_FANALYZE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" @@ -26,7 +36,8 @@ int full_screen_workspace_tiles(struct wlr_output_layout *layout, struct wlr_output *output, - struct cg_workspace *workspace) { + struct cg_workspace *workspace, + uint32_t *tiles_curr_id) { workspace->focused_tile = calloc(1, sizeof(struct cg_tile)); if(!workspace->focused_tile) { return -1; @@ -36,10 +47,13 @@ full_screen_workspace_tiles(struct wlr_output_layout *layout, workspace->focused_tile->prev = workspace->focused_tile; workspace->focused_tile->tile.x = 0; workspace->focused_tile->tile.y = 0; - struct wlr_box *output_box = wlr_output_layout_get_box(layout, output); - workspace->focused_tile->tile.width = output_box->width; - workspace->focused_tile->tile.height = output_box->height; - workspace->focused_tile->view = NULL; + struct wlr_box output_box; + wlr_output_layout_get_box(layout, output, &output_box); + workspace->focused_tile->tile.width = output_box.width; + workspace->focused_tile->tile.height = output_box.height; + workspace_tile_update_view(workspace->focused_tile, NULL); + workspace->focused_tile->id = *tiles_curr_id; + ++(*tiles_curr_id); return 0; } #if CG_HAS_FANALYZE @@ -52,9 +66,18 @@ full_screen_workspace(struct cg_output *output) { if(!workspace) { return NULL; } + struct wlr_scene_output *scene_output = + wlr_scene_get_scene_output(output->server->scene, output->wlr_output); + if(scene_output == NULL) { + free(workspace); + return NULL; + } workspace->server = output->server; + workspace->num = -1; + workspace->scene = wlr_scene_tree_create(&scene_output->scene->tree); if(full_screen_workspace_tiles(output->server->output_layout, - output->wlr_output, workspace) != 0) { + output->wlr_output, workspace, + &output->server->tiles_curr_id) != 0) { free(workspace); return NULL; } @@ -72,13 +95,18 @@ workspace_focus_tile(struct cg_workspace *ws, struct cg_tile *tile) { } box->x = tile->tile.x + tile->tile.width / 2; box->y = tile->tile.y + tile->tile.height / 2; - message_printf_pos(ws->output, box, CG_MESSAGE_CENTER, "Current frame"); + message_printf_pos(ws->output, box, CG_MESSAGE_CENTER, "Current tile"); } void workspace_free_tiles(struct cg_workspace *workspace) { workspace->focused_tile->prev->next = NULL; while(workspace->focused_tile != NULL) { + if(workspace->output->server->running && + workspace->output->server->seat->cursor_tile == + workspace->focused_tile) { + workspace->output->server->seat->cursor_tile = NULL; + } struct cg_tile *next = workspace->focused_tile->next; free(workspace->focused_tile); workspace->focused_tile = next; @@ -90,3 +118,19 @@ workspace_free(struct cg_workspace *workspace) { workspace_free_tiles(workspace); free(workspace); } + +void +workspace_focus(struct cg_output *outp, int ws) { + if(ws >= outp->server->nws) { + wlr_log(WLR_ERROR, + "Attempt to focus workspace %d, but only %d workspaces are " + "available.", + ws, outp->server->nws); + return; + } + wlr_scene_node_place_above( + &outp->bg->node, &outp->workspaces[outp->curr_workspace]->scene->node); + wlr_scene_node_place_above(&outp->workspaces[ws]->scene->node, + &outp->bg->node); + outp->curr_workspace = ws; +} diff --git a/workspace.h b/workspace.h index 0e8f91f..e0f2473 100644 --- a/workspace.h +++ b/workspace.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_WORKSPACE_H #define CG_WORKSPACE_H @@ -12,6 +15,7 @@ struct cg_tile { struct cg_view *view; struct cg_tile *next; struct cg_tile *prev; + uint32_t id; }; struct cg_workspace { @@ -19,8 +23,10 @@ struct cg_workspace { struct wl_list views; struct wl_list unmanaged_views; struct cg_output *output; + struct wlr_scene_tree *scene; struct cg_tile *focused_tile; + uint32_t num; }; struct cg_workspace * @@ -28,12 +34,17 @@ full_screen_workspace(struct cg_output *output); int full_screen_workspace_tiles(struct wlr_output_layout *layout, struct wlr_output *output, - struct cg_workspace *workspace); + struct cg_workspace *workspace, + uint32_t *tiles_curr_id); void workspace_free_tiles(struct cg_workspace *workspace); void workspace_free(struct cg_workspace *workspace); void workspace_focus_tile(struct cg_workspace *ws, struct cg_tile *tile); +void +workspace_focus(struct cg_output *outp, int ws); +void +workspace_tile_update_view(struct cg_tile *tile, struct cg_view *view); #endif diff --git a/xdg_shell.c b/xdg_shell.c index 6b9b074..fc251c7 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -1,17 +1,13 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2019 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT #define _POSIX_C_SOURCE 200809L +#include #include #include #include +#include #include #include #include @@ -24,8 +20,29 @@ #include "workspace.h" #include "xdg_shell.h" +static struct cg_view * +popup_get_view(struct wlr_xdg_popup *popup) { + while(true) { + if(popup->parent == NULL || + !wlr_surface_is_xdg_surface(popup->parent)) { + return NULL; + } + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_from_wlr_surface(popup->parent); + switch(xdg_surface->role) { + case WLR_XDG_SURFACE_ROLE_TOPLEVEL: + return xdg_surface->data; + case WLR_XDG_SURFACE_ROLE_POPUP: + popup = xdg_surface->popup; + break; + case WLR_XDG_SURFACE_ROLE_NONE: + return NULL; + } + } +} + static void -xdg_decoration_handle_destroy(struct wl_listener *listener, void *_data) { +xdg_decoration_handle_destroy(struct wl_listener *listener, void *data) { struct cg_xdg_decoration *xdg_decoration = wl_container_of(listener, xdg_decoration, destroy); @@ -53,100 +70,25 @@ xdg_decoration_handle_request_mode(struct wl_listener *listener, void *_data) { #endif static void -xdg_popup_destroy(struct cg_view_child *child) { - if(!child) { - return; - } - - view_damage_child(child, true); - struct cg_xdg_popup *popup = (struct cg_xdg_popup *)child; - wl_list_remove(&popup->destroy.link); - wl_list_remove(&popup->map.link); - wl_list_remove(&popup->unmap.link); - wl_list_remove(&popup->new_popup.link); - view_child_finish(&popup->view_child); - free(popup); -} - -static void -handle_xdg_popup_map(struct wl_listener *listener, void *_data) { - struct cg_xdg_popup *popup = wl_container_of(listener, popup, map); - view_damage_whole(popup->view_child.view); -} - -static void -handle_xdg_popup_unmap(struct wl_listener *listener, void *_data) { - struct cg_xdg_popup *popup = wl_container_of(listener, popup, unmap); - view_damage_whole(popup->view_child.view); -} - -static void -handle_xdg_popup_destroy(struct wl_listener *listener, void *_data) { - struct cg_xdg_popup *popup = wl_container_of(listener, popup, destroy); - struct cg_view_child *view_child = (struct cg_view_child *)popup; - xdg_popup_destroy(view_child); -} - -static void -xdg_popup_create(struct cg_view *view, struct wlr_xdg_popup *wlr_popup); - -static void -popup_handle_new_xdg_popup(struct wl_listener *listener, void *data) { - struct cg_xdg_popup *popup = wl_container_of(listener, popup, new_popup); - struct wlr_xdg_popup *wlr_popup = data; - xdg_popup_create(popup->view_child.view, wlr_popup); -} - -static void -popup_unconstrain(struct cg_xdg_popup *popup) { - struct cg_view *view = popup->view_child.view; - struct wlr_box *popup_box = &popup->wlr_popup->geometry; +popup_unconstrain(struct cg_view *view, struct wlr_xdg_popup *popup) { + struct wlr_box *popup_box = &popup->current.geometry; struct wlr_output_layout *output_layout = view->server->output_layout; - struct wlr_box *view_output_box = wlr_output_layout_get_box( - output_layout, view->workspace->output->wlr_output); + struct wlr_box view_output_box; + wlr_output_layout_get_box( + output_layout, view->workspace->output->wlr_output, &view_output_box); struct wlr_output *wlr_output = wlr_output_layout_output_at( - output_layout, view_output_box->x + view->ox + popup_box->x, - view_output_box->y + view->oy + popup_box->y); - struct wlr_box *output_box = - wlr_output_layout_get_box(output_layout, wlr_output); + output_layout, view_output_box.x + view->ox + popup_box->x, + view_output_box.y + view->oy + popup_box->y); + struct wlr_box output_box; + wlr_output_layout_get_box(output_layout, wlr_output, &output_box); struct wlr_box output_toplevel_box = {.x = -view->ox, .y = -view->oy, - .width = output_box->width, - .height = output_box->height}; + .width = output_box.width, + .height = output_box.height}; - wlr_xdg_popup_unconstrain_from_box(popup->wlr_popup, &output_toplevel_box); -} - -static void -xdg_popup_create(struct cg_view *view, struct wlr_xdg_popup *wlr_popup) { - struct cg_xdg_popup *popup = calloc(1, sizeof(struct cg_xdg_popup)); - if(!popup) { - return; - } - - popup->wlr_popup = wlr_popup; - view_child_init(&popup->view_child, NULL, view, wlr_popup->base->surface); - popup->view_child.destroy = xdg_popup_destroy; - popup->destroy.notify = handle_xdg_popup_destroy; - wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy); - popup->map.notify = handle_xdg_popup_map; - wl_signal_add(&wlr_popup->base->events.map, &popup->map); - popup->unmap.notify = handle_xdg_popup_unmap; - wl_signal_add(&wlr_popup->base->events.unmap, &popup->unmap); - popup->new_popup.notify = popup_handle_new_xdg_popup; - wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup); - - popup_unconstrain(popup); -} - -static void -handle_new_xdg_popup(struct wl_listener *listener, void *data) { - struct cg_xdg_shell_view *xdg_shell_view = - wl_container_of(listener, xdg_shell_view, new_popup); - struct wlr_xdg_popup *wlr_popup = data; - xdg_popup_create(&xdg_shell_view->view, wlr_popup); + wlr_xdg_popup_unconstrain_from_box(popup, &output_toplevel_box); } static struct cg_xdg_shell_view * @@ -159,27 +101,29 @@ xdg_shell_view_from_const_view(const struct cg_view *view) { return (const struct cg_xdg_shell_view *)view; } -static char * -get_title(const struct cg_view *view) { - const struct cg_xdg_shell_view *xdg_shell_view = - xdg_shell_view_from_const_view(view); - return xdg_shell_view->xdg_surface->toplevel->title; +static pid_t +get_pid(const struct cg_view *view) { + pid_t pid; + struct wl_client *client = + wl_resource_get_client(view->wlr_surface->resource); + wl_client_get_credentials(client, &pid, NULL, NULL); + return pid; } static bool is_primary(const struct cg_view *view) { const struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_const_view(view); - struct wlr_xdg_surface *parent = + struct wlr_xdg_toplevel *parent = xdg_shell_view->xdg_surface->toplevel->parent; - /* FIXME: role is 0? */ - return parent == NULL; /*&& role == WLR_XDG_SURFACE_ROLE_TOPLEVEL */ + return parent == NULL; } static void activate(struct cg_view *view, bool activate) { struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); - wlr_xdg_toplevel_set_activated(xdg_shell_view->xdg_surface, activate); + wlr_xdg_toplevel_set_activated(xdg_shell_view->xdg_surface->toplevel, + activate); } static void @@ -187,17 +131,18 @@ close(struct cg_view *view) { struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); struct wlr_xdg_surface *surface = xdg_shell_view->xdg_surface; if(surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { - wlr_xdg_toplevel_send_close(surface); + wlr_xdg_toplevel_send_close(surface->toplevel); } } static void maximize(struct cg_view *view, int width, int height) { struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); - wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_surface, width, height); + wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_surface->toplevel, width, + height); enum wlr_edges edges = WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM; - wlr_xdg_toplevel_set_tiled(xdg_shell_view->xdg_surface, edges); + wlr_xdg_toplevel_set_tiled(xdg_shell_view->xdg_surface->toplevel, edges); } static void @@ -206,47 +151,25 @@ destroy(struct cg_view *view) { free(xdg_shell_view); } -static void -for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, - void *data) { - struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); - wlr_xdg_surface_for_each_surface(xdg_shell_view->xdg_surface, iterator, - data); -} - -static void -for_each_popup(struct cg_view *view, wlr_surface_iterator_func_t iterator, - void *data) { - struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); - wlr_xdg_surface_for_each_popup_surface(xdg_shell_view->xdg_surface, - iterator, data); -} - -static struct wlr_surface * -wlr_surface_at(const struct cg_view *view, double sx, double sy, double *sub_x, - double *sub_y) { - const struct cg_xdg_shell_view *xdg_shell_view = - xdg_shell_view_from_const_view(view); - return wlr_xdg_surface_surface_at(xdg_shell_view->xdg_surface, sx, sy, - sub_x, sub_y); -} - static void handle_xdg_shell_surface_request_fullscreen(struct wl_listener *listener, void *data) { struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_fullscreen); - struct wlr_xdg_toplevel_set_fullscreen_event *event = data; - wlr_xdg_toplevel_set_fullscreen(xdg_shell_view->xdg_surface, - event->fullscreen); -} -static void -handle_xdg_shell_surface_commit(struct wl_listener *listener, void *_data) { - struct cg_xdg_shell_view *xdg_shell_view = - wl_container_of(listener, xdg_shell_view, commit); - struct cg_view *view = &xdg_shell_view->view; - view_damage_part(view); + /** + * Certain clients do not like figuring out their own window geometry if + * they display in fullscreen mode, so we set it here. + */ + struct wlr_box layout_box; + wlr_output_layout_get_box(xdg_shell_view->view.server->output_layout, NULL, + &layout_box); + wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_surface->toplevel, + layout_box.width, layout_box.height); + + wlr_xdg_toplevel_set_fullscreen( + xdg_shell_view->xdg_surface->toplevel, + xdg_shell_view->xdg_surface->toplevel->requested.fullscreen); } static void @@ -255,9 +178,6 @@ handle_xdg_shell_surface_unmap(struct wl_listener *listener, void *_data) { wl_container_of(listener, xdg_shell_view, unmap); struct cg_view *view = &xdg_shell_view->view; - wl_list_remove(&xdg_shell_view->new_popup.link); - wl_list_remove(&xdg_shell_view->commit.link); - view_unmap(view); } @@ -267,17 +187,9 @@ handle_xdg_shell_surface_map(struct wl_listener *listener, void *_data) { wl_container_of(listener, xdg_shell_view, map); struct cg_view *view = &xdg_shell_view->view; - xdg_shell_view->commit.notify = handle_xdg_shell_surface_commit; - wl_signal_add(&xdg_shell_view->xdg_surface->surface->events.commit, - &xdg_shell_view->commit); - xdg_shell_view->new_popup.notify = handle_new_xdg_popup; - wl_signal_add(&xdg_shell_view->xdg_surface->events.new_popup, - &xdg_shell_view->new_popup); - view_map(view, xdg_shell_view->xdg_surface->surface, view->server->curr_output ->workspaces[view->server->curr_output->curr_workspace]); - view_damage_whole(view); } static void @@ -295,17 +207,13 @@ handle_xdg_shell_surface_destroy(struct wl_listener *listener, void *_data) { view_destroy(view); } -static const struct cg_view_impl xdg_shell_view_impl = { - .get_title = get_title, - .is_primary = is_primary, - .activate = activate, - .close = close, - .maximize = maximize, - .destroy = destroy, - .for_each_surface = for_each_surface, - .for_each_popup = for_each_popup, - .wlr_surface_at = wlr_surface_at, -}; +static const struct cg_view_impl xdg_shell_view_impl = {.get_pid = get_pid, + .is_primary = + is_primary, + .activate = activate, + .close = close, + .maximize = maximize, + .destroy = destroy}; void handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { @@ -313,31 +221,72 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { wl_container_of(listener, server, new_xdg_shell_surface); struct wlr_xdg_surface *xdg_surface = data; - if(xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { - return; + switch(xdg_surface->role) { + case WLR_XDG_SURFACE_ROLE_TOPLEVEL:; + struct cg_xdg_shell_view *xdg_shell_view = + calloc(1, sizeof(struct cg_xdg_shell_view)); + if(!xdg_shell_view) { + wlr_log(WLR_ERROR, "Failed to allocate XDG Shell view"); + return; + } + + view_init(&xdg_shell_view->view, CG_XDG_SHELL_VIEW, + &xdg_shell_view_impl, server); + + xdg_shell_view->xdg_surface = xdg_surface; + + xdg_shell_view->map.notify = handle_xdg_shell_surface_map; + wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map); + xdg_shell_view->unmap.notify = handle_xdg_shell_surface_unmap; + wl_signal_add(&xdg_surface->events.unmap, &xdg_shell_view->unmap); + xdg_shell_view->destroy.notify = handle_xdg_shell_surface_destroy; + wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy); + xdg_shell_view->request_fullscreen.notify = + handle_xdg_shell_surface_request_fullscreen; + wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, + &xdg_shell_view->request_fullscreen); + + xdg_surface->data = xdg_shell_view; + break; + case WLR_XDG_SURFACE_ROLE_POPUP:; + struct wlr_xdg_popup *popup = xdg_surface->popup; + struct cg_view *view = popup_get_view(popup); + if(view == NULL) { + return; + } + + struct wlr_scene_tree *parent_scene_tree = NULL; + struct wlr_xdg_surface *parent = + wlr_xdg_surface_from_wlr_surface(popup->parent); + switch(parent->role) { + case WLR_XDG_SURFACE_ROLE_TOPLEVEL:; + parent_scene_tree = view->scene_tree; + break; + case WLR_XDG_SURFACE_ROLE_POPUP: + parent_scene_tree = parent->data; + break; + case WLR_XDG_SURFACE_ROLE_NONE: + break; + } + if(parent_scene_tree == NULL) { + return; + } + + struct wlr_scene_tree *popup_scene_tree = + wlr_scene_xdg_surface_create(parent_scene_tree, xdg_surface); + if(popup_scene_tree == NULL) { + wlr_log(WLR_ERROR, + "Failed to allocate scene-graph node for XDG popup"); + return; + } + + popup_unconstrain(view, popup); + + xdg_surface->data = popup_scene_tree; + break; + case WLR_XDG_SURFACE_ROLE_NONE: + assert(false); // unreachable } - - struct cg_xdg_shell_view *xdg_shell_view = - calloc(1, sizeof(struct cg_xdg_shell_view)); - if(!xdg_shell_view) { - wlr_log(WLR_ERROR, "Failed to allocate XDG Shell view"); - return; - } - view_init(&xdg_shell_view->view, CG_XDG_SHELL_VIEW, &xdg_shell_view_impl, - server); - - xdg_shell_view->xdg_surface = xdg_surface; - - xdg_shell_view->map.notify = handle_xdg_shell_surface_map; - wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map); - xdg_shell_view->unmap.notify = handle_xdg_shell_surface_unmap; - wl_signal_add(&xdg_surface->events.unmap, &xdg_shell_view->unmap); - xdg_shell_view->destroy.notify = handle_xdg_shell_surface_destroy; - wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy); - xdg_shell_view->request_fullscreen.notify = - handle_xdg_shell_surface_request_fullscreen; - wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, - &xdg_shell_view->request_fullscreen); } void diff --git a/xdg_shell.h b/xdg_shell.h index 601134b..e066208 100644 --- a/xdg_shell.h +++ b/xdg_shell.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_XDG_SHELL_H #define CG_XDG_SHELL_H @@ -10,19 +13,7 @@ struct cg_xdg_shell_view { struct wl_listener destroy; struct wl_listener unmap; struct wl_listener map; - struct wl_listener commit; struct wl_listener request_fullscreen; - struct wl_listener new_popup; -}; - -struct cg_xdg_popup { - struct cg_view_child view_child; - struct wlr_xdg_popup *wlr_popup; - - struct wl_listener destroy; - struct wl_listener map; - struct wl_listener unmap; - struct wl_listener new_popup; }; struct cg_xdg_decoration { diff --git a/xwayland.c b/xwayland.c index 98d0803..f601a0f 100644 --- a/xwayland.c +++ b/xwayland.c @@ -1,11 +1,6 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2020 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #include "config.h" #include @@ -44,11 +39,11 @@ xwayland_view_should_manage(const struct cg_view *view) { return !xwayland_surface->override_redirect; } -static char * -get_title(const struct cg_view *view) { - const struct cg_xwayland_view *xwayland_view = - xwayland_view_from_const_view(view); - return xwayland_view->xwayland_surface->title; +static pid_t +get_pid(const struct cg_view *view) { + struct wlr_xwayland_surface *surf = + wlr_xwayland_surface_from_wlr_surface(view->wlr_surface); + return surf->pid; } static bool @@ -64,6 +59,10 @@ static void activate(struct cg_view *view, bool activate) { struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); wlr_xwayland_surface_activate(xwayland_view->xwayland_surface, activate); + if(activate) { + wlr_xwayland_surface_restack(xwayland_view->xwayland_surface, NULL, + XCB_STACK_MODE_ABOVE); + } } static void @@ -75,35 +74,25 @@ close(struct cg_view *view) { static void maximize(struct cg_view *view, int width, int height) { struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); - struct cg_output *output = view->workspace->output; - - struct wlr_box *box = wlr_output_layout_get_box( - view->server->output_layout, view->workspace->output->wlr_output); - struct wlr_xwayland_surface_size_hints *hints = - xwayland_view->xwayland_surface->size_hints; + xcb_size_hints_t *hints = xwayland_view->xwayland_surface->size_hints; if(hints != NULL && hints->flags & PMaxSize) { if(width > hints->max_width) { - wlr_output_damage_add_box(output->damage, - &(struct wlr_box){.x = view->ox + box->x, - .y = view->oy + box->y, - .width = width, - .height = height}); width = hints->max_width; } if(height > hints->max_height) { - wlr_output_damage_add_box(output->damage, - &(struct wlr_box){.x = view->ox + box->x, - .y = view->oy + box->y, - .width = width, - .height = height}); height = hints->max_height; } } - wlr_xwayland_surface_configure(xwayland_view->xwayland_surface, view->ox, - view->oy, width, height); + struct wlr_box output_box; + wlr_output_layout_get_box(view->server->output_layout, + view->server->curr_output->wlr_output, + &output_box); + wlr_xwayland_surface_configure(xwayland_view->xwayland_surface, + view->ox + output_box.x, + view->oy + output_box.y, width, height); wlr_xwayland_surface_set_maximized(xwayland_view->xwayland_surface, true); } @@ -113,18 +102,6 @@ destroy(struct cg_view *view) { free(xwayland_view); } -static void -for_each_surface(struct cg_view *view, wlr_surface_iterator_func_t iterator, - void *data) { - wlr_surface_for_each_surface(view->wlr_surface, iterator, data); -} - -static struct wlr_surface * -wlr_surface_at(const struct cg_view *view, double sx, double sy, double *sub_x, - double *sub_y) { - return wlr_surface_surface_at(view->wlr_surface, sx, sy, sub_x, sub_y); -} - static void handle_xwayland_surface_request_fullscreen(struct wl_listener *listener, void *data) { @@ -136,33 +113,12 @@ handle_xwayland_surface_request_fullscreen(struct wl_listener *listener, xwayland_surface->fullscreen); } -static void -handle_xwayland_surface_commit(struct wl_listener *listener, void *_data) { - struct cg_xwayland_view *xwayland_view = - wl_container_of(listener, xwayland_view, commit); - struct cg_view *view = &xwayland_view->view; - /* xwayland surface has moved */ - if(xwayland_view->xwayland_surface->x != view->ox || - xwayland_view->xwayland_surface->y != view->oy) { - output_damage_surface(view->workspace->output, view->wlr_surface, - view->ox, view->oy, true); - view->ox = xwayland_view->xwayland_surface->x; - view->oy = xwayland_view->xwayland_surface->y; - output_damage_surface(view->workspace->output, view->wlr_surface, - view->ox, view->oy, true); - } else { - view_damage_part(view); - } -} - static void handle_xwayland_surface_unmap(struct wl_listener *listener, void *_data) { struct cg_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, unmap); struct cg_view *view = &xwayland_view->view; - wl_list_remove(&xwayland_view->commit.link); - view_unmap(view); } @@ -171,21 +127,18 @@ handle_xwayland_surface_map(struct wl_listener *listener, void *_data) { struct cg_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, map); struct cg_view *view = &xwayland_view->view; - if(!xwayland_view_should_manage(view)) { - view->ox = xwayland_view->xwayland_surface->x; - view->oy = xwayland_view->xwayland_surface->y; + struct wlr_output_layout *output_layout = view->server->output_layout; + struct wlr_box output_box; + wlr_output_layout_get_box( + output_layout, view->server->curr_output->wlr_output, &output_box); + view->ox = xwayland_view->xwayland_surface->x - output_box.x; + view->oy = xwayland_view->xwayland_surface->y - output_box.y; } - xwayland_view->commit.notify = handle_xwayland_surface_commit; - wl_signal_add(&xwayland_view->xwayland_surface->surface->events.commit, - &xwayland_view->commit); - view_map(view, xwayland_view->xwayland_surface->surface, view->server->curr_output ->workspaces[view->server->curr_output->curr_workspace]); - - view_damage_whole(view); } static void @@ -204,16 +157,12 @@ handle_xwayland_surface_destroy(struct wl_listener *listener, void *_data) { } static const struct cg_view_impl xwayland_view_impl = { - .get_title = get_title, + .get_pid = get_pid, .is_primary = is_primary, .activate = activate, .close = close, .maximize = maximize, .destroy = destroy, - .for_each_surface = for_each_surface, - /* XWayland doesn't have a separate popup iterator. */ - .for_each_popup = NULL, - .wlr_surface_at = wlr_surface_at, }; void diff --git a/xwayland.h b/xwayland.h index 4dfaac4..cde30c5 100644 --- a/xwayland.h +++ b/xwayland.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX -License-Identifier: MIT + #ifndef CG_XWAYLAND_H #define CG_XWAYLAND_H @@ -10,7 +13,6 @@ struct cg_xwayland_view { struct wl_listener destroy; struct wl_listener unmap; struct wl_listener map; - struct wl_listener commit; struct wl_listener request_fullscreen; }; From 3d86ea36b69601da90d8c801c2329adfb36524c7 Mon Sep 17 00:00:00 2001 From: project-repo Date: Mon, 9 Jan 2023 18:48:19 +0100 Subject: [PATCH 10/19] Release 2.0.1 Changelog: * Fix Issue 54 (#37 on github) * Cagebreak did not compile on BSD systems and falsely claimed to be POSIX compliant. --- Bugs.md | 10 ++++++++++ Hashes.md | 18 ++++++++++++++++++ README.md | 2 +- cagebreak.c | 1 - input_manager.c | 2 +- input_manager.h | 2 +- ipc_server.c | 1 - keybinding.c | 2 +- keybinding.h | 2 +- man/cagebreak-config.5.md | 2 +- man/cagebreak-socket.7.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 5 +++-- output.c | 2 +- signatures/2.0.0-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.0.0-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.0.0-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.0.0-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 22 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 signatures/2.0.0-cagebreak-config.5.sig create mode 100644 signatures/2.0.0-cagebreak-socket.7.sig create mode 100644 signatures/2.0.0-cagebreak.1.sig create mode 100644 signatures/2.0.0-cagebreak.sig diff --git a/Bugs.md b/Bugs.md index 25eeeca..c1792c4 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1110,3 +1110,13 @@ Under these circumstances Cagebreak did not quit right after startup. * Fixed: 2.0.0 Cagebreak did not build with wlroots 0.16.1 and this was adjusted. + +## Issue 54 + + * github issue numer: #36 + * Fixed: 2.0.1 + +Cagebreak was not compatible with clang 15 and POSIX which was causing issues +with building under FreeBSD. + +Thanks to Jan Beich for pointing this out and providing a PR. diff --git a/Hashes.md b/Hashes.md index 627d428..1fe4b4a 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,23 @@ # Hashes +2.0.1 cagebreak + + * sha 256: 3d7cdf511976248614617b1738246a3c5fa94543838e798c0c3a9aec325027b9 + * sha 512: 3b584e7a124e8b32b9d6584e82d256ca4a0b8c30423efc4678c8991d7a6f9b43edd29967eda7be6284e3583209e607b14d88e8ec65b19706849d0263a3188852 + +2.0.1 cagebreak.1 + + * sha 256: bb93d7d3af98b4b14a5b6968065ded51ad5006e6d81736ee1806ee62a99a137e + * sha 512: 90e8d4c5628cc556001da3b96194c5649cc948389697c4c70e10e5e259ce6a52150c6231b2fb9009d2834d52b64c0ebc5896403b9fd0c584d4c873e45846250f +2.0.1 cagebreak-config.5 + + * sha 256: 1870c1274848e6535edda170ec0349befb2aa78bc812c56bdc66df99600c86f0 + * sha 512: 4b546e77a722375cc6fd22562f3b4724e5cccc0907a935db5854fa4fe2a0eef16adbd2e7e2b35b023ac9609e5d97a341d62ade730c76acd6b3f80ba6f65d8a24 + +2.0.1 cagebreak-socket.7 + * sha 256: 1276c37af5cf32276b2f5bcb3f13d4d00c9a7957ef4d51cb2fa62d2fc3643c6f + * sha 512: 60b38a0b43d2a0d5026ecf2ec660538cd384b5a2e84f7a1a41ac916e67de54ae7a55e45492ed5654d3f248e1d6693ba7c4d596987b03082841a4c3c953c57846 + 2.0.0 cagebreak * sha 256: 45f88abdae03bbc7dad5734dd6fb1a00e1bf37d3e0c4016dad2fa3de832335cf diff --git a/README.md b/README.md index 1dba0b5..4c284b0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.0.0)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.0.1)](https://repology.org/project/cagebreak/versions) ## Quick Introduction diff --git a/cagebreak.c b/cagebreak.c index 0c5c247..28e363f 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -1,7 +1,6 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors // SPDX -License-Identifier: MIT -#define _POSIX_C_SOURCE 200812L #define _DEFAULT_SOURCE #include "config.h" diff --git a/input_manager.c b/input_manager.c index 29e4d1d..83cb966 100644 --- a/input_manager.c +++ b/input_manager.c @@ -89,7 +89,7 @@ input_manager_handle_device_destroy(struct wl_listener *listener, void *data) { } struct cg_input_config * -input_manager_create_empty_input_config() { +input_manager_create_empty_input_config(void) { struct cg_input_config *cfg = calloc(1, sizeof(struct cg_input_config)); if(cfg == NULL) { return NULL; diff --git a/input_manager.h b/input_manager.h index 1def1df..86dcf2e 100644 --- a/input_manager.h +++ b/input_manager.h @@ -16,7 +16,7 @@ input_manager_handle_device_destroy(struct wl_listener *listener, void *data); uint32_t input_manager_get_mouse_button(const char *name, char **error); struct cg_input_config * -input_manager_create_empty_input_config(); +input_manager_create_empty_input_config(void); struct cg_input_config * input_manager_merge_input_configs(struct cg_input_config *cfg1, struct cg_input_config *cfg2); diff --git a/ipc_server.c b/ipc_server.c index c5295e7..c28979d 100644 --- a/ipc_server.c +++ b/ipc_server.c @@ -1,7 +1,6 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors // SPDX -License-Identifier: MIT -#define _POSIX_C_SOURCE 200112L #define _DEFAULT_SOURCE #include "ipc_server.h" diff --git a/keybinding.c b/keybinding.c index 0c96d4b..c2f29bb 100644 --- a/keybinding.c +++ b/keybinding.c @@ -126,7 +126,7 @@ keybinding_list_push(struct keybinding_list *list, } struct keybinding_list * -keybinding_list_init() { +keybinding_list_init(void) { struct keybinding_list *list = malloc(sizeof(struct keybinding_list)); list->keybindings = malloc(sizeof(struct keybinding *)); list->capacity = 1; diff --git a/keybinding.h b/keybinding.h index 872f12d..c11de23 100644 --- a/keybinding.h +++ b/keybinding.h @@ -133,7 +133,7 @@ struct keybinding ** find_keybinding(const struct keybinding_list *list, const struct keybinding *keybinding); struct keybinding_list * -keybinding_list_init(); +keybinding_list_init(void); int run_action(enum keybinding_action action, struct cg_server *server, diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index a93734f..9fa63e3 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.0.0" "Cagebreak Manual" +cagebreak-config(5) "Version 2.0.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index d21ce84..66dd156 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.0.0" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.0.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 7feccc1..e05ae29 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.0.0" "Cagebreak Manual" +cagebreak(1) "Version 2.0.1" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index 9d2913f..29dbcd1 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.0.0', +version : '2.0.1', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -11,6 +11,7 @@ default_options : ['c_std=c11', 'warning_level=3'] add_project_arguments( [ '-DWLR_USE_UNSTABLE', + '-Werror=implicit-function-declaration', '-Wundef', '-Wno-unused-parameter', ], @@ -258,7 +259,7 @@ install_data('examples/config', install_dir : '/etc/xdg/cagebreak') if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1673193959 + secssinceepoch = 1673282376 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/output.c b/output.c index b36d724..a75f532 100644 --- a/output.c +++ b/output.c @@ -332,7 +332,7 @@ output_apply_config(struct cg_server *server, struct cg_output *output, } struct cg_output_config * -empty_output_config() { +empty_output_config(void) { struct cg_output_config *cfg = calloc(1, sizeof(struct cg_output_config)); if(cfg == NULL) { wlr_log(WLR_ERROR, "Could not allocate output configuration."); diff --git a/signatures/2.0.0-cagebreak-config.5.sig b/signatures/2.0.0-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..0e839de1d6a4029c6b1906c9b74962341d1add5f GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N-{RR9VJ5TM6H zgoft}d; zziNM$mHaAa9)z0kM}k45Z8dji9bL_riL4a>UFDl@2~vN)41xxj>0Wkv89j=;{oGKX z^A~tQ>S74ILHP>WV@`i(UJnzI_6ghUGvSviq^gF9-;B}ZwsE4*kBy9-<)XZK{!@-* z&hgGuZ9r%P+u`LAa@MFpzhROnVSl9{sv$bv!}2h11Wu|i%@`|^jQk!tgq0|XF EQh$jSv;Y7A literal 0 HcmV?d00001 diff --git a/signatures/2.0.0-cagebreak-socket.7.sig b/signatures/2.0.0-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..6c5048b79c2991fa9f1d0e86234926ebacf415f9 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N-{SpW(N5TM6H zgo@`h?n#LyK;!8^ONVafw0hZ759^be#Y5vvgbS%8( zr6n3>4_q-c_!#_23y|DeU*kv5#txLZxT816ne-fd-!;@V;T)X~gqMQ{iX%R67+OZ_ zI`x>h8*Sip|C8?buduzg8~y&`13b(lX32~JcTXu(TM$EK5w8pCL~ymwj?-6S)3yQ^ zB*#VzH%Kmu$?vl9b~bh7$E4ik!qrRt$Ed4TMQN}|OR6HW?UYr*g7DUnhJMgBw;nM* z1>Y0>*+l8s3*`{~IuLZXCSx|G<46>Ui8}k4@w0lPHpzL@@HTt9xFCK2;ANwxC`qm- zWjihvK~{&;PJ11k>O7vH*!jup2amsEe-67?M@iEJ1yQ=4ZQ%9d->9I;7X~(e5o?4y zPz7~!Orl)9PT|fOh`DE5V3_3~g3U@K`&jwfN_lbvSoDS4|7>tfbJbo97H7iFZAB`% z5U31S9^%K6x>%xCS((x^bfuuSTMjPZOQ+J!`*!ce7GUO z?As)9nZcoKyA>hlqBPC+$qBrL$?4S7HT$MGCAy3F?Ir8Z6hS>oQjwU<$y--2)xBBg zfKT`j8tN|YtvSI(xo}IO?>#DuJbdcngI4H~7WO^9Fd2xhI`RoId;=@YV5|dvbu@V1 EVY~ho;{X5v literal 0 HcmV?d00001 diff --git a/signatures/2.0.0-cagebreak.1.sig b/signatures/2.0.0-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..3dfee2837dfb06f16aeb167a6ad00914d94a8ed8 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N-{Pyh-E5TM6H zgo-W2!BHfPS^Gi=& z#hxq3RE#DT_XU3Sr|Czh@wMVJO0qKWy9dkq16QF=9rR-O0 zit<#6*?r0L>G%Xc> z%-+Z&xLZP9MEe#bN&|k<{0yaInV#E_xJy*4(5-U|h2tIvr9v5WPn?;|ZXM792R5`d zZ7?G}sUF_$$_eJc-&#VR5Q1@;0R`LVvXiLInzcu6I|j2= z8{Q@LjBpjyT-evrjEX-YJ;5fHH^C*Xm_9;^pJyxoON+B&p7in$HPpq&+Rdr!IMZUv zD;VMLXTOERHdZ6NDW+<~|7$l}du?(0kOkjV4F{mD-tn!LcGd!(Ob7l>d$9NggHZ}3 zILXX`N{g=8+J_HN1azWvA-$!xv$D{&1B>8w&=EFhN{rQJkkbCb1D<9<&C%L+zzfq0 EXp65H@&Et; literal 0 HcmV?d00001 diff --git a/signatures/2.0.0-cagebreak.sig b/signatures/2.0.0-cagebreak.sig new file mode 100644 index 0000000000000000000000000000000000000000..93517d0a5f58e4bcf66f09efccfcb8761670e9f0 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N-{OaKZA5TM6H zgo~=l{n)7QRnbU#$jeo7v*QE0H zNx?bqB`M~SowqBA>1{{Hat|LCP@pbGzpQ_pnZJCS<_CgpKC>*E$Z2K6mZ@nDbTmy9 zHic)f>9}PZT4OI$Cp=J_8zs2f1XR0tFZ`A(%{iF-=EhI44#(?5=#8%v3pE|6<;6wx zH84@?CzI9M^K_<&h>`e2c~=f{ljMum&}Ul6qgaL?iCV+tIv#Xtfq2Q>B3G9EC^)n{ z>yx6ahB%H|=skK6Yjyb&Kq$nr-{b+xY=cKV$th1ir4hb6?9Lf6k3y(_%5azjqq~Uc zP2f;<^+*2)PIG+ZO)Wo>H+A)SD85>gw_hk(P4oeW@SZjvNW-0{+~+(hZ~pNcuxxAVv_{@@5*G>mKizHnNPkZ1k(y2*Zkc E89-GH$N&HU literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index 0e839de1d6a4029c6b1906c9b74962341d1add5f..c2c27ba4cdab34262ca28c6967ed61e555cd3522 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY(V7%m4}r5TM6Hgoex zR_Un)RS6y%eva5{`l)fDw66bDb`cBjD>QVC41E6Fz@B*M#b|#x29>1{!YV7Nz^-R= z7SvfjTRDQ>(`W?ggT!_n!I<56{)f)pU+a~!*wr}U%8<eWKUSyl%YwY@l?ied|Y4fWUjo zz9P@2?IO?R57}`2{hf|S@!u|dNSv_{vfJTz8d#Ghy=zL&>0SMcq5JvxzQ4J&x0ssI2 delta 542 zcmV+(0^$9(1hxc_BY(RvRR9VJ5TM6HgoxlyB5yY2ZmH?%W?iDE;lfb*TpyC#?^L>EX&iYztF{#7cvy{Lz${?G-OwA z&pic^dQ)e&eT(R~c@dsP?a?TuB@x)6?KuV%vL)R~Qh~=R)T{420pG++NdBr0a^3O) zaQ0k~Kd-$SX@B|L&7tR#d_b}-`{MC*5fCxpZj6}RV#(g2+6>?&(!8OBT&}P4lj*&-E-#-lIf2V($Q!qrwFu8%9*!sU}f0mW}Dt~7lgqrY2f3;s)mT)jM3z_aiY(Ujf|b;qP%(jQ;uZL@y=6iKxhNo;pGu>)~G?hVUj3ef2AO* gAv)c|@)s~~1Wu|i%@`|^jQk!tgq0|XFQu(wHf&c&j diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index 6c5048b79c2991fa9f1d0e86234926ebacf415f9..d7dfe41453bb2d1880310eda8d18b9b4fe1c26d4 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY(V7&j1Pu5TM6Hgo0G6)?0C%_jEhB-K%m)L|XuI0e zVr~(+2J{j)bw=k~v4ztla|Ulh4{tTL?n7|@R5VB@$QBWg2`Xth9#FpXdV&3{9jNBeNd4ukHgYDcGU zgtU3vPqyFcq#!B)g=<6MYPnT9b;t!b5HbblkdH2VDf%k|x1XCNs!lD4O#kDjOB~C9 zRWBLyq|_OgEY_gA6(tne>c-us!z0~#zeLyKGR4OE01brUdZm0*%Poo47GQuupAR;! z(<1J}Tf++ohJUfLfE{Zw`%)cSFPzZ*MFyt8;4UZzx|z1?~qh^>C{DX z&n9iVP0R9+ gmHR@3Zx_>dzDwh6xjlT^`T4CsO__z*ttqyiy|R%H_W%F@ delta 542 zcmV+(0^$9(1hxc_BY(RvSpW(N5TM6Hgo@`h?n#LyK z;!8^ONVafw0hZ759^be#Y5vvgbS%8(r6n3>4_q-c_!#_23y|DeU*kv5#txLZxT816 zne-fd-!;@V;T)X~gqMQ{iX%R67+OZ_I`x>h8*Sip|C8?buYa(;wj2Ha;sZR)BWB5r z0e4R+Q(F*2Wf89n>O^q0&yLeqV$-$)7bM3<3pYqEiplS?@pd+Kr!h-PDk%oTIHMbryJ_X+s{n1G; znenrFqc+KT(|_Cpve~oHh&Rogga0Lb#qLjT)j@=&KZcgXIo&HsZa7=U6UJMpz!p?0)D!CA-3|AiF$A6N#SfW;0nbI?KrJ%N34ldwJ zr_#;)cJIaH+!E=@3ekvG5+O{3zr~^Ho<;QR+az(B!J%xs6(Q%MG|l$O3A}~L>D1FT z`=&T0x{LVjCF{-MriBIl)D_a7&`^Jt~VleCpzZ gR_Kuy_7^?AFd2xhI`RoId;=@YV5|dvbu@V1VKgQXu>b%7 diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 3dfee2837dfb06f16aeb167a6ad00914d94a8ed8..02074e9b5e5ef03999cd64d2f6009e46fe0ec97c 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY(V7$p8uo5TM6HgoUQEay2giu5l#VbH z-k@YujY!wvF;B+95U(nst7|ESnDJWkB%qF40HT=vqlJ58?3j}{ubwXf9G;ktbhzBF zy}<`WoH&}tb^3G`NTIh;h&p{1gyppn)~v1W)p)!Had&G07=IL@qr6Mvg#McQ3Gr4d zFZr-GqM@+)dYrm)Mc+Inss!`e>`UHsi?_wEK#>b&&R_)Cch$E5*#>cu!)hArj+dTI z_s{LQ98*BzCr#zooX<-{@?N~VzSWBWEEx*-`WVg{xl`X#n_Q*>LD-&V$pypqfv9~B42vCm58=q^=YdTtg66nx{37LdlWMZNS*kER0-W2!BHfPS^Gi=&#hxq3RE#DT_A zsLkaGkDGpeSyWzB=Mgc=bCZngrw|E{$b_=m|92^RCU^2_d>B>T{ke#kB}R4ceC858 zoRV}11ss3>x#p$(gW9eGi@2J#M{YX?vsD}3CH0JO6@S!R*w@mGia#Me!6ueB!6mJj zK0=D0XDk0pi?d>$^zsii)Wyfz&8h1+(_+di7~$_{zlFm#RwKMArfS6hYd2eaZE^aL z1>aN+2cWIq@vWA2)&ibP2mVfbu=oXoQ3@nD$;^RDi>}z(hYwH$bfR-1y`{FZve2~y gi{N$85f?USN{rQJkkbCb1D<9<&C%L+zzfq0XbgoCzyJUM diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 93517d0a5f58e4bcf66f09efccfcb8761670e9f0..f557280a419d0db0be93fa754e95b2d6ea52fbb1 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY(V7w*U$W5TM6HgonoJ9) z&{>5tT5ZYWEbw zY+?4ze$HBqg?TYBE&N{%N9fV;_F(n~22V3{4^xijR`KOu5rnJ@%zq~CJ z$-~%G2Elb9TYq7|Q#u3wWHsX7A=IMGr#wGBz5C?<9qg@Kec{|p8~|&6XLbwgzZ+M5 zpG{Pg98BuZOnnb^Z|6+`z4uWlPfp`2hz^w8SfCP($lehpB;iL{x#wG>!Op4l=S2E! z@;7*$dWWDl)|H+{#)GQ2p9_)U#cY-##psc}3m!L{bAL7VqzUE>fP{j3VkEVk<c` zf8LrW!E#C5iSU6z3f5^_9jJR}vF`U#e9JeMkAxvvkF*Y;EP-LTu->_Jl7)vMQ@fE( zKHYE>OoptX7xs>u$}htyX4<+M#f7B@(IdNeBv|S)phoi9=#+o=Lzj|cKe-!Z1l$_u go*Ezbw-@=5uM{#~(Avm1<9w&TWl{z`1X>|Rchm|4=l}o! delta 542 zcmV+(0^$9(1hxc_BY(RvOaKZA5TM6Hgo~=m47(n08!`gNyfA=uTijk zmhk+FQwz3qRuHi;Rip0phYCHhm0uS1j`5Z9FvtfguE0;$!}^OGQ7Ka9Ao7(XG_h0D zHGX(P@)q`anF*Y8Lyc>*=#77^)7PZ(_DR7x?qF>`uM-P39jN8SMf5c=QR*j?)!OrPrih4<_(XYE4sw&^i`LL* zTF9eVh98Mq!{j<1bZUWk$=o7Wmi;I=v^?vRqO68Ej(=L{J$evpb@>uND8#bgmKizHnNPkZ1k(y2*Zkc8KCk9mH+?% From 4f7be9d5cdd8df43609d983e58ab319b499cacb7 Mon Sep 17 00:00:00 2001 From: project-repo Date: Tue, 4 Apr 2023 14:00:31 +0200 Subject: [PATCH 11/19] Release 2.1.0 - Add -bs (bad security) option - Fix Issue 57 (SPDX spelling error #39) - Fix Issue 59 (meson install settings) - Fix Issue 55 (npd) - Fix Issue 56 (npd) - Fix Issue 58 (#40 config) - Improve release procedure - Add miniscule test suite - Adjust Cagebreak to wlroots 0.16.2 - New GPG Keys --- Bugs.md | 50 ++++++ Changelog.md | 13 ++ Hashes.md | 20 +++ LICENSE | 2 +- README.md | 82 +++++++-- SECURITY.md | 4 +- cagebreak.c | 52 +++--- config.h.in | 2 +- example_scripts/cb_script_header.sh | 2 +- example_scripts/focus_follows_cursor.sh | 2 +- example_scripts/show_workspace_views.sh | 3 +- examples/config | 2 +- fuzz/execl_override.c | 4 +- fuzz/fuzz-lib.c | 6 +- fuzz/fuzz-lib.h | 4 +- fuzz/fuzz-parse.c | 5 +- fuzz/meson.build | 38 ----- idle_inhibit_v1.c | 2 +- idle_inhibit_v1.h | 2 +- input.h | 2 +- input_manager.c | 2 +- input_manager.h | 2 +- ipc_server.c | 2 +- ipc_server.h | 2 +- keybinding.c | 39 +++-- keybinding.h | 3 +- keys/cagebreak@project-repo.co.pub | 157 ++++++++++-------- keys/cagebreak@project-repo.co.pub-legacy-3 | 76 +++++++++ ...gebreak_signing_key_11@project-repo.co.pub | 64 +++++++ ...gebreak_signing_key_12@project-repo.co.pub | 64 +++++++ libinput.c | 2 +- man/cagebreak-config.5.md | 3 +- man/cagebreak-socket.7.md | 3 +- man/cagebreak.1.md | 9 +- meson.build | 73 ++++++-- meson_options.txt | 2 +- message.c | 2 +- message.h | 2 +- output.c | 2 +- output.h | 2 +- pango.c | 2 +- pango.h | 2 +- parse.c | 19 +-- parse.h | 2 +- seat.c | 11 +- seat.h | 2 +- server.c | 10 +- server.h | 4 + signatures/2.0.1-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.0.1-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.0.1-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.0.1-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes test/arguments | 63 +++++++ test/build-w-o-warnings | 15 ++ test/build-w-o-xwayland | 15 ++ test/clang-format | 26 +++ test/copyright-license | 48 ++++++ test/environment-variables | 39 +++++ test/illegal-strings | 29 ++++ test/scan-build | 14 ++ test/shellcheck | 16 ++ test/testing-configurations/-c-config | 4 + test/testing-configurations/config | 4 + test/testing-configurations/env-var-config | 4 + test/testing-configurations/my-scan-build | 5 + test/versions | 42 +++++ util.c | 2 +- util.h | 2 +- view.c | 2 +- view.h | 3 +- workspace.c | 2 +- workspace.h | 2 +- xdg_shell.c | 10 +- xdg_shell.h | 2 +- xwayland.c | 10 +- xwayland.h | 2 +- 80 files changed, 975 insertions(+), 246 deletions(-) delete mode 100644 fuzz/meson.build create mode 100644 keys/cagebreak@project-repo.co.pub-legacy-3 create mode 100644 keys/cagebreak_signing_key_11@project-repo.co.pub create mode 100644 keys/cagebreak_signing_key_12@project-repo.co.pub create mode 100644 signatures/2.0.1-cagebreak-config.5.sig create mode 100644 signatures/2.0.1-cagebreak-socket.7.sig create mode 100644 signatures/2.0.1-cagebreak.1.sig create mode 100644 signatures/2.0.1-cagebreak.sig create mode 100644 test/arguments create mode 100644 test/build-w-o-warnings create mode 100644 test/build-w-o-xwayland create mode 100644 test/clang-format create mode 100644 test/copyright-license create mode 100644 test/environment-variables create mode 100644 test/illegal-strings create mode 100644 test/scan-build create mode 100644 test/shellcheck create mode 100644 test/testing-configurations/-c-config create mode 100644 test/testing-configurations/config create mode 100644 test/testing-configurations/env-var-config create mode 100755 test/testing-configurations/my-scan-build create mode 100644 test/versions diff --git a/Bugs.md b/Bugs.md index c1792c4..d8a33a1 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1120,3 +1120,53 @@ Cagebreak was not compatible with clang 15 and POSIX which was causing issues with building under FreeBSD. Thanks to Jan Beich for pointing this out and providing a PR. + +## Issue 55 + + * github issue number: N/A + * Fixed: 2.1.0 + +Prior to release 2.1.0, cagebreak sometimes crased due to a null pointer +derefrence when the cursor was moved. + +## Issue 56 + + * github issue numner: N/A + * Fixed: 2.1.0 + +Prior to release 2.1.0, the following workflow caused cagebreak to +crash: + + * Split an empty workspace. + * Open 2 windows on the left tile. + * exchangeright + * focus left + * cycle views + +The reason for this is that the ipc send event did not handle +focussing the background correctly when cycling. + +## Issue 57 + + * github issue number: #39 + * Fixed: 2.1.0 + +maxhbr pointed out that there was a spelling mistake in the +SPDX-License-Identifier. + +## Issue 58 + + * github issue number: #40 + * Fixed: 2.1.0 + +Prior to version 2.1.0, the logic behind configuration file loading was +broken. This had the effect, that the default configuration file was not +loaded when the user-specific config file was not present, instead +leading to a termination of cagebreak. + +## Issue 59 + + * github issue number: N/A + * Fixed: 2.1.0 + +Prior to release 2.1.0 `meson install` did not work perfectly. diff --git a/Changelog.md b/Changelog.md index e469a6c..c33e179 100644 --- a/Changelog.md +++ b/Changelog.md @@ -106,3 +106,16 @@ Changelog: * Disable outputs when unable to set any mode (crashed previously) * Add Code of Conduct * Print version number on startup + +## Release 2.1.0 + + * Add -bs (bad security) option + * Fix Issue 57 (SPDX spelling error #39) + * Fix Issue 59 (meson install settings) + * Fix Issue 55 (npd) + * Fix Issue 56 (npd) + * Fix Issue 58 (#40 config) + * Improve release procedure + * Add miniscule test suite + * Adjust Cagebreak to wlroots 0.16.2 + * New GPG Keys diff --git a/Hashes.md b/Hashes.md index 1fe4b4a..4e28e1e 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.1.0 cagebreak + + * sha 256: 0c90ba529ffc916306a1ca04d4c56a800c62a98d184d3cfcc2ce67dcdffad324 + * sha 512: 097007da750c8acd09ee63159aeff5a5584cbab45525bd8fe81a379da5cc0e9f2bf776b809122d1b599f4716ef7feb0ccc0cf98be47a71d4819e2a8cd7a2f495 + +2.1.0 cagebreak.1 + + * sha 256: 6509c9126a9a140c517111f9352bf787a31dd8451fa9976135fc1dfbe40ed23d + * sha 512: 96a8c3d5b9677a95255c09b3674559aea7ff130370baa1cce40212501cb288c047048cf9bfbf78bc2cfab35e346fd49ef6b9d5d67f8ab5d07f8991f66e8de3aa + +2.1.0 cagebreak-config.5 + + * sha 256: dbccee812d59209ddad73b376bfbb823611e2a8a92078b55e847ab678122bd54 + * sha 512: a8d0b31007208d7ca38f691ded77d9f13318f47046d9237efd6738d0e10dd8402a35fc48230e72493b17aeeb174cb246440301626a1cd5a48c7d03d0800d0128 + +2.1.0 cagebreak-socket.7 + + * sha 256: e7b85f15665da4a4422ad223b4b2748ff4315d315a8b108df279ff3b13b8c4c9 + * sha 512: 01dc53b4867ebc18f0091c3b1a239a89959403686c05e5e22aebf8155a46b82492b9aed27198a78e2777a9ff44b03f6e10ca82283062a29e1fa0114b97bb36a3 + 2.0.1 cagebreak * sha 256: 3d7cdf511976248614617b1738246a3c5fa94543838e798c0c3a9aec325027b9 diff --git a/LICENSE b/LICENSE index 538d78c..e0aba93 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2022 The Cagebreak authors +Copyright (c) 2020-2023 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes Copyright (c) 2019 The Sway authors diff --git a/README.md b/README.md index 4c284b0..f933980 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.0.1)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.1.0)](https://repology.org/project/cagebreak/versions) ## Quick Introduction @@ -148,7 +148,7 @@ Cagebreak was originally built to suit the needs of its creators. This section o how we intended some parts of cagebreak and might ease learning how to use cagebreak a little bit. Please note that this does not replace the man pages or the FAQ. Also, this is in no way intended as a guide on how cagebreak must be used but rather -as a source of inspiration and of explanations for why certain particularities. +as a source of inspiration and explanations for certain particularities. 1. Cagebreak is keyboard-based. Everything regarding cagebreak can be done through the keyboard and it is our view that it should be. This does not mean @@ -287,6 +287,49 @@ and after #endif ``` +### Test Suite + +``` +meson test -C build +``` + +invokes all tests. This is required for a release to occur. + +There are four test suites: + + * basic: tests actual outward-facing functionality + * Note optional dependencies for efficient socket interaction + * nc (openbsd-netcat) + * jq + * devel: tests internal properties of the repository + * Note potentially heavier dependencies such as + * shellcheck + * clang-format + * devel-long: applies more costly testing + * Note potentially heavier dependencies such as + * scan-build (static analysis (including security-relevant issues)) + * release: tests release specific considerations + * Note that this is only expected to pass just before + a release. This checks mostly administrative things + to check that a release is ready. + +Every commit should pass at least the basic and devel suites. + +It is expected that cagebreak passes at least the +basic, devel and devel-long suites when commits are pushed: + +``` +meson test -C build --suite basic --suite devel +``` + +The basic suite can be used to test a binary. This is +useful for PKGBUILDs and their equivalents in other +systems. + +``` +meson test -C build --suite basic +``` + ### Fuzzing Along with the project source code, a fuzzing framework based on `libfuzzer` is @@ -305,7 +348,7 @@ CC=clang meson setup build -Dfuzz=true -Db_sanitize=address,undefined -Db_lundef ninja -C build/ mkdir build/fuzz_corpus cp examples/config build/fuzz_corpus/ -WLR_BACKENDS=headless ./build/fuzz/fuzz-parse -jobs=12 -max_len=50000 -close_fd_mask=3 build/fuzz_corpus/ +WLR_BACKENDS=headless ./build/fuzz-parse -jobs=12 -max_len=50000 -close_fd_mask=3 build/fuzz_corpus/ ``` You may want to tweak `-jobs` or add other options depending on your own setup. @@ -376,6 +419,8 @@ keys. * AA927AFD50AF7C6810E69FE8274F2C605359E31B * BE2DED372287BC4EB2213E13A0C743848A638955 * 0F3476E4B2404F95EC41600683D5810F7911B020 + * 4E82C72C6B3E58A7BC4FF8554909F84CA83BB867 + * 5AEB1A2EB0D13F67E306AC59DC0CC81BE006FD85 Should we at any point retire a key, we will only replace it with keys signed by at least one of the above collection. @@ -415,8 +460,6 @@ The release procedure outlines the process for a release to occur. * [ ] Adjust version number * [ ] meson.build * [ ] git tag - * [ ] man pages - * [ ] README.md repology badges minversion * [ ] Relevant Documentation completed * [ ] New features * [ ] man pages @@ -430,16 +473,15 @@ The release procedure outlines the process for a release to occur. * [ ] Check features for SECURITY.md relevance (changes to socket scope for example) * [ ] Synchronize any socket changes to cagebreak-socket man page + * [ ] Updated internal wiki + * [ ] Added new files to meson.build or hardcoded testing variable * [ ] Fixed bugs documented in Bugs.md * [ ] Include issue discussion from github, where applicable * [ ] Testing * [ ] Manual testing * [ ] Libfuzzer testing - * [ ] Build version without xwayland support - * [ ] meson.build reproducible build versions are current archlinux libraries and gcc + * [ ] Arch Build System is up to date * [ ] wlr_xdg_shell version check - * [ ] `ninja -C build clang-format` makes no changes - * [ ] `ninja -C build scan-build` shows no issues * [ ] Cagebreak is reproducible on multiple machines * [ ] Documented reproducible build artefacts * [ ] Hashes of the artefacts in Hashes.md @@ -449,6 +491,7 @@ The release procedure outlines the process for a release to occur. * [ ] `gpg --detach-sign -u keyid cagebreak.1` * [ ] `gpg --detach-sign -u keyid cagebreak-config.5` * [ ] `gpg --detach-sign -u keyid cagebreak-socket.7` + * [ ] `meson test -C build` * [ ] `git add` relevant files * [ ] `git commit` * [ ] `git push origin development` @@ -568,5 +611,24 @@ see [SECURITY.md](SECURITY.md). ## License -MIT, please see [LICENSE](https://github.com/project-repo/cagebreak/blob/master/LICENSE). +Copyright (c) 2020-2023 The Cagebreak authors +Copyright (c) 2018-2020 Jente Hidskes +Copyright (c) 2019 The Sway authors +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/SECURITY.md b/SECURITY.md index bd7c388..2f33197 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -42,6 +42,7 @@ in `keys/` and sign your message with your own key. * B15B92642760E11FE002DE168708D42451A94AB5 * F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C * 3ACEA46CCECD59E4C8222F791CBEB493681E8693 +* 0A268C188D7949FEB39FD1462F2AD980247E4918 Note that our keys are signed by cagebreak signing keys. @@ -62,7 +63,8 @@ screens, ipc and potentially other documented local channels. ### STRIDE Threat List This is not a thorough analysis, just an overview of the ways in which cagebreak -has (no) attack surface. +has (no) attack surface. Please reference the man pages for details but especially +the -e and --bs options. #### Spoofing diff --git a/cagebreak.c b/cagebreak.c index 28e363f..4437331 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -1,11 +1,12 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _DEFAULT_SOURCE #include "config.h" #include +#include #include #include #include @@ -128,17 +129,26 @@ usage(FILE *file, const char *const cage) { " -e\t\t Enable socket\n" " -h\t\t Display this help message\n" " -s\t\t Show information about the current setup and exit\n" - " -v\t\t Show the version number and exit\n", + " -v\t\t Show the version number and exit\n" + " --bs\t\t \"bad security\": Enable features with potential " + "security implications (see man page)\n", cage); } static bool parse_args(struct cg_server *server, int argc, char *argv[], char **config_path) { - int c; + int c, option_index; server->enable_socket = false; - while((c = getopt(argc, argv, "c:hvse")) != -1) { + static struct option long_options[] = {{"bs", no_argument, 0, 0}, + {0, 0, 0, 0}}; +#ifndef __clang_analyzer__ + while((c = getopt_long(argc, argv, "c:hvse", long_options, + &option_index)) != -1) { switch(c) { + case 0: + server->bs = true; + break; case 'h': usage(stdout, argv[0]); return false; @@ -167,6 +177,7 @@ parse_args(struct cg_server *server, int argc, char *argv[], usage(stderr, argv[0]); return false; } +#endif return true; } @@ -197,7 +208,7 @@ set_configuration(struct cg_server *server, if(line == NULL) { wlr_log(WLR_ERROR, "Could not allocate buffer for reading " "configuration file."); - return 1; + return 2; } } if(strlen(line) == 0) { @@ -275,6 +286,7 @@ main(int argc, char *argv[]) { wl_list_init(&server.output_priorities); int ret = 0; + server.bs = 0; char *config_path = NULL; if(!parse_args(&server, argc, argv, &config_path)) { @@ -611,7 +623,7 @@ main(int argc, char *argv[]) { wlr_log_errno(WLR_ERROR, "Unable to set WAYLAND_DISPLAY.", "Clients may not be able to connect"); } else { - fprintf(stderr, + fprintf(stdout, "Cagebreak " CG_VERSION " is running on Wayland display %s\n", socket); } @@ -623,7 +635,7 @@ main(int argc, char *argv[]) { if(show_info) { char *msg = server_show_info(&server); if(msg != NULL) { - fprintf(stderr, "%s", msg); + fprintf(stdout, "%s", msg); free(msg); } else { wlr_log(WLR_ERROR, "Failed to get info on cagebreak setup\n"); @@ -632,27 +644,25 @@ main(int argc, char *argv[]) { } { // config_file should only be visible as long as it is valid + int conf_ret = 1; char *config_file = get_config_file(config_path); if(config_file == NULL) { wlr_log(WLR_ERROR, "Unable to get path to config file"); ret = 1; goto end; - } - int conf_ret = set_configuration(&server, config_file); - - // Configurtion file not found - if(conf_ret != 0) { - if(config_file == NULL) { - char *default_conf = "/etc/xdg/cagebreak/config"; - wlr_log(WLR_INFO, "Loading default configuration file: \"%s\"", - default_conf); - conf_ret = set_configuration(&server, default_conf); - } else { - conf_ret = 1; - } + } else { + conf_ret = set_configuration(&server, config_file); + free(config_file); + } + + // Configuration file not found + if(conf_ret == 1) { + char *default_conf = "/etc/xdg/cagebreak/config"; + wlr_log(WLR_INFO, "Loading default configuration file: \"%s\"", + default_conf); + conf_ret = set_configuration(&server, default_conf); } - free(config_file); if(conf_ret != 0 || !server.running) { ret = 1; goto end; diff --git a/config.h.in b/config.h.in index a79a80c..35dd0a6 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_CONFIG_H #define CG_CONFIG_H diff --git a/example_scripts/cb_script_header.sh b/example_scripts/cb_script_header.sh index 9533beb..770f075 100644 --- a/example_scripts/cb_script_header.sh +++ b/example_scripts/cb_script_header.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright 2023, project-repo and the cagebreak contributors -# SPDX -License-Identifier: MIT +# SPDX-License-Identifier: MIT named_pipe_send="$(mktemp -u)" named_pipe_recv="$(mktemp -u)" diff --git a/example_scripts/focus_follows_cursor.sh b/example_scripts/focus_follows_cursor.sh index 79e2889..e47bf88 100644 --- a/example_scripts/focus_follows_cursor.sh +++ b/example_scripts/focus_follows_cursor.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright 2023, project-repo and the cagebreak contributors -# SPDX -License-Identifier: MIT +# SPDX-License-Identifier: MIT # This script uses the cagebreak socket to modify the compositor's behaviour in # such a way that the currently focussed tile follows the cursor, i.e. that the diff --git a/example_scripts/show_workspace_views.sh b/example_scripts/show_workspace_views.sh index 3be9cbb..be6f0f9 100644 --- a/example_scripts/show_workspace_views.sh +++ b/example_scripts/show_workspace_views.sh @@ -1,6 +1,6 @@ #!/bin/bash # Copyright 2020 - 2023, project-repo and the cagebreak contributors -# SPDX -License-Identifier: MIT +# SPDX-License-Identifier: MIT # This script displays the process names of the views on the current workspace. @@ -19,6 +19,7 @@ do curr_workspace="$(echo "${event}"|jq -r ".outputs.${curr_output}.curr_workspace")" # Print the process names of the view on the current workspace. jq retrieves # their PID and ps is then used to retrieve the process names. + # shellcheck disable=2046 (echo -n "message ";ps -o comm=Command -p $(echo "${event}"|jq -r ".outputs.${curr_output}.workspaces[$((curr_workspace-1))].views[].pid")|tail +2|sed ':a; N; $!ba; s/\n/||/g') >&3 break fi diff --git a/examples/config b/examples/config index d79a792..6708e42 100644 --- a/examples/config +++ b/examples/config @@ -1,5 +1,5 @@ # Copyright 2020 - 2023, project-repo and the cagebreak contributors -# SPDX -License-Identifier: MIT +# SPDX-License-Identifier: MIT ###################### # General settings an key bindings ###################### diff --git a/fuzz/execl_override.c b/fuzz/execl_override.c index 9fc9e6e..275d4f0 100644 --- a/fuzz/execl_override.c +++ b/fuzz/execl_override.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT // This file is used by the fuzzer in order to prevent executing shell commands. #define _GNU_SOURCE @@ -10,7 +10,7 @@ #include int -fork() { +fork(void) { return 1; } diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index c159538..d331880 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -88,7 +88,7 @@ drop_permissions(void) { } void -cleanup() { +cleanup(void) { server.running = false; #if CG_HAS_XWAYLAND if(xwayland != NULL) { @@ -251,7 +251,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { wlr_renderer_init_wl_display(server.renderer, server.wl_display); - server.bg_color = (float[4]){0, 0, 0, 1}; + server.bg_color = calloc(4, sizeof(float *)); server.output_layout = wlr_output_layout_create(); if(!server.output_layout) { wlr_log(WLR_ERROR, "Unable to create output layout"); diff --git a/fuzz/fuzz-lib.h b/fuzz/fuzz-lib.h index 950f455..46aefd2 100644 --- a/fuzz/fuzz-lib.h +++ b/fuzz/fuzz-lib.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_FUZZ_LIB_H #define CG_FUZZ_LIB_H @@ -21,7 +21,7 @@ extern struct wlr_xcursor_manager *xcursor_manager; #endif void -cleanup(); +cleanup(void); int LLVMFuzzerInitialize(int *argc, char ***argv); diff --git a/fuzz/fuzz-parse.c b/fuzz/fuzz-parse.c index 0fc060c..d0bd5ab 100644 --- a/fuzz/fuzz-parse.c +++ b/fuzz/fuzz-parse.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -29,8 +29,7 @@ int set_configuration(struct cg_server *server, char *content) { char *line; - for(unsigned int line_num = 1; - (line = strtok_r(NULL, "\n", &content)) != NULL; ++line_num) { + while((line = strtok_r(NULL, "\n", &content)) != NULL) { line[strcspn(line, "\n")] = '\0'; if(*line != '\0' && *line != '#') { char *errstr = NULL; diff --git a/fuzz/meson.build b/fuzz/meson.build deleted file mode 100644 index 01fdd3e..0000000 --- a/fuzz/meson.build +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2020 - 2023, project-repo and the cagebreak contributors -# SPDX -License-Identifier: MIT - -fuzz_sources = [ - 'fuzz-parse.c', - 'fuzz-lib.c', - ] - -fuzz_headers = [ - '../parse.h', - 'fuzz-lib.h', - ] - -inc = include_directories(['..','../build/']) - -fuzz_dependencies = cagebreak_dependencies -if fuzzing_engine.found() - fuzz_dependencies += fuzzing_engine -else - link_args = [ '-fsanitize=fuzzer', ] -endif - -override_lib = shared_library('execl_override', - [ 'execl_override.c' ], - dependencies: [ cairo,pango,pangocairo ], - install: false - ) - -executable( - 'fuzz-parse', - fuzz_sources + fuzz_headers + cagebreak_headers + cagebreak_sources, - dependencies: fuzz_dependencies, - install: false, - include_directories: inc, - link_args: link_args + fuzz_link_args, - c_args: fuzz_compile_args, - link_with: override_lib, - ) diff --git a/idle_inhibit_v1.c b/idle_inhibit_v1.c index 9bc3f7a..b4f91f9 100644 --- a/idle_inhibit_v1.c +++ b/idle_inhibit_v1.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #include #include diff --git a/idle_inhibit_v1.h b/idle_inhibit_v1.h index f0dce64..74ae956 100644 --- a/idle_inhibit_v1.h +++ b/idle_inhibit_v1.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_IDLE_INHIBIT_H #define CG_IDLE_INHIBIT_H diff --git a/input.h b/input.h index f7877c5..f45e735 100644 --- a/input.h +++ b/input.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef _CG_INPUT_H #define _CG_INPUT_H diff --git a/input_manager.c b/input_manager.c index 83cb966..cfde2c9 100644 --- a/input_manager.c +++ b/input_manager.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L diff --git a/input_manager.h b/input_manager.h index 86dcf2e..b3eb006 100644 --- a/input_manager.h +++ b/input_manager.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_INPUT_MANAGER_H #define CG_INPUT_MANAGER_H diff --git a/ipc_server.c b/ipc_server.c index c28979d..ced183a 100644 --- a/ipc_server.c +++ b/ipc_server.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _DEFAULT_SOURCE diff --git a/ipc_server.h b/ipc_server.h index 2c66b83..41d7b88 100644 --- a/ipc_server.h +++ b/ipc_server.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_IPC_SERVER_H #define CG_IPC_SERVER_H diff --git a/keybinding.c b/keybinding.c index c2f29bb..44ccffb 100644 --- a/keybinding.c +++ b/keybinding.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -699,19 +699,20 @@ keybinding_cycle_views(struct cg_server *server, bool reverse, bool ipc) { seat_set_focus(server->seat, next_view); if(ipc) { + int curr_id = -1; + int curr_pid = -1; + if(current_view != NULL && + current_view->link.next != curr_workspace->views.next) { + curr_id = current_view->id; + curr_pid = current_view->impl->get_pid(current_view); + } ipc_send_event( curr_workspace->output->server, "{\"event_name\":\"cycle_views\",\"old_view_id\":%d,\"old_view_" "pid\":%d," "\"new_view_id\":%d,\"new_view_pid\":%d,\"tile_id\":%d," "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", - current_view->link.next == curr_workspace->views.next - ? -1 - : (int)current_view->id, - current_view->link.next == curr_workspace->views.next - ? -1 - : (int)current_view->impl->get_pid(current_view), - next_view == NULL ? -1 : (int)next_view->id, + curr_id, curr_pid, next_view == NULL ? -1 : (int)next_view->id, next_view == NULL ? -1 : (int)next_view->impl->get_pid(next_view), next_view->tile->id, curr_workspace->num + 1, curr_workspace->output->wlr_output->name, @@ -867,10 +868,15 @@ print_view(struct cg_view *view) { struct dyn_str outp_str; outp_str.len = 0; outp_str.cur_pos = 0; - uint32_t nmemb = 4; + uint32_t nmemb = 5; outp_str.str_arr = calloc(nmemb, sizeof(char *)); print_str(&outp_str, "\"id\": %d,\n", view->id); print_str(&outp_str, "\"pid\": %d,\n", view->impl->get_pid(view)); + if(view->server->bs == true) { + char *title_str = view->impl->get_title(view); + print_str(&outp_str, "\"title\": \"%s\",\n", + title_str == NULL ? "" : title_str); + } print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n", view->ox, view->oy); #if CG_HAS_XWAYLAND @@ -1180,8 +1186,16 @@ keybinding_dump(struct cg_server *server) { print_str(&str, "\"nws\":%d,\n", server->nws); print_str(&str, "\"bg_color\":[%f,%f,%f],\n", server->bg_color[0], server->bg_color[1], server->bg_color[2]); - print_str(&str, "\"views_curr_id\":%d,\n", server->views_curr_id); - print_str(&str, "\"tiles_curr_id\":%d,\n", server->tiles_curr_id); + struct cg_view *focused_view = seat_get_focus(server->seat); + int curr_view_id = -1, curr_tile_id = -1; + if(focused_view != NULL) { + curr_view_id = focused_view->id; + if(focused_view->tile != NULL) { + curr_tile_id = focused_view->tile->id; + } + } + print_str(&str, "\"views_curr_id\":%d,\n", curr_view_id); + print_str(&str, "\"tiles_curr_id\":%d,\n", curr_tile_id); print_str(&str, "\"curr_output\":\"%s\",\n", server->curr_output->wlr_output->name); print_str(&str, "\"default_mode\":\"%s\",\n", @@ -1784,9 +1798,6 @@ run_action(enum keybinding_action action, struct cg_server *server, server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->view); break; - case KEYBINDING_FOCUS_TILE: - keybinding_focus_tile(server, data.u); - break; default: { wlr_log(WLR_ERROR, "run_action was called with a value not present in \"enum " diff --git a/keybinding.h b/keybinding.h index c11de23..6d6cf87 100644 --- a/keybinding.h +++ b/keybinding.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef KEYBINDING_H @@ -74,7 +74,6 @@ struct cg_server; KEYBINDING(KEYBINDING_FOCUS_RIGHT, focusright) \ KEYBINDING(KEYBINDING_FOCUS_TOP, focusup) \ KEYBINDING(KEYBINDING_FOCUS_BOTTOM, focusdown) \ - KEYBINDING(KEYBINDING_FOCUS_TILE, focus_tile) \ \ KEYBINDING(KEYBINDING_DEFINEKEY, \ definekey) /* data.kb is the keybinding definition */ \ diff --git a/keys/cagebreak@project-repo.co.pub b/keys/cagebreak@project-repo.co.pub index c266665..648618b 100644 --- a/keys/cagebreak@project-repo.co.pub +++ b/keys/cagebreak@project-repo.co.pub @@ -1,76 +1,87 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -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 -PbvoKi4FeWdszeakeWuqdmKEi/+ltIk= -=uqsg +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 +=bl5A -----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak@project-repo.co.pub-legacy-3 b/keys/cagebreak@project-repo.co.pub-legacy-3 new file mode 100644 index 0000000..c266665 --- /dev/null +++ b/keys/cagebreak@project-repo.co.pub-legacy-3 @@ -0,0 +1,76 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +PbvoKi4FeWdszeakeWuqdmKEi/+ltIk= +=uqsg +-----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak_signing_key_11@project-repo.co.pub b/keys/cagebreak_signing_key_11@project-repo.co.pub new file mode 100644 index 0000000..e9e5720 --- /dev/null +++ b/keys/cagebreak_signing_key_11@project-repo.co.pub @@ -0,0 +1,64 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGQh0WABEADQBLQTo24k8CzFUKX4F9ROwyXLEg8HUxgfqq3jeH+0EdNs6uaT +W9IWn+Trd2iL6lvfcPpdAU737FiYLFU3GN7mMpTrdkf9HQD8FqwRtH6ikqrhXsZR +6AZLV+4K3YadV4rSkYiEM8w3wg6usMepGjO4yglIXFTW48QnkIQF6NjLeZ2alSon +OJqb//4ZoendW9GtFljUVKbpi7TRMGQuuSA1joGmBXv9TyvrrAPvG4bCqlsz4IqR +nsNSo4vs7kD9Sx4/beAYhSlqryWmB5QUK2QMi0cNN4foF9mrTQYGsoXosen1yay3 +vYClDdE1ehyJylmIrq3XDC9lS1HCF7c75ru3NEXyQgYiy2sYTfB3yWkK2cU61pYl ++K50WcT6Ko2h93LGSpehAT/OaliPY+kQ9BkOPjCIVkn504O/1mpK8COCrD3pcJhA +OnACIrxSCRBKlUARtzAQ2kz+HosBGaalEPT2XJErsdEXLz/QgNjocnAmMikIghP6 +3NhhsqDhL4ds044/AMUtUfo7svTYU3gOGvdHJlAqX/Tk7qAsecrBzgwzUkS2X+bN +T4SwfXJFigTl0Vntylu8tYIIDap8pLJXwRm3Y0tZOLKa1yIE0GDE78BFdYJ+Fael +pirh1qHrDySU30FOVTaEIAQodMwsAdYT9XdaXXZg5F9WJ3WpGwGIDN4PYQARAQAB +tENDYWdlYnJlYWsgU2lnbmluZyBLZXkgMTEgPGNhZ2VicmVha19zaWduaW5nX2tl +eV8xMUBwcm9qZWN0LXJlcG8uY28+iQJUBBMBCAA+FiEEToLHLGs+WKe8T/hVSQn4 +TKg7uGcFAmQh0WACGwMFCQHhM4AFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ +SQn4TKg7uGeEJA//ZRYkUrzOpwRLxKa11Y6QULuTMBptz9JLAZcXGUiOv4e2gZgV +nMg79iXsuqP3Za7sVaqvUZpeQcaUvYi1cnyG7JW+gombFUcBo2fqxPxykQ/LLi2s +4iFM9R9kI6NLHQt3ZcHWLNGYglA+uep5oJVNS+WN7TvTObvR7JZMzplnOu8SBoiZ +VGD7SVGYCzBGv4EFjlAy6oxjbCtZTC2j1+dxYyi987+F78bUOfH66QbYEZ+iQSYh +1+5Pj7K4WSEBhjTL3C7FjuL2NE+zTmYNNRDaDraV8t60V1lt8uYFz8+/ddDqGKet +0mFibaNTBQxjxttxcdRPvGJJPPdnbpodDmp24t40ELJ/aDb/aEb7L7HSelDAx38y +78zLgC9Of8zaZ3QryZ3svWRRURAIbb64l1QWDLQ7evZVf7iSOtc+DCRcfMPTAIXj +RNI3jZm83xLDW14y3CAhg2oyGD9oei29mjSZrhZ8LahnOW35O79EkjpGSgwRm1yS +PN1dkZX5PlXnt2/dh4kk8s86xz/gD77cK0/zNyPxqI6Ofj+/pGzm+X+apjINDl7k +r9kFqS1ksDOR/984pVY1hcuT6qiToQvH09SNXwdF1IcUndzTz8iT8ph0fNpXs1ot +m5OQCAIozso92RT/ESx1UpprCiwuFKlOxRmAEAxAdBYx/RVtI2sHKfJUDWaJAjME +EAEIAB0WIQS+Le03Ioe8TrIhPhOgx0OEimOJVQUCZCHd5wAKCRCgx0OEimOJVbyN +D/9iy+xqXGF+fdvOtgAoSL9xrwqzS/rXw37Wg7h4I0ajGheE2KlR6KGGcYTnJhkO +debD5H6bhuD5+ajaajknksCc/ikRZXvxC+rUIQtgm+HIGNgtlAYWgf4SvNVaOK4k +f8DdWqj0on+CZdNN/mh3HLbjU8quGf+iS5+5T6yVZEExT8Rf18ROM2xGHlti9zdJ +FjeY76PFQ51TKvTec8hiz7+DkogcFl9YY/I1vsRZG3/0T7JzuiXJOQvGWFYKsd7G +L92UbjD8B8agGdLeBYZcgLLNFpRDZUgPcSpo6jbA36Chnytu/Mwnsm8L/SVgb221 +zsYGUAE4h+UAb6DqiGcIhEvhA89nKzM2ek5j0L2swaS67i/SIMmb1ZkTzHUNVdQX +VDpNt2eNeJnJWY0cMKeynUc/SBJK/CweKBlCjHKxgJ8U4WbYUr5p/6GJw0/l610R +IIMHLuAYMChJjXkFygGpbc5zNl/RwbkS8jIfeLMmiafRDv9EJHkPqVGKBRaj7Rp3 +CsJbB2Lm+M0bB6xLtKrM18PkaGE9CuccWiQgB4g0gxPhteltRde2BozpJZQl4dDv +uRUjsC9GFgP4vaQCDHyyDRHEE9y/guo6l9m+az07HWvw2fo3zDCTP6CL7PhEmRlR +rw5M57AW2KRHaIoS1mG+aYTDuVOqcEXIOfqktc3euut3JLkCDQRkIdFgARAA4MaD +Ny6YUbkxdxsfvaUMMK/umk0U1yDNcEtjl53rzYbPTGRz28DMgZcD85w1eBPvUZ/0 +0OEgpmQ/EqCnu65Enwy1uyYgN64yiU0iGpOBm6eL1gd+AdTqEGXzs8N0oWZoUOtT +9bwShSBc7Zf8SlqPy6zL8RaGy0OXerCXHy3n5jQjjVfrfPP33NaitsL579WWW7cB +exvaPeEZnbr5BfH+aOfMzmZ1qseKSbNb7juh/lvq5iGYltCULALvQkL1tDBiS72g +SRVIliEe7ir3wukdtLAYInuMMwC8T5+36gkHjJ3zL0y8w4MQVSfSmScO68MrdCNl +6yPWGjvOyQgAeBqBeg1k9zn+Bo2HyvE3ubWDgmsnIzaDCXpRkPzpUw3re7/f6fXz +VdwvGvB1aQmcOKRRXs55g8PfE/i62bx/2THxKekwW3RuAEudUvChGqxogwCZEtDy +CiP+/f7AZ3Po+z8uTTbvonReKwA1hD0lgO0X43qtDGzunwaVkpL0erjYp9JVUYo6 +0oGgnKs9kKZcLXO709pwL7yyubAnWHjXLdMsOXBh9wwEaig87QsTuYMwxNkphAh7 +mZRhHODXEAtD6C5B5o1HvFfYJcZ8hStqtYbIOPaW1yOKnoW1CuQ8/0D4YFZ1I25d +nK36KPNLEcg6r32te3jAugk1z+PT0eJiwYSJeFsAEQEAAYkCPAQYAQgAJhYhBE6C +xyxrPlinvE/4VUkJ+EyoO7hnBQJkIdFgAhsMBQkB4TOAAAoJEEkJ+EyoO7hnjrUQ +ALAALHGlJAGuZiS0D/4qaXk+H53b6AeVymQn909nHmt7BQqzULoMPDrykh8o9Hom +Lc0qmd0PjN54Y4kSVZgaYtHgOvTSc2q8HTGOTEbBtS6ZT9jsRilV6XF6YKygYdU0 +IWhntciRCRtr9Xs6Ynb9p2g1Ji13Ic0CAZ6cEvt43ERUzU9nfTDH2GkhpQ4Rm98d +q3+SpCrY5XzlWJr7wOqKL1yLq2uW9RrxgEO+7l6OXtZ/+JzasxQeysB+zCmKJSR3 +QDT0LEliFRV1x01NdJnzLiMcTwKyaRCajgLb4rZO5JI06GTuAeqafLfZlr8XbKDe +O2QoWWiGQIYPfNx6zXBuJixKeM1GnpSaCeZakBq2Ex5fIGhPzUbsM6a+c9SC0f6R +zpYOJyDge84+YwEfqb8Cn2ytgRBX6a6vBGXRIR0MqCbM4TAqbFu4v5NznITYIWAh +dYJDF1mqKgE5b4xazl48XycHArkqxCEqPChKecwAFeHYr2LAMsa4vpRUFnQCD0TC +ny1tbvSUSuEdUJH4QT/F76d6augsvrAmfLXTn4KPhs3b7r6CNS7Ii13lvPOPATXa +P5KsJ+us//WBstRfPfatVpB6nS++BXI5oI1cM7/mhDfrnPVp9/FfGGE0S3DyPKvL +b/KPMkus9TOonKoUJ0Gp4Pl391/CekGmuOhEpvSeJr9n +=aQvd +-----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak_signing_key_12@project-repo.co.pub b/keys/cagebreak_signing_key_12@project-repo.co.pub new file mode 100644 index 0000000..e8a379f --- /dev/null +++ b/keys/cagebreak_signing_key_12@project-repo.co.pub @@ -0,0 +1,64 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=ZVRm +-----END PGP PUBLIC KEY BLOCK----- diff --git a/libinput.c b/libinput.c index dcb9d1f..e980060 100644 --- a/libinput.c +++ b/libinput.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #include "input.h" #include "input_manager.h" diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 9fa63e3..1c65b78 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.0.1" "Cagebreak Manual" +cagebreak-config(5) "Version 2.1.0" "Cagebreak Manual" # NAME @@ -420,6 +420,7 @@ GPG Fingerprints: - B15B92642760E11FE002DE168708D42451A94AB5 - F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C - 3ACEA46CCECD59E4C8222F791CBEB493681E8693 +- 0A268C188D7949FEB39FD1462F2AD980247E4918 # LICENSE diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index 66dd156..b8e8d9c 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.0.1" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.1.0" "Cagebreak Manual" # NAME @@ -582,6 +582,7 @@ GPG Fingerprints: - B15B92642760E11FE002DE168708D42451A94AB5 - F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C - 3ACEA46CCECD59E4C8222F791CBEB493681E8693 +- 0A268C188D7949FEB39FD1462F2AD980247E4918 # LICENSE diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index e05ae29..b3fd209 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.0.1" "Cagebreak Manual" +cagebreak(1) "Version 2.1.0" "Cagebreak Manual" # NAME @@ -47,6 +47,12 @@ are displayed in a message box at the top right of the screen. *-v* Show version number and exit +*--bs* + "bad security". Enable features with potential security implications. + Currently, this option has the following effects (possible implications + in parentheses): + - Print view titles in `dump` output (an attacker may be able to read sensitive information contained in the view title). + # ENVIRONMENT *CAGEBREAK_SOCKET* @@ -84,6 +90,7 @@ GPG Fingerprints: - B15B92642760E11FE002DE168708D42451A94AB5 - F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C - 3ACEA46CCECD59E4C8222F791CBEB493681E8693 +- 0A268C188D7949FEB39FD1462F2AD980247E4918 # LICENSE diff --git a/meson.build b/meson.build index 29dbcd1..f9708e7 100644 --- a/meson.build +++ b/meson.build @@ -1,9 +1,9 @@ # Copyright 2020 - 2023, project-repo and the cagebreak contributors -# SPDX -License-Identifier: MIT +# SPDX-License-Identifier: MIT project( 'cagebreak', 'c', -version : '2.0.1', +version : '2.1.0', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -204,15 +204,15 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.21.0', 'wayland_cursor': '1.21.0', - 'wlroots': '0.16.1', + 'wlroots': '0.16.2', 'xkbcommon': '1.5.0', - 'fontconfig': '2.14.1', - 'libinput': '1.22.0', + 'fontconfig': '2.14.2', + 'libinput': '1.23.0', 'libevdev': '1.13.0', - 'libudev': '252', - 'pango': '1.50.12', - 'cairo': '1.17.6', - 'pangocairo': '1.50.12', + 'libudev': '253', + 'pango': '1.50.14', + 'cairo': '1.17.8', + 'pangocairo': '1.50.14', 'math': '-1' } @@ -238,7 +238,7 @@ foreach name, dep : cagebreak_dependencies_dict endforeach reproducible_build_compiler = 'gcc' -reproducible_build_compiler_version = '12.2.0' +reproducible_build_compiler_version = '12.2.1' if cc.get_id() != reproducible_build_compiler warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in Hashes.md (' + reproducible_build_compiler + ').') @@ -256,10 +256,11 @@ executable( ) install_data('examples/config', install_dir : '/etc/xdg/cagebreak') +install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_name() + '/') if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1673282376 + secssinceepoch = 1680540192 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') @@ -294,8 +295,44 @@ if get_option('man-pages') ) endif +fuzz_sources = [ + 'fuzz/fuzz-parse.c', + 'fuzz/fuzz-lib.c', + ] + +fuzz_headers = [ + 'parse.h', + 'fuzz/fuzz-lib.h', + ] + +fuzz_override_lib = [ 'fuzz/execl_override.c' ] + if get_option('fuzz') - subdir('fuzz') + inc = include_directories(['.','build/']) + + fuzz_dependencies = cagebreak_dependencies + if fuzzing_engine.found() + fuzz_dependencies += fuzzing_engine + else + link_args = [ '-fsanitize=fuzzer', ] + endif + +override_lib = shared_library('execl_override', + [ fuzz_override_lib ], + dependencies: [ cairo,pango,pangocairo ], + install: false + ) + + executable( + 'fuzz-parse', + fuzz_sources + fuzz_headers + cagebreak_headers + cagebreak_sources, + dependencies: fuzz_dependencies, + install: false, + include_directories: inc, + link_args: link_args + fuzz_link_args, + c_args: fuzz_compile_args, + link_with: override_lib, + ) endif summary = [ @@ -306,3 +343,15 @@ summary = [ '' ] message('\n'.join(summary)) + +# Test Suite + +test('Build without warnings', find_program('test/build-w-o-warnings'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Build without xwayland', find_program('test/build-w-o-xwayland'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Copyright and LICENSE', find_program('test/copyright-license'), args : [ cagebreak_main_file + cagebreak_source_strings + cagebreak_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()), ''.join('MESONLICENSE=', meson.project_license())], suite: 'devel' ) +test('Clang-format (formatting check)', find_program('test/clang-format'), args : [ cagebreak_main_file + cagebreak_source_strings + cagebreak_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Shellcheck (script linting)', find_program('test/shellcheck'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Scan-build (static analysis)', find_program('test/scan-build'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel-long') +test('Arguments', find_program('test/arguments'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic') +test('Environment Variables', find_program('test/environment-variables'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic') +test('Semantic versioning', find_program('test/versions'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release') diff --git a/meson_options.txt b/meson_options.txt index 6d4a787..b7fc956 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,5 +1,5 @@ # Copyright 2020 - 2023, project-repo and the cagebreak contributors -# SPDX -License-Identifier: MIT +# SPDX-License-Identifier: MIT option('xwayland', type: 'boolean', value: 'false', description: 'Enable support for X11 applications') option('man-pages', type: 'boolean', value: 'false', description: 'Build man pages (requires pandoc)') option('fuzz', type: 'boolean', value: 'false', description: 'Enable building fuzzer targets') diff --git a/message.c b/message.c index f0c2c64..74b1d0a 100644 --- a/message.c +++ b/message.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #include #include diff --git a/message.h b/message.h index 25bf692..806307c 100644 --- a/message.h +++ b/message.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef MESSAGE_H diff --git a/output.c b/output.c index a75f532..b8fc627 100644 --- a/output.c +++ b/output.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L diff --git a/output.h b/output.h index 0a255df..90cd615 100644 --- a/output.h +++ b/output.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_OUTPUT_H #define CG_OUTPUT_H diff --git a/pango.c b/pango.c index c513f97..3af6f7f 100644 --- a/pango.c +++ b/pango.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #include #include diff --git a/pango.h b/pango.h index 30f2865..53a78cc 100644 --- a/pango.h +++ b/pango.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef _SWAY_PANGO_H #define _SWAY_PANGO_H diff --git a/parse.c b/parse.c index d250439..68767c6 100644 --- a/parse.c +++ b/parse.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -786,23 +786,6 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, keybinding->action = KEYBINDING_SHOW_INFO; } else if(strcmp(action, "close") == 0) { keybinding->action = KEYBINDING_CLOSE_VIEW; - } else if(strcmp(action, "focus_tile") == 0) { - keybinding->action = KEYBINDING_FOCUS_TILE; - char *nws_str = strtok_r(NULL, " ", &saveptr); - if(nws_str == NULL) { - *errstr = log_error( - "Expected argument for \"focus_tile\" action, got none."); - return -1; - } - - long tile_id = strtol(nws_str, NULL, 10); - if(tile_id < 1) { - *errstr = log_error( - "Tile id for focus_tile must be a positive integer. Got %l\n", - tile_id); - return -1; - } - keybinding->data.u = tile_id; } else if(strcmp(action, "focus") == 0) { keybinding->action = KEYBINDING_CYCLE_TILES; keybinding->data.b = false; diff --git a/parse.h b/parse.h index 4e38ea9..2949315 100644 --- a/parse.h +++ b/parse.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef PARSE_H diff --git a/seat.c b/seat.c index a3e09a0..cd085be 100644 --- a/seat.c +++ b/seat.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -214,8 +214,11 @@ handle_command_key_bindings(struct cg_server *server, xkb_keysym_t sym, wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { surface = scene_surface->surface; + if(surface != NULL) { + wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, + sy); + } } - wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy); } } } @@ -701,8 +704,10 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { surface = scene_surface->surface; + if(surface != NULL) { + wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy); + } } - wlr_seat_pointer_notify_enter(wlr_seat, surface, sx, sy); bool focus_changed = wlr_seat->pointer_state.focused_surface != surface; if(!focus_changed && time > 0) { diff --git a/seat.h b/seat.h index e44d808..74f4092 100644 --- a/seat.h +++ b/seat.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_SEAT_H #define CG_SEAT_H diff --git a/server.c b/server.c index 292d0b0..c50f528 100644 --- a/server.c +++ b/server.c @@ -1,11 +1,5 @@ -/* - * Cagebreak: A Wayland tiling compositor. - * - * Copyright (C) 2020-2022 The Cagebreak Authors - * Copyright (C) 2018-2019 Jente Hidskes - * - * See the LICENSE file accompanying this file. - */ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L diff --git a/server.h b/server.h index 39d26f4..9f6eca6 100644 --- a/server.h +++ b/server.h @@ -1,3 +1,6 @@ +// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// SPDX-License-Identifier: MIT + #ifndef CG_SERVER_H #define CG_SERVER_H @@ -54,6 +57,7 @@ struct cg_server { struct cg_ipc_handle ipc; bool enable_socket; + bool bs; bool running; char **modes; uint16_t nws; diff --git a/signatures/2.0.1-cagebreak-config.5.sig b/signatures/2.0.1-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..c2c27ba4cdab34262ca28c6967ed61e555cd3522 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N>V%m4}r5TM6H zgo8S-(2_71Lj@WDZsd1sSuK!ea5ex4t zG<1y&eE!_Po_OfRXn!~cm8B5EDl4hLu4i)=)LA}TIfCBPXawnl#C9FQnB92(htAz! z>y@(D)i~kGkj)K}no#5%0G(l=Y)}|}AmrOFO5`g@pSbgF&pM^k{nd&<5d&+Q;0$DwF)__Kmu6w9uUE`=LedD0LPpZ=WpI$&C0NLk}{~mJUD^KP_#=zL&>0SMcq5Jvxz EQJJ_DGynhq literal 0 HcmV?d00001 diff --git a/signatures/2.0.1-cagebreak-socket.7.sig b/signatures/2.0.1-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..d7dfe41453bb2d1880310eda8d18b9b4fe1c26d4 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N>V&j1Pu5TM6H zgo0G6)?0C%_jEhB-K%m)L|XuI0eVr~(+2J{j)bw=k~v4ztla|Ulh4{tTL z?n7|@R5VB@$Q zBWg2`Xth9#FpXdV%|o0=`*6q(gYKznN2hOuw0YZ4w%_WcASwWbYeV5`xm7xK$OShL zG6m<5k1l&D`YQvspPMAAPA!N`|Kq1i9Ls=JFB$Ws)ESp7)}Xr;B^24}#@(jFBi(wx zMAzan#m4yn4TRx(rF>J%Es53^V1PlN4>qpTBJRUm!wU$8v9f?1hd}uaes)atFl~jf z3|mvj;m|N@y?#TF??W9xatvKQtam21k3xdP$zPvDk=$lsYA?Bh7p~NEtl-6|zjj_) zQ1t(=(XX?U4PQ0VTxMTap50^2ik`E4KFb6`s8nUo;(yt&3gjO4Q7sI070S=2lEb%Z z`(0P9=``1;jT?tkEx-MpQ16gbdFj+ea^%f4vj}&@b3kaTx?Wn|S#&caun#P;owpr^ z*}OPqgZ_?aH$}tY){U&W+rbU0s#cE7!u?)Y*f|rQ{zfdGVjs~2V$p8uo5TM6H zgoUQEay2giu5l#VbH-k@YujY!wvF;B+95U(nst7|ESnDJWk zB%qF40HT=vqlJ58?3j}{ubwXf9G;ktbhzBFy}<`WoH&}tb^3G`NTIh;h&p{1gyppn z)~v1W)p)!Had&G07!;wSyi4MQ{+jy<@m4D@`LH&kp|JUSoVs#F-#jI%1oPVLOWt&g zx5ckOkqc$cUmQ)M2AbmJ!D-r57rIvB>Jv050RoD9#ou#5SAUk&<{SNJ1>M0VD`E_2UH@>7( z2S6vhoDzWXeZ?qcZ9%23RL@y1K!W)cQeH;Uc6ZkX`7s^tz)`|Nl*uVw*U$W5TM6H zgonoJ9)&{i1#gpM}@m{|lw|Ku2CUQS)TLtAvj-K;Vh zb|POEmZojMp*F!d#Dl4|Q+nO#!|4Q7BJN<12^` zl-yXL5{<~-5hWzyM_IY&Tcg3wsr2VW`fTzyc%6EOpf}c)o<_!ls<)pDk>SN`mLbLH zk-ZBZH=A=c_M{2s41k1!dtxNDoX;4*Qh(l>C&6+_+==jkK?>GsS{|R EcZ1Uk8UO$Q literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index c2c27ba4cdab34262ca28c6967ed61e555cd3522..25072cbc7ec479dc03f8b0e58fb181f393b6019f 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@H2?|;5J?I6 zOsG4!XTI7G{wRJJEi`J}KeQfb1JU@66Z3T<6NTy#--hMh*c8j3d2~hbi^ZX=-TrKn ztD7j~V&53Q9i%4h8U#_7hK7oj`CIlD=;Mc4GwQ>a)J-YmdG`Vl;8s)}69L&?L5d~& z$20iJNFBNWK|tDpKg-~|d82IW#CC`j7nDWB&(z58T;2M2wvtE4dP=d?zp?WD0=p9* zUPU`tsJ{U-0GdW{DSNRrlKUGFVqhO3@k!$cL3*Qp6odwyB-0xQnq)@N!PVe$1`L>|k=$CLVHK?O+TkwoVUh!Xj=V&t>{#C*0%ot(iIdi&^gyH8KlU zhBT+I4>=Rc$+O;JZ!`T~Bm7w_#GKcp?kq#s$P0|Y^(i`zme%V+VSapC^`l@oRL1{@BcO}re zf)i0-Wdr6R<0JhvON1>o?yPvCFw8vYk{DbTrXy>~v!h&yhCb5?O?zZ$sp$kzmLK)j EGK$X>3IG5A literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N>V%m4}r5TM6H zgo8S-(2_71Lj@WDZsd1sSuK!ea5ex4t zG<1y&eE!_Po_OfRXn!~cm8B5EDl4hLu4i)=)LA}TIfCBPXawnl#C9FQnB92(htAz! z>y@(D)i~kGkj)K}no#5%0G(l=Y)}|}AmrOFO5`g@pSbgF&pM^k{nd&<5d&+Q;0$DwF)__Kmu6w9uUE`=LedD0LPpZ=WpI$&C0NLk}{~mJUD^KP_#=zL&>0SMcq5Jvxz EQJJ_DGynhq diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index d7dfe41453bb2d1880310eda8d18b9b4fe1c26d4..67c2e166279805704204ef4ba7843177146a8340 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@I{*p^5J?I6 zOsG4!XJ?rY{wb7ikpWvUjL5LXPboA72(rh}Um;IL{Hr(?cZ{Hcdvsw7)6JwNk7BnM zayXykj0YkR+Jh2Hwq|Y^A zPu`ugLAlCp?L0U!>F;Zuu;aVM2bI~8Xj333 zsC7lgX`xb^ETu!?Bw8FNyQ$U4&W>=On~*_~z-WZIC6s*H>m*Fo>YN z3NqSep3ktdUAbS8m_Vjw$@OzLcpWk*swcy9j=(Zt11%qsS1}G4A(U&PU%nG0<@*JgP<=etYs$Pl@IShl2ReE?BjM En*g&E-T(jq literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N>V&j1Pu5TM6H zgo0G6)?0C%_jEhB-K%m)L|XuI0eVr~(+2J{j)bw=k~v4ztla|Ulh4{tTL z?n7|@R5VB@$Q zBWg2`Xth9#FpXdV%|o0=`*6q(gYKznN2hOuw0YZ4w%_WcASwWbYeV5`xm7xK$OShL zG6m<5k1l&D`YQvspPMAAPA!N`|Kq1i9Ls=JFB$Ws)ESp7)}Xr;B^24}#@(jFBi(wx zMAzan#m4yn4TRx(rF>J%Es53^V1PlN4>qpTBJRUm!wU$8v9f?1hd}uaes)atFl~jf z3|mvj;m|N@y?#TF??W9xatvKQtam21k3xdP$zPvDk=$lsYA?Bh7p~NEtl-6|zjj_) zQ1t(=(XX?U4PQ0VTxMTap50^2ik`E4KFb6`s8nUo;(yt&3gjO4Q7sI070S=2lEb%Z z`(0P9=``1;jT?tkEx-MpQ16gbdFj+ea^%f4vj}&@b3kaTx?Wn|S#&caun#P;owpr^ z*}OPqgZ_?aH$}tY){U&W+rbU0s#cE7!u?)Y*f|rQ{zfdGVjs~2(fZ&kfv`E=xo zinXUoT!}dOjO)=zs&(12$gG=(A+U zCuHOF=LWtU(1Dednc%h`JboeK64+cz8-y0Yk7+1^yM3lwplgw@i?XqZjEFM^_-h0Z z@*BzMK7ViM?i+E-b1U5=bh>3>h#N%FkvtOpAiTrt%rBrS4;{wW z#YEh;zE>EsLm_eFyq|IMThIw)Ro#1BO`vWh!8CFn|>I$Jm(P9-y7 z!he0ilG@?V$p8uo5TM6H zgoUQEay2giu5l#VbH-k@YujY!wvF;B+95U(nst7|ESnDJWk zB%qF40HT=vqlJ58?3j}{ubwXf9G;ktbhzBFy}<`WoH&}tb^3G`NTIh;h&p{1gyppn z)~v1W)p)!Had&G07!;wSyi4MQ{+jy<@m4D@`LH&kp|JUSoVs#F-#jI%1oPVLOWt&g zx5ckOkqc$cUmQ)M2AbmJ!D-r57rIvB>Jv050RoD9#ou#5SAUk&<{SNJ1>M0VD`E_2UH@>7( z2S6vhoDzWXeZ?qcZ9%23RL@y1K!W)cQeH;Uc6ZkX`7s^tz)`|Nl*um)J zJ{eq<2(d=d+Cpi7$j%0c)kbInMA%wt<+aJ-)*bD#_1BbxZ)|xCbL@ctO6~R@_Yax; ztz>7&y$BT!7q(-3!{XjbzOdope4li@9B$gEPsc6ep)BMU=j$b*W(L=2xx4%aHp6O( z7~7&h?CgJ;Y7fxOYMx`k^J-@2HA?d{Nqqb-Nx|}M5-;vQBp9R!+q}?FrR-=x3L{11 zX969$BPXz2{2CKuBWFU)jUhbLXVmrPv>nUqh3+4CF$V;Jk3r<2*J+2=tj2xT%|&ZHd?OR?L2P;|Rb_ANCh zPF{g+^Ao3WzoSl#rc9|q`MH>0@plcedJVZl=KE%i5jp}Oii=6Ioj%WE$eO}I?`J)d z0v84f93fy1zigPkk+j$?-pb1~hneUMuYKNRY_)GY8L#g!H@eW3r_OiO(=HN>$zcI9 EDjqQqh5!Hn literal 566 zcmV-60?GY}0y6{v0SEvc79j+_E$ufVhrCX*AwCnJ$3ujQV~JG-0%N>Vw*U$W5TM6H zgonoJ9)&{i1#gpM}@m{|lw|Ku2CUQS)TLtAvj-K;Vh zb|POEmZojMp*F!d#Dl4|Q+nO#!|4Q7BJN<12^` zl-yXL5{<~-5hWzyM_IY&Tcg3wsr2VW`fTzyc%6EOpf}c)o<_!ls<)pDk>SN`mLbLH zk-ZBZH=A=c_M{2s41k1!dtxNDoX;4*Qh(l>C&6+_+==jkK?>GsS{|R EcZ1Uk8UO$Q diff --git a/test/arguments b/test/arguments new file mode 100644 index 0000000..3112ca4 --- /dev/null +++ b/test/arguments @@ -0,0 +1,63 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +testdir="${MESONCURRENTCONFIGDIR}/_build-arguments/" +mkdir "${testdir}" +mkdir "${testdir}/arguments/" + +readonly helptext="Usage: ./cagebreak [OPTIONS] + + -c Load configuration file from + -e Enable socket + -h Display this help message + -s Show information about the current setup and exit + -v Show the version number and exit + --bs \"bad security\": Enable features with potential security implications (see man page)" + +readonly basicheadless="Cagebreak ${1} is running on Wayland display wayland-.* +Outputs: + \\* HEADLESS-1 +Inputs:" + +RESULT=0 + +# check -c option +## Check without config file +[[ $(2>&1 ./cagebreak -c | head -1 ) = "./cagebreak: option requires an argument -- 'c'" ]] || RESULT=1 +[[ $(2>&1 ./cagebreak -c | tail -n +2 ) = "$helptext" ]] || RESULT=1 +## Check with config file +cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/-c-config" "${testdir}/arguments/" +sed -i "s|CONFIGPATH|${testdir}\/arguments\/result|g" "${testdir}/arguments/-c-config" +WLR_BACKENDS=headless ./cagebreak -c "${testdir}/arguments/-c-config" +sync +[[ $(cat "${testdir}/arguments/result") = "SUCCESS" ]] || RESULT=1 + +# check -e option +## Check without socket +cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/config" "${testdir}/arguments" +readonly oldsocket=$CAGEBREAK_SOCKET +sed -i "s|CONFIGPATH|${testdir}\/arguments\/socket|g" "${testdir}/arguments/config" +(WLR_BACKENDS=headless ./cagebreak -c "${testdir}/arguments/config") +sync +[[ $(cat "${testdir}/arguments/socket") = "${oldsocket}" ]] || RESULT=1 +## Check with socket +cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/config" "${testdir}/arguments" +sed -i "s|CONFIGPATH|$testdir\/arguments\/socket|g" "${testdir}/arguments/config" +(WLR_BACKENDS=headless ./cagebreak -e -c "${testdir}/arguments/config") +sync +[[ ! $(cat "${testdir}/arguments/socket") = "${oldsocket}" ]] || RESULT=1 + +# check -h option +[[ $(./cagebreak -h) = "$helptext" ]] || RESULT=1 + +# check -s option +[[ $(WLR_BACKENDS=headless ./cagebreak -s) =~ ${basicheadless} ]] || RESULT=1 + + +# check -v option +[[ $(./cagebreak -v) = "Cagebreak version $1" ]] || RESULT=1 + +rm -rf "${testdir}" + +exit "${RESULT}" diff --git a/test/build-w-o-warnings b/test/build-w-o-warnings new file mode 100644 index 0000000..3866aff --- /dev/null +++ b/test/build-w-o-warnings @@ -0,0 +1,15 @@ +#! /bin/sh +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +# shellcheck disable=SC2164 +cd "${MESONCURRENTCONFIGDIR}" +echo "Build standard release build" +rm -rf _build-w-o-warnings +meson setup _build-w-o-warnings -Dxwayland=true -Dman-pages=true --buildtype=release --fatal-meson-warnings || RESULT=1 +ninja -C _build-w-o-warnings || RESULT=1 +rm -rf _build-w-o-warnings + +exit "${RESULT}" diff --git a/test/build-w-o-xwayland b/test/build-w-o-xwayland new file mode 100644 index 0000000..6164f6e --- /dev/null +++ b/test/build-w-o-xwayland @@ -0,0 +1,15 @@ +#! /bin/sh +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}" +echo "Build without xwayland" +rm -rf _build-w-o-xwayland +meson setup _build-w-o-xwayland -Dxwayland=false -Dman-pages=false --buildtype=release --fatal-meson-warnings || RESULT=1 +ninja -C _build-w-o-xwayland || RESULT=1 +rm -rf _build-w-o-xwayland + +exit "${RESULT}" diff --git a/test/clang-format b/test/clang-format new file mode 100644 index 0000000..cf7e553 --- /dev/null +++ b/test/clang-format @@ -0,0 +1,26 @@ +#! /bin/sh +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +readonly declared_deps="${*}" +readonly deps="${declared_deps}" + +RESULT=0 + +set -x + +echo "${MESONCURRENTCONFIGDIR}" + +for file in ${deps} +do + echo "${file}" + if (clang-format -Werror --dry-run "${MESONCURRENTCONFIGDIR}/${file}") + then + echo " [x] clang-format" + else + RESULT=1 + echo " [ ] clang-format" + fi +done + +exit "${RESULT}" diff --git a/test/copyright-license b/test/copyright-license new file mode 100644 index 0000000..4fe517f --- /dev/null +++ b/test/copyright-license @@ -0,0 +1,48 @@ +#! /bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +readonly declared_deps="${*}" +readonly hardcoded_deps="meson_options.txt meson.build" +# shellcheck disable=2155,2164,2046 +readonly test_deps=$(cd "${MESONCURRENTCONFIGDIR}" ; find . -type f | grep test/) +# shellcheck disable=2155,2164,2046 +readonly examples_deps=$(cd "${MESONCURRENTCONFIGDIR}" ; find . -type f | grep examples/) +# shellcheck disable=2155,2164,2046 +readonly example_scripts_deps=$(cd "${MESONCURRENTCONFIGDIR}" ; find . -type f | grep example_scripts/) +readonly deps="${declared_deps} ${hardcoded_deps} ${test_deps} ${examples_deps} ${example_scripts_deps}" +# shellcheck disable=2046,2155 +readonly curryear=$(date +%Y) + +RESULT=0 + +for file in ${deps} +do + echo "${file}" + if (grep -q "Copyright.*${curryear}, project-repo and the cagebreak contributors" "$MESONCURRENTCONFIGDIR/${file}") + then + echo " [x] Copyright Notice" + else + RESULT=1 + echo " [ ] Copyright Notice" + fi + if (grep -q "SPDX-License-Identifier: MIT" "$MESONCURRENTCONFIGDIR/${file}") + then + echo " [x] SPDX-License-Identifier" + else + RESULT=1 + echo " [ ] SPDX-License-Identifier" + fi +done + +[[ "${MESONLICENSE}" = "MIT" ]] || RESULT=1 + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}" + +# shellcheck disable=2046,2002 +[[ $(cat LICENSE) = $( cat README.md | tail -$(wc -l LICENSE)) ]] || RESULT=1 + +[[ "Copyright (c) 2020-${curryear} The Cagebreak authors" = $( head -1 LICENSE) ]] || RESULT=1 + +exit "${RESULT}" diff --git a/test/environment-variables b/test/environment-variables new file mode 100644 index 0000000..f1c9fac --- /dev/null +++ b/test/environment-variables @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +testdir="${MESONCURRENTCONFIGDIR}/_build-envvars" +mkdir "${testdir}" +mkdir "${testdir}/envvars/" +mkdir "${testdir}/cagebreak" + +RESULT=0 + +# CAGEBREAK_SOCKET (duplicate of arguments test) +## Check without socket +cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/config" "${testdir}/envvars" +readonly oldsocket="${CAGEBREAK_SOCKET}" +sed -i "s|CONFIGPATH|$testdir\/envvars\/socket|g" "${testdir}/envvars/config" +(WLR_BACKENDS=headless ./cagebreak -c "${testdir}/envvars/config") +sync +[[ $(cat "${testdir}/envvars/socket") = "${oldsocket}" ]] || RESULT=1 +## Check with socket +cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/config" "${testdir}/envvars" +sed -i "s|CONFIGPATH|$testdir\/envvars\/socket|g" "${testdir}/envvars/config" +(WLR_BACKENDS=headless ./cagebreak -e -c "${testdir}/envvars/config") +sync +[[ ! $(cat "${testdir}/socket") = "${oldsocket}" ]] || RESULT=1 + +# XDG_CONFIG_HOME +cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/env-var-config" "${testdir}/cagebreak/config" +sed -i "s|CONFIGPATH|${testdir}\/cagebreak\/result|g" "${testdir}/cagebreak/config" +XDG_CONFIG_HOME="${testdir}/" WLR_BACKENDS=headless ./cagebreak +sync +[[ $(cat "${testdir}/cagebreak/result") = "SUCCESS" ]] || RESULT=1 + +# The XKB_DEFAULT_* family of variables is not found in the source code +# of Cagebreak but necessary to configure software for use with Cagebreak. + +rm -rf "${testdir}" + +exit "${RESULT}" diff --git a/test/illegal-strings b/test/illegal-strings new file mode 100644 index 0000000..5ae9dc0 --- /dev/null +++ b/test/illegal-strings @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}" + +# Check that no TODO statements remain in the release directory +if ! grep -Rq "TODO" . +then + echo "[x] TODO" +else + RESULT=1 + echo "[ ] TODO" +fi + +# Check that Cagebreak does not falsely claim to be POSIX compliant +if ! grep -Rq "_POSIX_C_SOURCE" . +then + echo "[x] _POSIX_C_SOURCE" +else + RESULT=1 + echo "[ ] _POSIX_C_SOURCE" +fi + + +exit "${RESULT}" diff --git a/test/scan-build b/test/scan-build new file mode 100644 index 0000000..562fb42 --- /dev/null +++ b/test/scan-build @@ -0,0 +1,14 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}" +rm -rf _build-scan-build +meson setup _build-scan-build -Dxwayland=true -Dman-pages=true --buildtype=release || RESULT=1 +SCANBUILD="$(pwd)/test/testing-configurations/my-scan-build" ninja -C _build-scan-build scan-build || RESULT=1 +rm -rf _build-scan-build + +exit "${RESULT}" diff --git a/test/shellcheck b/test/shellcheck new file mode 100644 index 0000000..0727178 --- /dev/null +++ b/test/shellcheck @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +set -x +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}/test" +# shellcheck disable=2046 +shellcheck --source-path=../example_scripts/ $(ls -Itesting-configurations) || RESULT=1 + +cd "${MESONCURRENTCONFIGDIR}/example_scripts/" || RESULT=1 +shellcheck ./* + +exit "${RESULT}" diff --git a/test/testing-configurations/-c-config b/test/testing-configurations/-c-config new file mode 100644 index 0000000..a769e73 --- /dev/null +++ b/test/testing-configurations/-c-config @@ -0,0 +1,4 @@ +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT +exec (echo "SUCCESS" > CONFIGPATH ) +quit diff --git a/test/testing-configurations/config b/test/testing-configurations/config new file mode 100644 index 0000000..9925aec --- /dev/null +++ b/test/testing-configurations/config @@ -0,0 +1,4 @@ +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT +exec (echo $CAGEBREAK_SOCKET > CONFIGPATH) +quit diff --git a/test/testing-configurations/env-var-config b/test/testing-configurations/env-var-config new file mode 100644 index 0000000..a769e73 --- /dev/null +++ b/test/testing-configurations/env-var-config @@ -0,0 +1,4 @@ +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT +exec (echo "SUCCESS" > CONFIGPATH ) +quit diff --git a/test/testing-configurations/my-scan-build b/test/testing-configurations/my-scan-build new file mode 100755 index 0000000..526f1dd --- /dev/null +++ b/test/testing-configurations/my-scan-build @@ -0,0 +1,5 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +scan-build --status-bugs "$@" diff --git a/test/versions b/test/versions new file mode 100644 index 0000000..b408c71 --- /dev/null +++ b/test/versions @@ -0,0 +1,42 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +readonly newversion="${1}" +# shellcheck disable=2155 +readonly oldversion=$(git describe --match=master --abbrev=0) + +RESULT=0 + +# meson.build version +if [[ $(vercmp "${newversion}" "${oldversion}") -gt 0 ]] +then + echo "[x] meson.build version respects semantic versioning" +else + RESULT=1 + echo "[ ] meson.build version is NOT semantic version" +fi + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}" + +for file in man/* +do + if [[ $(head -1 "${file}" | cut -d ' ' -f 3 | rev | cut -c2- | rev ) = "${newversion}" ]] + then + echo "[x] ${file} version is meson.build version" + else + RESULT=1 + echo "[ ] ${file} version is NOT meson.build version" + fi +done + +if head -3 README.md | tail -1 | grep -q "minversion=${newversion}" +then + echo "[x] README.md repology minversion" +else + RESULT=1 + echo "[ ] README.md repology minversion" +fi + +exit "${RESULT}" diff --git a/util.c b/util.c index 455f306..f8c7a82 100644 --- a/util.c +++ b/util.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #include diff --git a/util.h b/util.h index ef3f532..b509a00 100644 --- a/util.h +++ b/util.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_UTIL_H #define CG_UTIL_H diff --git a/view.c b/view.c index 74c31b8..99e2e7c 100644 --- a/view.c +++ b/view.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L diff --git a/view.h b/view.h index 99e3e65..a3b61ed 100644 --- a/view.h +++ b/view.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_VIEW_H #define CG_VIEW_H @@ -39,6 +39,7 @@ struct cg_view { struct cg_view_impl { pid_t (*get_pid)(const struct cg_view *view); + char *(*get_title)(const struct cg_view *view); bool (*is_primary)(const struct cg_view *view); void (*activate)(struct cg_view *view, bool activate); void (*close)(struct cg_view *view); diff --git a/workspace.c b/workspace.c index 1caff0d..3f84c6f 100644 --- a/workspace.c +++ b/workspace.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L diff --git a/workspace.h b/workspace.h index e0f2473..b669cec 100644 --- a/workspace.h +++ b/workspace.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_WORKSPACE_H #define CG_WORKSPACE_H diff --git a/xdg_shell.c b/xdg_shell.c index fc251c7..afa3352 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -110,6 +110,13 @@ get_pid(const struct cg_view *view) { return pid; } +static char * +get_title(const struct cg_view *view) { + const struct cg_xdg_shell_view *xdg_shell_view = + xdg_shell_view_from_const_view(view); + return xdg_shell_view->xdg_surface->toplevel->title; +} + static bool is_primary(const struct cg_view *view) { const struct cg_xdg_shell_view *xdg_shell_view = @@ -208,6 +215,7 @@ handle_xdg_shell_surface_destroy(struct wl_listener *listener, void *_data) { } static const struct cg_view_impl xdg_shell_view_impl = {.get_pid = get_pid, + .get_title = get_title, .is_primary = is_primary, .activate = activate, diff --git a/xdg_shell.h b/xdg_shell.h index e066208..fd80b99 100644 --- a/xdg_shell.h +++ b/xdg_shell.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_XDG_SHELL_H #define CG_XDG_SHELL_H diff --git a/xwayland.c b/xwayland.c index f601a0f..ece9e5a 100644 --- a/xwayland.c +++ b/xwayland.c @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #include "config.h" @@ -46,6 +46,13 @@ get_pid(const struct cg_view *view) { return surf->pid; } +static char * +get_title(const struct cg_view *view) { + const struct cg_xwayland_view *xwayland_view = + xwayland_view_from_const_view(view); + return xwayland_view->xwayland_surface->title; +} + static bool is_primary(const struct cg_view *view) { const struct cg_xwayland_view *xwayland_view = @@ -157,6 +164,7 @@ handle_xwayland_surface_destroy(struct wl_listener *listener, void *_data) { } static const struct cg_view_impl xwayland_view_impl = { + .get_title = get_title, .get_pid = get_pid, .is_primary = is_primary, .activate = activate, diff --git a/xwayland.h b/xwayland.h index cde30c5..71a0b7a 100644 --- a/xwayland.h +++ b/xwayland.h @@ -1,5 +1,5 @@ // Copyright 2020 - 2023, project-repo and the cagebreak contributors -// SPDX -License-Identifier: MIT +// SPDX-License-Identifier: MIT #ifndef CG_XWAYLAND_H #define CG_XWAYLAND_H From bea18c7a6f0f709251d6e7670eed5d3d9ef1b02b Mon Sep 17 00:00:00 2001 From: project-repo Date: Mon, 17 Apr 2023 22:17:06 +0200 Subject: [PATCH 12/19] Release 2.1.1 - Adjust dependency versions - Add release tests - Add a quick installation script - Add small utility scripts - Add note on review and developer certificate of origin (DCO) - Add note on accessibility --- .gitignore | 2 + Hashes.md | 20 ++ README.md | 249 ++++++++++++++---- man/cagebreak-config.5.md | 2 +- man/cagebreak-socket.7.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 38 ++- meson_options.txt | 2 + release-non-auto-checks/Bugs.md | 2 + release-non-auto-checks/FAQ.md | 2 + release-non-auto-checks/SECURITY.md | 2 + release-non-auto-checks/WLR_XDG_VERSION | 2 + release-non-auto-checks/changelog-major-minor | 2 + release-non-auto-checks/internal-wiki | 2 + release-non-auto-checks/meson-epoch | 2 + release-non-auto-checks/release-note | 2 + .../reproducibility-checked | 2 + .../security-to-man-page-info-transfer | 2 + scripts/adjust-epoch | 13 + scripts/create-release-artefacts | 40 +++ scripts/create-signatures | 37 +++ scripts/fuzz | 17 ++ scripts/git-tag | 8 + scripts/install-development-environment | 13 + scripts/output-hashes | 50 ++++ scripts/set-version | 20 ++ signatures/2.1.0-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.1.0-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.1.0-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.1.0-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes test/check-artefacts | 27 ++ test/copyright-license | 4 +- test/git-tag | 16 ++ test/gpg-signatures | 43 +++ test/gpg-validity | 46 ++++ test/hashes-md | 53 ++++ test/non-auto-tests | 25 ++ test/shellcheck | 6 +- 42 files changed, 688 insertions(+), 67 deletions(-) create mode 100644 release-non-auto-checks/Bugs.md create mode 100644 release-non-auto-checks/FAQ.md create mode 100644 release-non-auto-checks/SECURITY.md create mode 100644 release-non-auto-checks/WLR_XDG_VERSION create mode 100644 release-non-auto-checks/changelog-major-minor create mode 100644 release-non-auto-checks/internal-wiki create mode 100644 release-non-auto-checks/meson-epoch create mode 100644 release-non-auto-checks/release-note create mode 100644 release-non-auto-checks/reproducibility-checked create mode 100644 release-non-auto-checks/security-to-man-page-info-transfer create mode 100755 scripts/adjust-epoch create mode 100755 scripts/create-release-artefacts create mode 100755 scripts/create-signatures create mode 100755 scripts/fuzz create mode 100755 scripts/git-tag create mode 100755 scripts/install-development-environment create mode 100755 scripts/output-hashes create mode 100755 scripts/set-version create mode 100644 signatures/2.1.0-cagebreak-config.5.sig create mode 100644 signatures/2.1.0-cagebreak-socket.7.sig create mode 100644 signatures/2.1.0-cagebreak.1.sig create mode 100644 signatures/2.1.0-cagebreak.sig create mode 100644 test/check-artefacts create mode 100644 test/git-tag create mode 100644 test/gpg-signatures create mode 100644 test/gpg-validity create mode 100644 test/hashes-md create mode 100644 test/non-auto-tests diff --git a/.gitignore b/.gitignore index 378eac2..a91faf5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ build +fuzz_corpus +fuzzing-directory diff --git a/Hashes.md b/Hashes.md index 4e28e1e..e5da651 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.1.1 cagebreak + + * sha 256: 8632e7e49637e5a3e7ab425a05fbd63d71cf6025143c89d196f309dbf4efdd57 + * sha 512: ca853aca80bde974f00e4cfcb21a77159d2f9f639342e92d049a0c5290a57094a1b2b1f28ac76ebdf89cf76384bb1caca45813d25ba5ef8ba8996e8c10e51e7a + +2.1.1 cagebreak.1 + + * sha 256: 1d56762bcbe4ba5b9015dda3c19ab1d628d08c7a7c731042643c9f2e59cf3a7c + * sha 512: e421da32e8d6f9eec4559c53614427900fd7ae5c17bf9b9fdfa90764017d5d90c08e10e737aacbe46ed97966dbc4c76944b54bce367925fd9899ff8e41fa7947 + +2.1.1 cagebreak-config.5 + + * sha 256: f4405bd650d4cab29e536651f0d45443ebe51628c4dfef75576923ec903d781e + * sha 512: 451c85c7a02f724824499a43929ef6f05eee4d4c666186f766163c01e36503a36b7f6bbf2d5cb632cbd2cd0740b0b3becc2d8c388e914cb0bacfe6134a6ada92 + +2.1.1 cagebreak-socket.7 + + * sha 256: cd67c9de727d6f8727269bc06a80aa77ede26b5652eb4ab35c898939711ae429 + * sha 512: a572710972b19a3872269fd2c52f1afd09a11dd621b4108f6ec3cde383c088c52782d5a240b001328257a66143a045fbf967d327b434e2ca32c2ffafc3b18b7f + 2.1.0 cagebreak * sha 256: 0c90ba529ffc916306a1ca04d4c56a800c62a98d184d3cfcc2ce67dcdffad324 diff --git a/README.md b/README.md index f933980..aca03a6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.1.0)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.1.1)](https://repology.org/project/cagebreak/versions) ## Quick Introduction @@ -260,6 +260,156 @@ need to ask for the distribution the user was having the issue on.)). You should use Arch Linux if you want to modify Cagebreak for yourself. +### Review Requirements + +Project-repo will review your proposal before your implementation for feasibility +and desirability. After your pull request, the code will be reviewed in conjunction +with all other changes before the release as per the release procedure. + +All reviews performed by project-repo are verified by at least two people internally. + +### Developer Certificate of Origin (DCO) + +On any pull requests please include a + +``` +signed-off-by: YOUR IDENTIFIER OR NAME +``` + +DCO statement. + +By doing this you claim that you are legally allowed to contribute the +code and agree to let project-repo publish it under the MIT License. + +#### Development Environment + +CAVEAT: This script works exclusively on Arch Linux, which, as outlined above, +is the development distribution of Cagebreak. + +Cloning the Cagebreak repository and building it is sufficient as a starting point. + +All other dependencies can be installed by invoking + +``` +meson compile devel-install -C build +``` + +if meson is already available or + +``` +./scripts/install-development-environment +``` + +otherwise. + +#### Scripts + +Cagebreak provides a few convenience tools to facilitate development. + +##### Fuzzing + +If your fuzzing corpus is located in the directory `fuzz_corpus` you can +just call: + +``` +meson compile fuzz -C build +``` + +If you want to use a different directory, configure cagebreak with +`-Dcorpus=OTHERDIRECTORY` or call `./scripts/fuzz OTHERDIRECTORY`. + +##### Adjusting Epoch + +To facilitate the creation of reproducible man pages an arbitrary release +time has to be set in `meson.build`: + +``` +meson compile adjust-epoch -C build +``` + +or + +``` +./scripts/adjust-epoch +``` + +##### Git tag + +If you are on the master branch, everything is ready and you want to create +a release tag you can call: + +``` +meson compile git-tag -C build +``` + +If you want to use another signing key than the prespecified one, configure +Cagebreak with `-Dgpg_id=GPGID`. + +``` +./scripts/git-tag GPGID CBVERSION +``` + +can be used alternatively. + +##### Output Hashes + +Hashes of release versions of all binaries can be output to `local-hashes.txt` +via: + +``` +meson compile output-hashes -C build +``` + +Or + +``` +./scripts/output-hashes VERSION +``` + +if meson is unavailable. + +##### Create Signatures + +Creation of signatures for releases can be achieved through: + +``` +meson compile create-sigs -C build +``` + +Configure Cagebreak with `-Dgpg_id=GPGID` for a different gpg signing +key. + +Without meson use: + +``` +./scripts/create-signatures GPGID +``` + +##### Set Version Number + +Once the version number is set within meson.build, you can use + +``` +meson compile set-ver -C build +``` + +to set the version number in the man pages and README repology minversion. + +Use of the script without meson is discouraged because meson.build is +not touched by the script. + +##### Create Release Artefacts + +The following command generates the release artefacts which must be created +once a release is completely ready to be published (the commit is tagged with +the version of the master branch, etc.): + +``` +meson compile create-artefacts -C build +``` + +Use of the script version is discouraged. + ### GCC and -fanalyzer Cagebreak should compile with any reasonably new gcc or clang. Consider @@ -312,6 +462,11 @@ There are four test suites: * Note that this is only expected to pass just before a release. This checks mostly administrative things to check that a release is ready. + * Note that non-auto tests are files in `release-non-auto-checks` + and have to contain the release version and current date in + YYYY-mm-dd format on seperate lines. This is our imperfect attempt + to guarantee some hard-to-automate checks are carried out before + a release is undertaken. Every commit should pass at least the basic and devel suites. @@ -359,7 +514,7 @@ find bugs in other areas of the code. #### Caveat Currently, there are memory leaks which do not seem to stem from our code but rather -the code of wl-roots or some other library we depend on. We are working on the problem. +the code of wlroots or some other library we depend on. We are working on the problem. In the meantime, add `-Db_detect-leaks=0` to the meson command to exclude memory leaks. ### Reproducible Builds @@ -456,53 +611,47 @@ The release procedure outlines the process for a release to occur. * [ ] `git checkout development` * [ ] `git pull origin development` * [ ] `git push origin development` - * [ ] New semantic version number determined - * [ ] Adjust version number - * [ ] meson.build - * [ ] git tag - * [ ] Relevant Documentation completed + * [ ] Arch Build System is up to date + * [ ] `meson test -C build/` just to get an overview + * [ ] Update internal wiki + * [ ] Adjust version number in meson.build + * [ ] `meson compile set-ver -C build` + * [ ] Add new files to meson.build or hardcoded testing variable + * [ ] Commit changes + * [ ] `git push origin development` + * [ ] Complete relevant documentation * [ ] New features + * [ ] tests added and old test scripts adjusted * [ ] man pages * [ ] cagebreak * [ ] cagebreak-config * [ ] cagebreak-socket * [ ] example config - * [ ] Set EPOCH to release day in man generation in meson.build * [ ] FAQ.md * [ ] Changelog.md for major and minor releases but not patches - * [ ] Check features for SECURITY.md relevance (changes to socket scope - for example) + * [ ] Check changes for SECURITY.md relevance (changes to socket scope for example) * [ ] Synchronize any socket changes to cagebreak-socket man page - * [ ] Updated internal wiki - * [ ] Added new files to meson.build or hardcoded testing variable - * [ ] Fixed bugs documented in Bugs.md + * [ ] Document fixed bugs in Bugs.md * [ ] Include issue discussion from github, where applicable + * [ ] Commit changes + * [ ] `git push origin development` * [ ] Testing * [ ] Manual testing - * [ ] Libfuzzer testing - * [ ] Arch Build System is up to date - * [ ] wlr_xdg_shell version check - * [ ] Cagebreak is reproducible on multiple machines - * [ ] Documented reproducible build artefacts - * [ ] Hashes of the artefacts in Hashes.md - * [ ] Renamed previous signatures - * [ ] Created gpg signature of the artefacts - * [ ] `gpg --detach-sign -u keyid cagebreak` - * [ ] `gpg --detach-sign -u keyid cagebreak.1` - * [ ] `gpg --detach-sign -u keyid cagebreak-config.5` - * [ ] `gpg --detach-sign -u keyid cagebreak-socket.7` - * [ ] `meson test -C build` + * [ ] `meson compile fuzz -C build` for at least one hour + * [ ] Complete release-non-auto-checks + * [ ] Use `meson compile output-hashes -C build` to add Hashes or aid in repro check + * [ ] `meson compile create-signatures -C build` + * [ ] Commit and push signatures, hashes and non-auto-check files + * [ ] `meson test -C build` passes everything except some release tests * [ ] `git add` relevant files * [ ] `git commit` * [ ] `git push origin development` - * [ ] Determined commit and tag message (Start with "Release version_number\n\n") - * [ ] Mentioned fixed Bugs.md issues ("Fixed Issue n") - * [ ] Mentioned other important changes * [ ] `git checkout master` * [ ] `git merge --squash development` * [ ] `git commit` and insert message - * [ ] `git tag -u keyid version HEAD` and insert message - * [ ] `git tag -v version` and check output + * [ ] `meson compile git-tag -C build` + * [ ] `meson compile create-artefacts -C build` + * [ ] `meson test -C build` THIS MUST PASS WITHOUT ANY FAILURES WHATSOEVER * [ ] `git push --tags origin master` * [ ] `git checkout development` (merge to development depends on whether release was a hotfix) * [ ] `git merge master` @@ -510,33 +659,8 @@ The release procedure outlines the process for a release to occur. * [ ] `git checkout hotfix` (hotfix is to be kept current with master after releases) * [ ] `git merge master` * [ ] `git push --tags origin hotfix` - * [ ] `git archive --prefix=cagebreak/ -o release_version.tar.gz tags/version .` - * [ ] Create release-artefacts_version.tar.gz - * [ ] `mkdir release-artefacts_version` - * [ ] `cp build/cagebreak release-artefacts_version/` - * [ ] `cp build/cagebreak.sig release-artefacts_version/` - * [ ] `cp build/cagebreak.1 release-artefacts_version/` - * [ ] `cp build/cagebreak.1.sig release-artefacts_version/` - * [ ] `cp build/cagebreak-config.5 release-artefacts_version/` - * [ ] `cp build/cagebreak-config.5.sig release-artefacts_version/` - * [ ] `cp build/cagebreak-socket.7 release-artefacts_version/` - * [ ] `cp build/cagebreak-socket.7.sig release-artefacts_version/` - * [ ] `cp LICENSE release-artefacts_version/` - * [ ] `cp README.md release-artefacts_version/` - * [ ] `cp SECURITY.md release-artefacts_version/` - * [ ] `cp FAQ.md release-artefacts_version/` - * [ ] `export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) ; tar --sort=name --mtime= --owner=0 --group=0 --numeric-owner -czf release-artefacts_version.tar.gz release-artefacts_version` - * [ ] Checked archive - * [ ] tar -xvf release_version.tar.gz - * [ ] cd cagebreak - * [ ] meson setup build -Dxwayland=true -Dman-pages=true --buildtype=release - * [ ] ninja -C build - * [ ] gpg --verify ../signatures/cagebreak.sig build/cagebreak - * [ ] cd .. - * [ ] rm -rf cagebreak - * [ ] `gpg --detach-sign -u keyid release_version.tar.gz` - * [ ] `gpg --detach-sign -u keyid release-artefacts_version.tar.gz` * [ ] Upload archives and signatures as release assets + * [ ] Manage package release ## Roadmap @@ -600,6 +724,17 @@ independent of github, in case this service is unavailable. For other means of contacting the Cagebreak authors and for security issues see [SECURITY.md](SECURITY.md). +## Accessibility + + * We use text input/output to interact with the user whenever possible. For + example, sending text-based commands to the cagebreak sockets allows + one to change every configurable feature of cagebreak. + * Color is displayed but never a vital part to operating cagebreak. + * Text size can be increased and background color adjusted using text commands. + * There is no screen reader support per se but using a screen reader on socket output + would work and cagebreak does not preclude the use of a screen reader + for any software run with it. + ## Contributors * Aisha Tammy diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 1c65b78..bb04547 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.1.0" "Cagebreak Manual" +cagebreak-config(5) "VERSION 2.1.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index b8e8d9c..19b7370 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.1.0" "Cagebreak Manual" +cagebreak-socket(7) "VERSION 2.1.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index b3fd209..fdc2da1 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.1.0" "Cagebreak Manual" +cagebreak(1) "VERSION 2.1.1" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index f9708e7..26b0746 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.1.0', +version : '2.1.1', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -202,8 +202,8 @@ cagebreak_dependencies_dict = { reproducible_build_versions = { 'server_protos': '-1', 'wayland_server': '1.19.0', - 'wayland_client': '1.21.0', - 'wayland_cursor': '1.21.0', + 'wayland_client': '1.22.0', + 'wayland_cursor': '1.22.0', 'wlroots': '0.16.2', 'xkbcommon': '1.5.0', 'fontconfig': '2.14.2', @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1680540192 + secssinceepoch = 1681758922 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') @@ -344,6 +344,30 @@ summary = [ ] message('\n'.join(summary)) +run_target('devel-install', + command : ['scripts/install-development-environment']) + +run_target('fuzz', + command : ['scripts/fuzz', get_option('corpus')]) + +run_target('adjust-epoch', + command : ['scripts/adjust-epoch']) + +run_target('git-tag', + command : ['scripts/git-tag', get_option('gpg_id'), meson.project_version()]) + +run_target('output-hashes', + command : ['scripts/output-hashes', meson.project_version()]) + +run_target('create-sigs', + command : ['scripts/create-signatures', get_option('gpg_id')]) + +run_target('set-ver', + command : ['scripts/set-version', meson.project_version()]) + +run_target('create-artefacts', + command : ['scripts/create-release-artefacts', get_option('gpg_id'), meson.project_version()]) + # Test Suite test('Build without warnings', find_program('test/build-w-o-warnings'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') @@ -351,7 +375,13 @@ test('Build without xwayland', find_program('test/build-w-o-xwayland'), env : [ test('Copyright and LICENSE', find_program('test/copyright-license'), args : [ cagebreak_main_file + cagebreak_source_strings + cagebreak_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()), ''.join('MESONLICENSE=', meson.project_license())], suite: 'devel' ) test('Clang-format (formatting check)', find_program('test/clang-format'), args : [ cagebreak_main_file + cagebreak_source_strings + cagebreak_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') test('Shellcheck (script linting)', find_program('test/shellcheck'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('GPG key validity', find_program('test/gpg-validity'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') test('Scan-build (static analysis)', find_program('test/scan-build'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel-long') test('Arguments', find_program('test/arguments'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic') test('Environment Variables', find_program('test/environment-variables'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic') test('Semantic versioning', find_program('test/versions'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release') +test('Signature validity', find_program('test/gpg-signatures'), suite: 'release') +test('Hashes.md', find_program('test/hashes-md'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release') +test('Non-auto tests', find_program('test/non-auto-tests'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release') +test('Git tag', find_program('test/git-tag'), args : [ meson.project_version() ], suite: 'release') +test('Release-artefacts', find_program('test/check-artefacts'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release') diff --git a/meson_options.txt b/meson_options.txt index b7fc956..eba2f60 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -4,3 +4,5 @@ option('xwayland', type: 'boolean', value: 'false', description: 'Enable support option('man-pages', type: 'boolean', value: 'false', description: 'Build man pages (requires pandoc)') option('fuzz', type: 'boolean', value: 'false', description: 'Enable building fuzzer targets') option('version_override', type: 'string', description: 'Set the project version to the string specified. Used for creating hashes for reproducible builds.') +option('corpus', type: 'string', value: 'fuzz_corpus', description: 'Set fuzzing corpus directory') +option('gpg_id', type: 'string', value: '4E82C72C6B3E58A7BC4FF8554909F84CA83BB867', description: 'Set gpg signing key for cagebreak') diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/Bugs.md @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/FAQ.md @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/SECURITY.md @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/changelog-major-minor @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/internal-wiki @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/meson-epoch b/release-non-auto-checks/meson-epoch new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/meson-epoch @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/release-note @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/reproducibility-checked @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer new file mode 100644 index 0000000..aa7d21e --- /dev/null +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -0,0 +1,2 @@ +2.1.1 +2023-04-17 diff --git a/scripts/adjust-epoch b/scripts/adjust-epoch new file mode 100755 index 0000000..362c840 --- /dev/null +++ b/scripts/adjust-epoch @@ -0,0 +1,13 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +if [[ -n ${MESON_SOURCE_ROOT} ]] +then + # shellcheck disable=2164 + cd "${MESON_SOURCE_ROOT}" +fi + +# shellcheck disable=2034 +ssepoch=$(date +%s) +sed -i -e "/secssinceepoch \=/s/[0-9]*$/$ssepoch/" meson.build diff --git a/scripts/create-release-artefacts b/scripts/create-release-artefacts new file mode 100755 index 0000000..4b16167 --- /dev/null +++ b/scripts/create-release-artefacts @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +if [[ -n ${MESON_SOURCE_ROOT} ]] +then + # shellcheck disable=2164 + cd "${MESON_SOURCE_ROOT}" +fi + +readonly gpg_id="${1}" +readonly version="${2}" + +git archive --prefix=cagebreak/ -o "release_${version}.tar.gz" "tags/${version}" . + +rm -rf "release-artefacts_${version}" +mkdir "release-artefacts_${version}" + +rm -rf temp-rel-artefacts +meson setup temp-rel-artefacts -Dxwayland=true -Dman-pages=true --buildtype=release +ninja -C temp-rel-artefacts + +cp LICENSE "release-artefacts_${version}" +cp SECURITY.md "release-artefacts_${version}" +cp FAQ.md "release-artefacts_${version}" +cp README.md "release-artefacts_${version}" +cp temp-rel-artefacts/cagebreak "release-artefacts_${version}" +cp temp-rel-artefacts/cagebreak.1 "release-artefacts_${version}" +cp temp-rel-artefacts/cagebreak-config.5 "release-artefacts_${version}" +cp temp-rel-artefacts/cagebreak-socket.7 "release-artefacts_${version}" +cp signatures/cagebreak*.sig "release-artefacts_${version}" + +# shellcheck disable=2155 +export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) ; tar --sort=name --mtime= --owner=0 --group=0 --numeric-owner -czf "release-artefacts_${version}.tar.gz" "release-artefacts_${version}" + +gpg -u "${gpg_id}" --detach-sign "release-artefacts_${version}.tar.gz" +gpg -u "${gpg_id}" --detach-sign "release_${version}.tar.gz" + + +rm -rf temp-rel-artefacts diff --git a/scripts/create-signatures b/scripts/create-signatures new file mode 100755 index 0000000..3292374 --- /dev/null +++ b/scripts/create-signatures @@ -0,0 +1,37 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +if [[ -n ${MESON_SOURCE_ROOT} ]] +then + # shellcheck disable=2164 + cd "${MESON_SOURCE_ROOT}" +fi + +readonly gpg_id="${1}" +# shellcheck disable=2155 +readonly old_tags=$(git tag| tail -1) + +mv signatures/cagebreak.sig "signatures/${old_tags}-cagebreak.sig" +mv signatures/cagebreak.1.sig "signatures/${old_tags}-cagebreak.1.sig" +mv signatures/cagebreak-config.5.sig "signatures/${old_tags}-cagebreak-config.5.sig" +mv signatures/cagebreak-socket.7.sig "signatures/${old_tags}-cagebreak-socket.7.sig" + +git add "signatures/${old_tags}-cagebreak.sig" +git add "signatures/${old_tags}-cagebreak.1.sig" +git add "signatures/${old_tags}-cagebreak-config.5.sig" +git add "signatures/${old_tags}-cagebreak-socket.7.sig" + +rm -rf temp-sigs +meson setup temp-sigs -Dxwayland=true -Dman-pages=true --buildtype=release +ninja -C temp-sigs + +gpg -u "${gpg_id}" --detach-sign temp-sigs/cagebreak +gpg -u "${gpg_id}" --detach-sign temp-sigs/cagebreak.1 +gpg -u "${gpg_id}" --detach-sign temp-sigs/cagebreak-config.5 +gpg -u "${gpg_id}" --detach-sign temp-sigs/cagebreak-socket.7 + +cp temp-sigs/*.sig signatures/ + + +rm -rf temp-sigs diff --git a/scripts/fuzz b/scripts/fuzz new file mode 100755 index 0000000..7f227ec --- /dev/null +++ b/scripts/fuzz @@ -0,0 +1,17 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +readonly fuzzing_corpus="${1}" + +if [[ -n ${MESON_SOURCE_ROOT} ]] +then + # shellcheck disable=2164 + cd "${MESON_SOURCE_ROOT}" +fi + +rm -rf fuzzing-directory +CC=clang meson setup fuzzing-directory -Dfuzz=true -Db_sanitize=address,undefined -Db_lundef=false -Db_detect-leaks=0 +ninja -C fuzzing-directory/ +WLR_BACKENDS=headless ./fuzzing-directory/fuzz-parse -jobs=12 -max_len=50000 -close_fd_mask=3 "${fuzzing_corpus}" +rm -rf fuzzing-directory diff --git a/scripts/git-tag b/scripts/git-tag new file mode 100755 index 0000000..bd8e541 --- /dev/null +++ b/scripts/git-tag @@ -0,0 +1,8 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +readonly gpg_id="${1}" +readonly version="${2}" + +git tag -u "${gpg_id}" "${version}" HEAD diff --git a/scripts/install-development-environment b/scripts/install-development-environment new file mode 100755 index 0000000..d1b9793 --- /dev/null +++ b/scripts/install-development-environment @@ -0,0 +1,13 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +sudo pacman -Syu --noconfirm git grep sed xev meson ninja clang gcc shellcheck jq openbsd-netcat gnupg binutils alacritty wlroots wayland libxkbcommon cairo pango fontconfig libinput libevdev systemd-libs # systemd-libs is included because of libudev + +if [[ -n ${MESON_SOURCE_ROOT} ]] +then + # shellcheck disable=2164 + cd "${MESON_SOURCE_ROOT}" +fi + +gpg --import keys/* diff --git a/scripts/output-hashes b/scripts/output-hashes new file mode 100755 index 0000000..cf7cacf --- /dev/null +++ b/scripts/output-hashes @@ -0,0 +1,50 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +if [[ -n ${MESON_SOURCE_ROOT} ]] +then + # shellcheck disable=2164 + cd "${MESON_SOURCE_ROOT}" +fi + +readonly version="${1}" + +rm -rf hashes +meson setup hashes -Dxwayland=true -Dman-pages=true --buildtype=release +ninja -C hashes + +cb256=$(sha256sum hashes/cagebreak | cut -d " " -f1) +cb512=$(sha512sum hashes/cagebreak | cut -d " " -f1) + +cb1man256=$(sha256sum hashes/cagebreak.1 | cut -d " " -f1) +cb1man512=$(sha512sum hashes/cagebreak.1 | cut -d " " -f1) + +cb5man256=$(sha256sum hashes/cagebreak-config.5 | cut -d " " -f1) +cb5man512=$(sha512sum hashes/cagebreak-config.5 | cut -d " " -f1) + +cb7man256=$(sha256sum hashes/cagebreak-socket.7 | cut -d " " -f1) +cb7man512=$(sha512sum hashes/cagebreak-socket.7 | cut -d " " -f1) + +echo "${version} cagebreak + + * sha 256: ${cb256} + * sha 512: ${cb512} + +${version} cagebreak.1 + + * sha 256: ${cb1man256} + * sha 512: ${cb1man512} + +${version} cagebreak-config.5 + + * sha 256: ${cb5man256} + * sha 512: ${cb5man512} + +${version} cagebreak-socket.7 + + * sha 256: ${cb7man256} + * sha 512: ${cb7man512} +" > local-hashes.txt + +rm -rf hashes diff --git a/scripts/set-version b/scripts/set-version new file mode 100755 index 0000000..c4506cb --- /dev/null +++ b/scripts/set-version @@ -0,0 +1,20 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +# TODO man pages + +if [[ -n ${MESON_SOURCE_ROOT} ]] +then + # shellcheck disable=2164 + cd "${MESON_SOURCE_ROOT}" +fi + +# shellcheck disable=2034 +version="${1}" +sed -i -e "s/minversion\=[0-9]*\.[0-9]*.[0-9]*/minversion=$version/" README.md + + +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak.1.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak-config.5.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak-socket.7.md diff --git a/signatures/2.1.0-cagebreak-config.5.sig b/signatures/2.1.0-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..25072cbc7ec479dc03f8b0e58fb181f393b6019f GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@H2?|;5J?I6 zOsG4!XTI7G{wRJJEi`J}KeQfb1JU@66Z3T<6NTy#--hMh*c8j3d2~hbi^ZX=-TrKn ztD7j~V&53Q9i%4h8U#_7hK7oj`CIlD=;Mc4GwQ>a)J-YmdG`Vl;8s)}69L&?L5d~& z$20iJNFBNWK|tDpKg-~|d82IW#CC`j7nDWB&(z58T;2M2wvtE4dP=d?zp?WD0=p9* zUPU`tsJ{U-0GdW{DSNRrlKUGFVqhO3@k!$cL3*Qp6odwyB-0xQnq)@N!PVe$1`L>|k=$CLVHK?O+TkwoVUh!Xj=V&t>{#C*0%ot(iIdi&^gyH8KlU zhBT+I4>=Rc$+O;JZ!`T~Bm7w_#GKcp?kq#s$P0|Y^(i`zme%V+VSapC^`l@oRL1{@BcO}re zf)i0-Wdr6R<0JhvON1>o?yPvCFw8vYk{DbTrXy>~v!h&yhCb5?O?zZ$sp$kzmLK)j EGK$X>3IG5A literal 0 HcmV?d00001 diff --git a/signatures/2.1.0-cagebreak-socket.7.sig b/signatures/2.1.0-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..67c2e166279805704204ef4ba7843177146a8340 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@I{*p^5J?I6 zOsG4!XJ?rY{wb7ikpWvUjL5LXPboA72(rh}Um;IL{Hr(?cZ{Hcdvsw7)6JwNk7BnM zayXykj0YkR+Jh2Hwq|Y^A zPu`ugLAlCp?L0U!>F;Zuu;aVM2bI~8Xj333 zsC7lgX`xb^ETu!?Bw8FNyQ$U4&W>=On~*_~z-WZIC6s*H>m*Fo>YN z3NqSep3ktdUAbS8m_Vjw$@OzLcpWk*swcy9j=(Zt11%qsS1}G4A(U&PU%nG0<@*JgP<=etYs$Pl@IShl2ReE?BjM En*g&E-T(jq literal 0 HcmV?d00001 diff --git a/signatures/2.1.0-cagebreak.1.sig b/signatures/2.1.0-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..b0c8dc15ac8fae31e58867f0a45a09b3ed2d1486 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@FaQb(5J?I6 zOsG4!XQ9Rq`v;-NQB9`itOy7w8l=VA36V8d$O+C8V4siElG)?+-d>(fZ&kfv`E=xo zinXUoT!}dOjO)=zs&(12$gG=(A+U zCuHOF=LWtU(1Dednc%h`JboeK64+cz8-y0Yk7+1^yM3lwplgw@i?XqZjEFM^_-h0Z z@*BzMK7ViM?i+E-b1U5=bh>3>h#N%FkvtOpAiTrt%rBrS4;{wW z#YEh;zE>EsLm_eFyq|IMThIw)Ro#1BO`vWh!8CFn|>I$Jm(P9-y7 z!he0ilG@?m)J zJ{eq<2(d=d+Cpi7$j%0c)kbInMA%wt<+aJ-)*bD#_1BbxZ)|xCbL@ctO6~R@_Yax; ztz>7&y$BT!7q(-3!{XjbzOdope4li@9B$gEPsc6ep)BMU=j$b*W(L=2xx4%aHp6O( z7~7&h?CgJ;Y7fxOYMx`k^J-@2HA?d{Nqqb-Nx|}M5-;vQBp9R!+q}?FrR-=x3L{11 zX969$BPXz2{2CKuBWFU)jUhbLXVmrPv>nUqh3+4CF$V;Jk3r<2*J+2=tj2xT%|&ZHd?OR?L2P;|Rb_ANCh zPF{g+^Ao3WzoSl#rc9|q`MH>0@plcedJVZl=KE%i5jp}Oii=6Ioj%WE$eO}I?`J)d z0v84f93fy1zigPkk+j$?-pb1~hneUMuYKNRY_)GY8L#g!H@eW3r_OiO(=HN>$zcI9 EDjqQqh5!Hn literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index 25072cbc7ec479dc03f8b0e58fb181f393b6019f..e25e49c74428afbac6d7bd0466d556b92405bdfe 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(xBv>V!tzCAjipv zwL*&XWDQ+NgCa63^5xd6*rRB5_M7Ys7zgiT1s~-o2YJ1 z);#uxIl2+qI$*0rlI_<5p|vN80hPq{9%)NYButb7%J%%KnV z2q1c)eISEOG|o0!{YFv#IK8B;M~-^UR+TC;oHi$U-&sQxB_Yrv&!_Me-|GPK$CZbO E66|6O`Tzg` literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@H2?|;5J?I6 zOsG4!XTI7G{wRJJEi`J}KeQfb1JU@66Z3T<6NTy#--hMh*c8j3d2~hbi^ZX=-TrKn ztD7j~V&53Q9i%4h8U#_7hK7oj`CIlD=;Mc4GwQ>a)J-YmdG`Vl;8s)}69L&?L5d~& z$20iJNFBNWK|tDpKg-~|d82IW#CC`j7nDWB&(z58T;2M2wvtE4dP=d?zp?WD0=p9* zUPU`tsJ{U-0GdW{DSNRrlKUGFVqhO3@k!$cL3*Qp6odwyB-0xQnq)@N!PVe$1`L>|k=$CLVHK?O+TkwoVUh!Xj=V&t>{#C*0%ot(iIdi&^gyH8KlU zhBT+I4>=Rc$+O;JZ!`T~Bm7w_#GKcp?kq#s$P0|Y^(i`zme%V+VSapC^`l@oRL1{@BcO}re zf)i0-Wdr6R<0JhvON1>o?yPvCFw8vYk{DbTrXy>~v!h&yhCb5?O?zZ$sp$kzmLK)j EGK$X>3IG5A diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index 67c2e166279805704204ef4ba7843177146a8340..6b1a6a53bea5fd958f39e4e1a3b2630bc6bcfdd0 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(xBv<1}Fi}wvC0q8gc5j<2D--xgVi`D}qC? zVas)^fv%k{3!i4=+1r}fNLnDFBz&I`+q}yv?MCPXEhv(V#gT*E1@Ms!jzt)>6e6+| zX-u`yGyy-#sngzXi1tX8NCm+~i~>#s;PTeX{a!7a)AGH=S63U0u!;hLXdA$#rdSc0 z6YA!rPx9cY;iCCLmvPHMB{^o!+s?Nfmnp>f(39do*$Ir=a042`w^^;rkBk4a&zP(I zU}8wkO#P-KAM&EkhPF(rf9_C}R_T`%KR{cI)*$4uPZiJS2XunIn^uGgXo>%`hPIXv z`D{%Sh{dJ2P+)I$w3HP7lho0qk)zWVu*`U7``v1rG;;X^I`?&U`=Am_vS{j<0lMUE zmuvJ^o-(sqCPjoa+y8hZxkM`*=hB4tB^ zh_^{u14_Mg3N{t3Qi;moRnhiUR}1deAKy`A zPu`ugLAlCp?L0U!>F;Zuu;aVM2bI~8Xj333 zsC7lgX`xb^ETu!?Bw8FNyQ$U4&W>=On~*_~z-WZIC6s*H>m*Fo>YN z3NqSep3ktdUAbS8m_Vjw$@OzLcpWk*swcy9j=(Zt11%qsS1}G4A(U&PU%nG0<@*JgP<=etYs$Pl@IShl2ReE?BjM En*g&E-T(jq diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index b0c8dc15ac8fae31e58867f0a45a09b3ed2d1486..7674f52c5525457b35e37630f7e174105cdf97d9 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(w*U$W5ZnyN z8{h{0g$BP5|3+rAM~!0w2)qQtiHJcD&$F7&*Ws<|G9b8d%A9w%?95_vvKr+J)dzRT z7}Dgl#lO}{Xei>jJAKVPK7g8_Z;E9f2&>0R>{6hPo?`&kqf!UMp}tJ)Wsq+ISEiLc z7wO~hJp|Wc#X+~)`n?40XtTbraBHqbm7O6V;i}>0UJV#W;2C%VvTX#0btuAYjR6kK zV(WyW@T$+>F)0eIA#}TV0@9hAJJUyyy&M9IU|`_8J@ED)2L9y07q1&UNkZha0OUV- zzD8CJ_LtymJoE9Y+goAv*mFh$G!(CRd$NaiJ?a@9zGQOd|U9!Q9j1Hs(lb?99V8jsaHPjFUYU2Vou z5{B+uG9q~#=4~+u)zU8ZH5&c03;JsLZ`OT_OK~VtnV*H%Og}fPQLGtIKz<&l7hNw zXd}6GH50ZJcJ$7*KqSJ+o=(V*_Xs82+|+zDk=Tdh5m^n@F2~G0VK#2!Pg{B!-)gN& zw6%KZzQ%6kJxHm(P0kSI51z_n58^m{ogDeO4T6{-y(@0Q;GhiJ+aP^ E*P|>Ivj6}9 literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@FaQb(5J?I6 zOsG4!XQ9Rq`v;-NQB9`itOy7w8l=VA36V8d$O+C8V4siElG)?+-d>(fZ&kfv`E=xo zinXUoT!}dOjO)=zs&(12$gG=(A+U zCuHOF=LWtU(1Dednc%h`JboeK64+cz8-y0Yk7+1^yM3lwplgw@i?XqZjEFM^_-h0Z z@*BzMK7ViM?i+E-b1U5=bh>3>h#N%FkvtOpAiTrt%rBrS4;{wW z#YEh;zE>EsLm_eFyq|IMThIw)Ro#1BO`vWh!8CFn|>I$Jm(P9-y7 z!he0ilG@?l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(w*U$W5ZnyN z8{h{0g|O`p|93+h`>T39v=djZ0&wOd*$K{aopV$L6nt}hx`hB&5Pf-?SaHqLIQKWAKFY)eQIZhM_TsTyth9BBvr?NCuIW4avXTAIt@Y<2T&n7p3kNrY! zqSc2?p^pZ(*T>#NcFb>weL^n7E3W>$GC?NFrG23dM+(TyWnpJ0Gx3H;|>bN zb4u`nR4`|f>GZAb=#_=PzeB?U&iWE&nPq(yXa9ud%8?4xOz%Omilkz`{YlRd^H~E3 zx98;1k+8JlLoJbo6%@FZ`jLoSn_zx{I`)X*_k9X&K-^K)Hd7Cd7R^550PG4Oeg4-m<1JL!W$2>2kLobN-?OLq z|LzkmP}4FyS|(AAzV-Ft1r%Nw+tRy1fEVK9fRa<;&NO>1m_X=8F<`g0s%*;X%p-IT zK#Fz}rdXasS2uaDJFVCNrH64xK49yEpCUp8p|%F? E)OoZP+yDRo literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%R-@EdUA$5J?I6 zOsG4!XUo$N0E5~0P~h*DH~*A2hTro%z;sAA=WxosF)hl-_!M(1uj5Le+}S87X>m)J zJ{eq<2(d=d+Cpi7$j%0c)kbInMA%wt<+aJ-)*bD#_1BbxZ)|xCbL@ctO6~R@_Yax; ztz>7&y$BT!7q(-3!{XjbzOdope4li@9B$gEPsc6ep)BMU=j$b*W(L=2xx4%aHp6O( z7~7&h?CgJ;Y7fxOYMx`k^J-@2HA?d{Nqqb-Nx|}M5-;vQBp9R!+q}?FrR-=x3L{11 zX969$BPXz2{2CKuBWFU)jUhbLXVmrPv>nUqh3+4CF$V;Jk3r<2*J+2=tj2xT%|&ZHd?OR?L2P;|Rb_ANCh zPF{g+^Ao3WzoSl#rc9|q`MH>0@plcedJVZl=KE%i5jp}Oii=6Ioj%WE$eO}I?`J)d z0v84f93fy1zigPkk+j$?-pb1~hneUMuYKNRY_)GY8L#g!H@eW3r_OiO(=HN>$zcI9 EDjqQqh5!Hn diff --git a/test/check-artefacts b/test/check-artefacts new file mode 100644 index 0000000..9e62bb5 --- /dev/null +++ b/test/check-artefacts @@ -0,0 +1,27 @@ +#! /bin/sh +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +readonly version="${1}" + +# shellcheck disable=SC2164 +cd "${MESONCURRENTCONFIGDIR}" + +gpg --verify "release_${version}.tar.gz.sig" || RESULT=1 +gpg --verify "release-artefacts_${version}.tar.gz.sig" || RESULT=1 + +tar -xvf "release_${version}.tar.gz" +cd cagebreak || exit 1 +meson setup build -Dxwayland=true -Dman-pages=true --buildtype=release +ninja -C build +gpg --verify ../signatures/cagebreak.sig build/cagebreak || RESULT=1 +gpg --verify ../signatures/cagebreak.1.sig build/cagebreak.1 || RESULT=1 +gpg --verify ../signatures/cagebreak-config.5.sig build/cagebreak-config.5 || RESULT=1 +gpg --verify ../signatures/cagebreak-socket.7.sig build/cagebreak-socket.7 || RESULT=1 +# shellcheck disable=2103 +cd .. +rm -rf cagebreak + +exit "${RESULT}" diff --git a/test/copyright-license b/test/copyright-license index 4fe517f..630f843 100644 --- a/test/copyright-license +++ b/test/copyright-license @@ -10,7 +10,9 @@ readonly test_deps=$(cd "${MESONCURRENTCONFIGDIR}" ; find . -type f | grep test/ readonly examples_deps=$(cd "${MESONCURRENTCONFIGDIR}" ; find . -type f | grep examples/) # shellcheck disable=2155,2164,2046 readonly example_scripts_deps=$(cd "${MESONCURRENTCONFIGDIR}" ; find . -type f | grep example_scripts/) -readonly deps="${declared_deps} ${hardcoded_deps} ${test_deps} ${examples_deps} ${example_scripts_deps}" +# shellcheck disable=2155,2164,2046 +readonly scripts_deps=$(cd "${MESONCURRENTCONFIGDIR}" ; find . -type f | grep scripts/) +readonly deps="${declared_deps} ${hardcoded_deps} ${test_deps} ${examples_deps} ${example_scripts_deps} ${scripts_deps}" # shellcheck disable=2046,2155 readonly curryear=$(date +%Y) diff --git a/test/git-tag b/test/git-tag new file mode 100644 index 0000000..f080060 --- /dev/null +++ b/test/git-tag @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +VERSION=$1 +RESULT=0 + +if git tag -v "${VERSION}" +then + echo "[x] git tag" +else + RESULT=1 + echo "[ ] git tag" +fi + +exit "${RESULT}" diff --git a/test/gpg-signatures b/test/gpg-signatures new file mode 100644 index 0000000..c5d63fd --- /dev/null +++ b/test/gpg-signatures @@ -0,0 +1,43 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +# cagebreak +if gpg --verify ../signatures/cagebreak.sig cagebreak +then + echo "[x] cagebreak binary" +else + RESULT=1 + echo "[ ] cagebreak binary" +fi + +# cagebreak-man +if gpg --verify ../signatures/cagebreak.1.sig cagebreak.1 +then + echo "[x] cagebreak.1 man" +else + RESULT=1 + echo "[ ] cagebreak.1 man" +fi + +# cagebreak-config man +if gpg --verify ../signatures/cagebreak-config.5.sig cagebreak-config.5 +then + echo "[x] cagebreak-config.5 man" +else + RESULT=1 + echo "[ ] cagebreak-config.5 man" +fi + +# cagebreak-socket man +if gpg --verify ../signatures/cagebreak-socket.7.sig cagebreak-socket.7 +then + echo "[x] cagebreak-socket.7 man" +else + RESULT=1 + echo "[ ] cagebreak-socket.7 man" +fi + +exit "${RESULT}" diff --git a/test/gpg-validity b/test/gpg-validity new file mode 100644 index 0000000..6340105 --- /dev/null +++ b/test/gpg-validity @@ -0,0 +1,46 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +RESULT=0 + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}/keys" +stoday=$(date +%s) +signingmargin=90 + +# shellcheck disable=2046 +skey11exptime=$(date --date=$(gpg --show-keys cagebreak_signing_key_11\@project-repo.co.pub | tail -2 | head -1 | cut -d " " -f 8 | rev | cut -c2- | rev) '+%s') +# shellcheck disable=2046 +skey12exptime=$(date --date=$(gpg --show-keys cagebreak_signing_key_12\@project-repo.co.pub | tail -2 | head -1 | cut -d " " -f 8 | rev | cut -c2- | rev) '+%s') +# shellcheck disable=2046 +mailexptime=$(date --date=$(gpg --show-keys cagebreak\@project-repo.co.pub | tail -2 | head -1 | cut -d " " -f 8 | rev | cut -c2- | rev) '+%s') + +# signing keys +## signing key 11 +if [[ $(( (stoday - skey11exptime) / 86400 )) -lt $signingmargin ]] +then + echo "[x] signign key 11" +else + RESULT=1 + echo "[ ] signing key 11" +fi +## signing key 12 +if [[ $(( (stoday - skey12exptime) / 86400 )) -lt $signingmargin ]] +then + echo "[x] signign key 12" +else + RESULT=1 + echo "[ ] signing key 12" +fi + +# email key +if [[ $(( (stoday - mailexptime) / 86400 )) -lt $signingmargin ]] +then + echo "[x] mail key" +else + RESULT=1 + echo "[ ] mail key" +fi + +exit "${RESULT}" diff --git a/test/hashes-md b/test/hashes-md new file mode 100644 index 0000000..30a5529 --- /dev/null +++ b/test/hashes-md @@ -0,0 +1,53 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +VERSION=$1 +RESULT=0 + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}" + +cb256=$(sha256sum build/cagebreak | cut -d " " -f1 ) +cb256man1=$(sha256sum build/cagebreak.1 | cut -d " " -f1 ) +cb256man5=$(sha256sum build/cagebreak-config.5 | cut -d " " -f1 ) +cb256man7=$(sha256sum build/cagebreak-socket.7 | cut -d " " -f1 ) +cb512=$(sha512sum build/cagebreak | cut -d " " -f1 ) +cb512man1=$(sha512sum build/cagebreak.1 | cut -d " " -f1 ) +cb512man5=$(sha512sum build/cagebreak-config.5 | cut -d " " -f1 ) +cb512man7=$(sha512sum build/cagebreak-socket.7 | cut -d " " -f1 ) + +hashesdoc=$(head -21 Hashes.md) + +testdoc="# Hashes + +$VERSION cagebreak + + * sha 256: ${cb256} + * sha 512: ${cb512} + +$VERSION cagebreak.1 + + * sha 256: ${cb256man1} + * sha 512: ${cb512man1} + +$VERSION cagebreak-config.5 + + * sha 256: ${cb256man5} + * sha 512: ${cb512man5} + +$VERSION cagebreak-socket.7 + + * sha 256: ${cb256man7} + * sha 512: ${cb512man7}" + +# email key +if [[ "${hashesdoc}" = "${testdoc}" ]] +then + echo "[x] Hashes.md" +else + RESULT=1 + echo "[ ] Hashes.md" +fi + +exit "${RESULT}" diff --git a/test/non-auto-tests b/test/non-auto-tests new file mode 100644 index 0000000..470d494 --- /dev/null +++ b/test/non-auto-tests @@ -0,0 +1,25 @@ +#!/bin/bash +# Copyright 2023, project-repo and the cagebreak contributors +# SPDX-License-Identifier: MIT + +VERSION=$1 +RESULT=0 + +# shellcheck disable=2164 +cd "${MESONCURRENTCONFIGDIR}/release-non-auto-checks" + +filevar="$VERSION +$(date +%Y-%m-%d)" + +for check in ./* +do + if [[ $(cat "$check") = "${filevar}" ]] + then + echo "[x] ${check}" + else + RESULT=1 + echo "[ ] ${check}" + fi +done + +exit "${RESULT}" diff --git a/test/shellcheck b/test/shellcheck index 0727178..8fa5f4e 100644 --- a/test/shellcheck +++ b/test/shellcheck @@ -4,13 +4,15 @@ RESULT=0 -set -x # shellcheck disable=2164 cd "${MESONCURRENTCONFIGDIR}/test" # shellcheck disable=2046 shellcheck --source-path=../example_scripts/ $(ls -Itesting-configurations) || RESULT=1 cd "${MESONCURRENTCONFIGDIR}/example_scripts/" || RESULT=1 -shellcheck ./* +shellcheck ./* || RESULT=1 + +cd "${MESONCURRENTCONFIGDIR}/scripts/" || RESULT=1 +shellcheck ./* || RESULT=1 exit "${RESULT}" From 9a4c07d8154f993ed9ca92a3fee1792e536bcccb Mon Sep 17 00:00:00 2001 From: project-repo Date: Mon, 24 Apr 2023 22:57:42 +0200 Subject: [PATCH 13/19] Release 2.1.2 - Adjust release procedure - Fix Issue 60 in Bugs.md (Thanks to Tom Greig) - Fix Issue 61 in Bugs.md --- Bugs.md | 17 +++++++++++++ Hashes.md | 20 +++++++++++++++ README.md | 12 ++++++--- example_scripts/focus_follows_cursor.sh | 23 ------------------ man/cagebreak-config.5.md | 2 +- man/cagebreak-socket.7.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 4 +-- output.c | 2 +- release-non-auto-checks/Bugs.md | 4 +-- release-non-auto-checks/FAQ.md | 4 +-- release-non-auto-checks/SECURITY.md | 4 +-- release-non-auto-checks/WLR_XDG_VERSION | 4 +-- release-non-auto-checks/changelog-major-minor | 4 +-- release-non-auto-checks/internal-wiki | 4 +-- release-non-auto-checks/meson-epoch | 2 -- release-non-auto-checks/release-note | 4 +-- .../reproducibility-checked | 4 +-- .../security-to-man-page-info-transfer | 4 +-- scripts/install-development-environment | 2 +- scripts/set-version | 6 ++--- signatures/2.1.1-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.1.1-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.1.1-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.1.1-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 29 files changed, 74 insertions(+), 56 deletions(-) delete mode 100644 example_scripts/focus_follows_cursor.sh delete mode 100644 release-non-auto-checks/meson-epoch mode change 100755 => 100644 scripts/install-development-environment create mode 100644 signatures/2.1.1-cagebreak-config.5.sig create mode 100644 signatures/2.1.1-cagebreak-socket.7.sig create mode 100644 signatures/2.1.1-cagebreak.1.sig create mode 100644 signatures/2.1.1-cagebreak.sig diff --git a/Bugs.md b/Bugs.md index d8a33a1..4075383 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1170,3 +1170,20 @@ leading to a termination of cagebreak. * Fixed: 2.1.0 Prior to release 2.1.0 `meson install` did not work perfectly. + +## Issue 60 + + * github issue number: N/A + * Fixed: 2.1.2 + +In the `merge_output_configs` function, when copying the properties of +one config to another, the `angles` element of an input structure was +being copied to the `status` element of the resultant structure. + +## Issue 61 + + * github issue number: N/A + * Fixed: 2.1.2 + +The script introduced with 2.1.1 `scripts/install-development-environment` had some +missing dependencies. This has been resolved and tested with bare arch containers. diff --git a/Hashes.md b/Hashes.md index e5da651..a6ceae1 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.1.2 cagebreak + + * sha 256: 7d07864a837ee577a52b2727bfbfe8834fe599712144f0685f458d508717e451 + * sha 512: 9429bace89affdd9f7e83f48168c1e119d1531a5eb9a320299924e469c0e43052e93580aee6ba5f4c2b878e5b85ec5fc4cf172940cb4c1d950329c175898b647 + +2.1.2 cagebreak.1 + + * sha 256: aec69b06cc8dd4328027a04a12847c91b6a176537cce7a6c2d68a4f004cdd47c + * sha 512: 1d6e882a1fa8bec84df189cd32a1ac8953fb61d0241b04296ecb8caadfc55733947037b3810ba28b73e2a32bc30dfd68794dd173220e1f8af8ba9d3d02abe19e + +2.1.2 cagebreak-config.5 + + * sha 256: 36e11b9d4437485a9671e72b3f6cc5669fb6a5b67b60198ee310efd6f3f3b093 + * sha 512: 8378924d81c2c35ddfeace15debafb0407fbbe76513f7a488815a1421ff1c49d7aa7f21812573043004a8fd4e481242fd6970be270fac8007771623ed8d92208 + +2.1.2 cagebreak-socket.7 + + * sha 256: 346f8e203210a1542ca31980628095dbfb267764e3c2228457dc5b0b43850fda + * sha 512: 84e40072c71a38449ec6a5409445458405009010ee47d3e26ba13f6fd13f0291e1c3b38f5e84ba5521b14955bd97ab6d1c636b72a093b6322d0879f98218ab7f + 2.1.1 cagebreak * sha 256: 8632e7e49637e5a3e7ab425a05fbd63d71cf6025143c89d196f309dbf4efdd57 diff --git a/README.md b/README.md index aca03a6..004239a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.1.1)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.1.2)](https://repology.org/project/cagebreak/versions) ## Quick Introduction @@ -633,14 +633,17 @@ The release procedure outlines the process for a release to occur. * [ ] Synchronize any socket changes to cagebreak-socket man page * [ ] Document fixed bugs in Bugs.md * [ ] Include issue discussion from github, where applicable + * [ ] `meson compile adjust-epoch -C build` * [ ] Commit changes * [ ] `git push origin development` * [ ] Testing * [ ] Manual testing * [ ] `meson compile fuzz -C build` for at least one hour + * [ ] Adjust Hashes.md - Use `meson compile output-hashes -C build` to add Hashes or aid in repro check + * [ ] Commit changes + * [ ] `git push origin development` * [ ] Complete release-non-auto-checks - * [ ] Use `meson compile output-hashes -C build` to add Hashes or aid in repro check - * [ ] `meson compile create-signatures -C build` + * [ ] `meson compile create-sigs -C build` * [ ] Commit and push signatures, hashes and non-auto-check files * [ ] `meson test -C build` passes everything except some release tests * [ ] `git add` relevant files @@ -660,6 +663,7 @@ The release procedure outlines the process for a release to occur. * [ ] `git merge master` * [ ] `git push --tags origin hotfix` * [ ] Upload archives and signatures as release assets + * [ ] Delete feature branches if appropriate * [ ] Manage package release ## Roadmap @@ -743,6 +747,8 @@ see [SECURITY.md](SECURITY.md). * Oliver Friedmann * [Add output scaling](https://github.com/project-repo/cagebreak/pull/34), released in 2.0.0 with slight modifications + * Tom Greig + * Fix bug in merge_output_configs in 2.1.2 ## License diff --git a/example_scripts/focus_follows_cursor.sh b/example_scripts/focus_follows_cursor.sh deleted file mode 100644 index e47bf88..0000000 --- a/example_scripts/focus_follows_cursor.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors -# SPDX-License-Identifier: MIT - -# This script uses the cagebreak socket to modify the compositor's behaviour in -# such a way that the currently focussed tile follows the cursor, i.e. that the -# currently focussed tile is always the one within which the cursor is located. - -# Start up the ipc link -source "$(dirname "${BASH_SOURCE[0]}")/cb_script_header.sh" - -while IFS= read -r -d $'\0' event -do - # Remove the cg-ipc header - event="${event:6}" - if [[ "$(echo "${event}" | jq ".event_name")" = "\"cursor_switch_tile\"" ]] - then - new_tile="$(echo "${event}"|jq -r ".new_tile")" - new_output_id="$(echo "${event}"|jq -r ".new_output_id")" - # Send the new tile to focus to cagebreak - echo -e "screen ${new_output_id}\nfocus_tile ${new_tile}" >&3 - fi -done <&4 diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index bb04547..b9632dd 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "VERSION 2.1.1" "Cagebreak Manual" +cagebreak-config(5) "Version 2.1.2" "Cagebreak Manual" # NAME diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index 19b7370..4c1a31a 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "VERSION 2.1.1" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.1.2" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index fdc2da1..c8fc85e 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "VERSION 2.1.1" "Cagebreak Manual" +cagebreak(1) "Version 2.1.2" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index 26b0746..777c8d3 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.1.1', +version : '2.1.2', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1681758922 + secssinceepoch = 1682363199 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/output.c b/output.c index b8fc627..506f5bd 100644 --- a/output.c +++ b/output.c @@ -399,7 +399,7 @@ merge_output_configs(struct cg_output_config *cfg1, out_cfg->scale = cfg1->scale; } if(cfg1->angle == out_cfg->angle) { - out_cfg->status = cfg2->angle; + out_cfg->angle = cfg2->angle; } else { out_cfg->angle = cfg1->angle; } diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/meson-epoch b/release-non-auto-checks/meson-epoch deleted file mode 100644 index aa7d21e..0000000 --- a/release-non-auto-checks/meson-epoch +++ /dev/null @@ -1,2 +0,0 @@ -2.1.1 -2023-04-17 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index aa7d21e..5f93ac2 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.1.1 -2023-04-17 +2.1.2 +2023-04-24 diff --git a/scripts/install-development-environment b/scripts/install-development-environment old mode 100755 new mode 100644 index d1b9793..1b71ce5 --- a/scripts/install-development-environment +++ b/scripts/install-development-environment @@ -2,7 +2,7 @@ # Copyright 2023, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT -sudo pacman -Syu --noconfirm git grep sed xev meson ninja clang gcc shellcheck jq openbsd-netcat gnupg binutils alacritty wlroots wayland libxkbcommon cairo pango fontconfig libinput libevdev systemd-libs # systemd-libs is included because of libudev +sudo pacman -Syu --noconfirm git grep sed xorg-xev meson ninja clang gcc shellcheck jq openbsd-netcat gnupg binutils alacritty wlroots wayland wayland-protocols libxkbcommon cairo pango fontconfig libinput libevdev pkgconf scdoc systemd-libs # systemd-libs is included because of libudev if [[ -n ${MESON_SOURCE_ROOT} ]] then diff --git a/scripts/set-version b/scripts/set-version index c4506cb..3ee035c 100755 --- a/scripts/set-version +++ b/scripts/set-version @@ -15,6 +15,6 @@ version="${1}" sed -i -e "s/minversion\=[0-9]*\.[0-9]*.[0-9]*/minversion=$version/" README.md -sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak.1.md -sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak-config.5.md -sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/VERSION $version/" man/cagebreak-socket.7.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/Version $version/" man/cagebreak.1.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/Version $version/" man/cagebreak-config.5.md +sed -i -e "s/Version [0-9]*\.[0-9]*.[0-9]*/Version $version/" man/cagebreak-socket.7.md diff --git a/signatures/2.1.1-cagebreak-config.5.sig b/signatures/2.1.1-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..e25e49c74428afbac6d7bd0466d556b92405bdfe GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(xBv>V!tzCAjipv zwL*&XWDQ+NgCa63^5xd6*rRB5_M7Ys7zgiT1s~-o2YJ1 z);#uxIl2+qI$*0rlI_<5p|vN80hPq{9%)NYButb7%J%%KnV z2q1c)eISEOG|o0!{YFv#IK8B;M~-^UR+TC;oHi$U-&sQxB_Yrv&!_Me-|GPK$CZbO E66|6O`Tzg` literal 0 HcmV?d00001 diff --git a/signatures/2.1.1-cagebreak-socket.7.sig b/signatures/2.1.1-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..6b1a6a53bea5fd958f39e4e1a3b2630bc6bcfdd0 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(xBv<1}Fi}wvC0q8gc5j<2D--xgVi`D}qC? zVas)^fv%k{3!i4=+1r}fNLnDFBz&I`+q}yv?MCPXEhv(V#gT*E1@Ms!jzt)>6e6+| zX-u`yGyy-#sngzXi1tX8NCm+~i~>#s;PTeX{a!7a)AGH=S63U0u!;hLXdA$#rdSc0 z6YA!rPx9cY;iCCLmvPHMB{^o!+s?Nfmnp>f(39do*$Ir=a042`w^^;rkBk4a&zP(I zU}8wkO#P-KAM&EkhPF(rf9_C}R_T`%KR{cI)*$4uPZiJS2XunIn^uGgXo>%`hPIXv z`D{%Sh{dJ2P+)I$w3HP7lho0qk)zWVu*`U7``v1rG;;X^I`?&U`=Am_vS{j<0lMUE zmuvJ^o-(sqCPjoa+y8hZxkM`*=hB4tB^ zh_^{u14_Mg3N{t3Qi;moRnhiUR}1deAKy`l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(w*U$W5ZnyN z8{h{0g$BP5|3+rAM~!0w2)qQtiHJcD&$F7&*Ws<|G9b8d%A9w%?95_vvKr+J)dzRT z7}Dgl#lO}{Xei>jJAKVPK7g8_Z;E9f2&>0R>{6hPo?`&kqf!UMp}tJ)Wsq+ISEiLc z7wO~hJp|Wc#X+~)`n?40XtTbraBHqbm7O6V;i}>0UJV#W;2C%VvTX#0btuAYjR6kK zV(WyW@T$+>F)0eIA#}TV0@9hAJJUyyy&M9IU|`_8J@ED)2L9y07q1&UNkZha0OUV- zzD8CJ_LtymJoE9Y+goAv*mFh$G!(CRd$NaiJ?a@9zGQOd|U9!Q9j1Hs(lb?99V8jsaHPjFUYU2Vou z5{B+uG9q~#=4~+u)zU8ZH5&c03;JsLZ`OT_OK~VtnV*H%Og}fPQLGtIKz<&l7hNw zXd}6GH50ZJcJ$7*KqSJ+o=(V*_Xs82+|+zDk=Tdh5m^n@F2~G0VK#2!Pg{B!-)gN& zw6%KZzQ%6kJxHm(P0kSI51z_n58^m{ogDeO4T6{-y(@0Q;GhiJ+aP^ E*P|>Ivj6}9 literal 0 HcmV?d00001 diff --git a/signatures/2.1.1-cagebreak.sig b/signatures/2.1.1-cagebreak.sig new file mode 100644 index 0000000000000000000000000000000000000000..c71037ff63b412c8e4ee197d5ed9267706168b0c GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(w*U$W5ZnyN z8{h{0g|O`p|93+h`>T39v=djZ0&wOd*$K{aopV$L6nt}hx`hB&5Pf-?SaHqLIQKWAKFY)eQIZhM_TsTyth9BBvr?NCuIW4avXTAIt@Y<2T&n7p3kNrY! zqSc2?p^pZ(*T>#NcFb>weL^n7E3W>$GC?NFrG23dM+(TyWnpJ0Gx3H;|>bN zb4u`nR4`|f>GZAb=#_=PzeB?U&iWE&nPq(yXa9ud%8?4xOz%Omilkz`{YlRd^H~E3 zx98;1k+8JlLoJbo6%@FZ`jLoSn_zx{I`)X*_k9X&K-^K)Hd7Cd7R^550PG4Oeg4-m<1JL!W$2>2kLobN-?OLq z|LzkmP}4FyS|(AAzV-Ft1r%Nw+tRy1fEVK9fRa<;&NO>1m_X=8F<`g0s%*;X%p-IT zK#Fz}rdXasS2uaDJFVCNrH64xK49yEpCUp8p|%F? E)OoZP+yDRo literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index e25e49c74428afbac6d7bd0466d556b92405bdfe..f96713d95f03f5db4cb5d9f359f5a07efe261263 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XN%(x{vno|Sj7x0L`Rsk` zzccF>sPdtgaU4+77ayFBN zL^y190up?k#V_WR^AIUpXARKF?>7Pi;N+0Lad*>|^}Rjv`Ht-`WO^?`ltx=!!sIC# z^G!&A7B+INK_M#jzyF%$+1LiW?U!5%MOQc26B8*GTlnd%8Gs-0Cgn}~T}@eGpvtkc z2|6({wHX<0T{+EhR2>^Qu3-&A%G>TykPPs0n75m>G5w!naEvg1&=TW;)NzxOQ)H;- zdyPhRslELoykhP2>JIQlaFf_qf;3A&`kRqsX?xGRY_m;^0Ssze;3I25@-&3jv{%LO zlt`NJBEZ0hE4D+0HmHM!j!XPoad8u>E$czw*o&rfvIjyILMlzJA%PU^WO29|T4_{) Ey-4Q{fB*mh literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(xBv>V!tzCAjipv zwL*&XWDQ+NgCa63^5xd6*rRB5_M7Ys7zgiT1s~-o2YJ1 z);#uxIl2+qI$*0rlI_<5p|vN80hPq{9%)NYButb7%J%%KnV z2q1c)eISEOG|o0!{YFv#IK8B;M~-^UR+TC;oHi$U-&sQxB_Yrv&!_Me-|GPK$CZbO E66|6O`Tzg` diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index 6b1a6a53bea5fd958f39e4e1a3b2630bc6bcfdd0..fec631f4783791825b37c8b15a6c4e24cca58d55 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XVo?CTq)#T*vDA8Uv0yd-^z|q<4hqC}C^c;56vGqqV62Z0uy0F_8W35NU8g;5AHC59BNy2{Q?7)R%MQUM`Tb zFv4dkl&*4`9`fA59G5+%c*$F><(@z?}Q_4rlof-K!}(ISCRNGVfw7&vuT$iT2Q zVWn@xp0K@o{>#Qo+54}2Gv&Ie*M@P$Fihu;Z>%`5l1R$1bJq$PcKxs!7vH1l$HSYy z25=-=ZZAhjUn)CT;B~FWgS_E>2VF|gB&V2gstyT9sHUEzMrDT}x+H8X_i7%_B&~SG zc$EpgnHN}f*FPwKB3N6xv*{nsJ0o4zyNLx7Q!ncY^a{fXJ@Esa@=vK;a4I z8_RhqV5KRy4RQ$`<*%w7xi{-nI3^0@?6iLUl|JA7`dsicN7B8sb~X01qEI9okTQ%W zOWuS5w!uKv3cn0ID(_u`!SgLEqIz;TBZrJ^#!ZwIg`kVr$r|}OTS~AVgz`8TEF)`r EcpuIZNB{r; literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(xBv<1}Fi}wvC0q8gc5j<2D--xgVi`D}qC? zVas)^fv%k{3!i4=+1r}fNLnDFBz&I`+q}yv?MCPXEhv(V#gT*E1@Ms!jzt)>6e6+| zX-u`yGyy-#sngzXi1tX8NCm+~i~>#s;PTeX{a!7a)AGH=S63U0u!;hLXdA$#rdSc0 z6YA!rPx9cY;iCCLmvPHMB{^o!+s?Nfmnp>f(39do*$Ir=a042`w^^;rkBk4a&zP(I zU}8wkO#P-KAM&EkhPF(rf9_C}R_T`%KR{cI)*$4uPZiJS2XunIn^uGgXo>%`hPIXv z`D{%Sh{dJ2P+)I$w3HP7lho0qk)zWVu*`U7``v1rG;;X^I`?&U`=Am_vS{j<0lMUE zmuvJ^o-(sqCPjoa+y8hZxkM`*=hB4tB^ zh_^{u14_Mg3N{t3Qi;moRnhiUR}1deAKy`Bqcp_iBViwa^f(K{t0D?!V5CHZzL!ufR3! zyz?2YNBfCc<;3OqzTnrq{)>k(%&BnGYt+-axf3=(G}sl{lLQQd(H2-Q%@ZLau4>nu zNMW7d^VsREfMH!M$9$HYlEBM>|6kD35+1uI%UqIEo2^622DgP@O$tLHx$d*980Rch ze9j2`VDBw4m!f8}?pnyop;R#sbL;w(!;6n5Q?|ipbaVSgEArB?h2ZQ}bVO~HGhQ=o6v9P|u z4KR14ets86#>W%0L2u|GAFv`=<-QLkl{NUmeWNO1Vw-$QfZ}r)Hs?S_0^171zHVVB>-%pE z07BOgiY;zQt~Kpeg>xNLwD5d%byVna<{5cccreqy9i7=oUEYXECZ!VLI^CN@X*@eG zU?NWI*A_8U$?YU!z6ZQcoerhjMX#**W=jaACCetS+A0|TLm+B$cQw6#d+cxf&3K`i z&;|;4sZvB}Z)+zA)inhQsBVnI#q}>R5-8vgEvg!Ji!S;QKh1bCMttvf>C%l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(w*U$W5ZnyN z8{h{0g$BP5|3+rAM~!0w2)qQtiHJcD&$F7&*Ws<|G9b8d%A9w%?95_vvKr+J)dzRT z7}Dgl#lO}{Xei>jJAKVPK7g8_Z;E9f2&>0R>{6hPo?`&kqf!UMp}tJ)Wsq+ISEiLc z7wO~hJp|Wc#X+~)`n?40XtTbraBHqbm7O6V;i}>0UJV#W;2C%VvTX#0btuAYjR6kK zV(WyW@T$+>F)0eIA#}TV0@9hAJJUyyy&M9IU|`_8J@ED)2L9y07q1&UNkZha0OUV- zzD8CJ_LtymJoE9Y+goAv*mFh$G!(CRd$NaiJ?a@9zGQOd|U9!Q9j1Hs(lb?99V8jsaHPjFUYU2Vou z5{B+uG9q~#=4~+u)zU8ZH5&c03;JsLZ`OT_OK~VtnV*H%Og}fPQLGtIKz<&l7hNw zXd}6GH50ZJcJ$7*KqSJ+o=(V*_Xs82+|+zDk=Tdh5m^n@F2~G0VK#2!Pg{B!-)gN& zw6%KZzQ%6kJxHm(P0kSI51z_n58^m{ogDeO4T6{-y(@0Q;GhiJ+aP^ E*P|>Ivj6}9 diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index c71037ff63b412c8e4ee197d5ed9267706168b0c..d729d108fda99f3c4a6433ce5ae228ab14dbf810 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XMW!h0Eh!1R%k=hodX8nwACP9sFdtasp)hWtSn%_UH1!yDPCD!X4Y8UDKIVE zO)nk@R>7}qq(Zv6isAH)uV$hx9h5EgW5)k0pHgaa?dreFtjJ}VC2HAS-!2_VVT~S7 z{6U*9Cu|k%{*PikV04S2?Ev8Oci;@xz!x?3$)2s|Xnqk7b7QnkI#t zwVyvLx{CzDTgBJ=F-iyjBYM!{JQ7H>j-8}ugRvkD*P1CwehD6+%k@xn6=fU1iJcOP z&OPIBV2HPFk|h;oGCr3gcKN#{4kx=nwsf`+AGhtUxUKN!MgI{OMcn4rLlI(M1Sj@; z7)v089Y#=;RHKo#K7OLOaju2N%v`I5un~nncJ&)3Xj1aOM_>hO2=NC4mNQ|iPqwc_ zDhgzB^dL%&*>I#sE6mXceGoq4mDE?q?b)-QO|O%%;f{s|N_YXrue;sbY!zvg1b7RQ zTmJ>+R^LUI)KuX?eP6-c2T6~+4?iE{P_Xfq1rYPs=$%Cn$f6IjlvLn&z+Bfk%Ii{h zkG#@S4^bmNRX?m9@a>;|?+(*As=n+zcd%;jIbNcCB9o6ldd(5EnY|x{j51y6R4jC$ E=0t7`+5i9m literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%Sd(w*U$W5ZnyN z8{h{0g|O`p|93+h`>T39v=djZ0&wOd*$K{aopV$L6nt}hx`hB&5Pf-?SaHqLIQKWAKFY)eQIZhM_TsTyth9BBvr?NCuIW4avXTAIt@Y<2T&n7p3kNrY! zqSc2?p^pZ(*T>#NcFb>weL^n7E3W>$GC?NFrG23dM+(TyWnpJ0Gx3H;|>bN zb4u`nR4`|f>GZAb=#_=PzeB?U&iWE&nPq(yXa9ud%8?4xOz%Omilkz`{YlRd^H~E3 zx98;1k+8JlLoJbo6%@FZ`jLoSn_zx{I`)X*_k9X&K-^K)Hd7Cd7R^550PG4Oeg4-m<1JL!W$2>2kLobN-?OLq z|LzkmP}4FyS|(AAzV-Ft1r%Nw+tRy1fEVK9fRa<;&NO>1m_X=8F<`g0s%*;X%p-IT zK#Fz}rdXasS2uaDJFVCNrH64xK49yEpCUp8p|%F? E)OoZP+yDRo From d946b62a4c41ba7b513c1eb56af8684ec6cc16cb Mon Sep 17 00:00:00 2001 From: project-repo Date: Wed, 31 May 2023 21:38:43 +0200 Subject: [PATCH 14/19] Release 2.2.0 - Add custom events - Fix Issue 62 (#46 Github) - Fix Issue 63 (environment variables test) - Fix Issue 64 (pointer focus bug) --- Bugs.md | 36 ++++++++++++++++++ Changelog.md | 7 ++++ Hashes.md | 20 ++++++++++ README.md | 2 +- ipc_server.c | 4 -- keybinding.c | 15 ++++++++ keybinding.h | 1 + man/cagebreak-config.5.md | 10 ++++- man/cagebreak-socket.7.md | 13 ++++++- man/cagebreak.1.md | 2 +- meson.build | 8 ++-- parse.c | 9 +++++ release-non-auto-checks/Bugs.md | 4 +- release-non-auto-checks/FAQ.md | 4 +- release-non-auto-checks/SECURITY.md | 4 +- release-non-auto-checks/WLR_XDG_VERSION | 4 +- release-non-auto-checks/changelog-major-minor | 4 +- release-non-auto-checks/internal-wiki | 4 +- release-non-auto-checks/release-note | 4 +- .../reproducibility-checked | 4 +- .../security-to-man-page-info-transfer | 4 +- seat.c | 1 + signatures/2.1.2-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.1.2-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.1.2-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.1.2-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes test/environment-variables | 2 +- workspace.c | 3 ++ 32 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 signatures/2.1.2-cagebreak-config.5.sig create mode 100644 signatures/2.1.2-cagebreak-socket.7.sig create mode 100644 signatures/2.1.2-cagebreak.1.sig create mode 100644 signatures/2.1.2-cagebreak.sig diff --git a/Bugs.md b/Bugs.md index 4075383..4536616 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1187,3 +1187,39 @@ being copied to the `status` element of the resultant structure. The script introduced with 2.1.1 `scripts/install-development-environment` had some missing dependencies. This has been resolved and tested with bare arch containers. + +## Issue 62 + + * github issue number: #46 + * Fixed: 2.2.0 + +When the readable flag of the IPC socket was set with 0 readable bytes +available, cagebreak entered an infinite loop which caused high CPU +usage before the first event was sent over the IPC socket. + +## Issue 63 + + * github issue number: N/A + * Fixed: 2.2.0 + +A file path in the environment-variables unit test was wrongly set, +causing this test to fail. + +## Issue 64 + + * github issue number: N/A + * Fixed: 2.2.0 + +Cagebreak did not update the pointer focus when focussing the +background. This means that the first pointer event after focussing the +background was sent to the previously focussed window. + +Steps to reproduce: + + * Open an application and hover the mouse over a clickable area. + * Switch to an empty desktop using a keybinding without moving the + mouse. + * Click the mouse without moving it. + * Observe that the element in the previously focussed window was + clicked. + diff --git a/Changelog.md b/Changelog.md index c33e179..b9f7461 100644 --- a/Changelog.md +++ b/Changelog.md @@ -119,3 +119,10 @@ Changelog: * Add miniscule test suite * Adjust Cagebreak to wlroots 0.16.2 * New GPG Keys + +## Release 2.2.0 + + * Add custom events + * Fix Issue 62 (#46 Github) + * Fix Issue 63 (environment variables test) + * Fix Issue 64 (pointer focus bug) diff --git a/Hashes.md b/Hashes.md index a6ceae1..22a179e 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.2.0 cagebreak + + * sha 256: 67660297290a18b7822a818d1d43343e4e6f4dc27427ed9099ff803f218aa9b4 + * sha 512: 9837e3901b2b10453db2663f5a3da6ec2393610c82984cbabe1c64a6d575e32b492cd3326a6fbb91faa912d14c58dfd1160168280b66417ce7f7f2306c5a501c + +2.2.0 cagebreak.1 + + * sha 256: 79caf055cb1c75f3751863718728cca5ea6231891d21b4364c877d5e4888e727 + * sha 512: 843e15e51f01ed25d0630eee8b6e12ebcc68934da49d6fb66e86f6a46d512145d9be22081b0c2b5f0356c2d0e15b9f13170f7ba1d34d5fba69c7e05a069db337 + +2.2.0 cagebreak-config.5 + + * sha 256: 7047333f5600d3b05caf04caf9910da1468efe49c1418ca3fcdc6163bade9e89 + * sha 512: 35203d3959594fe5130a561c440bf85a978384bc874fcce773bb02fa5c637ccc375f1b0ce1ad05603266dcdefed2570815363bc2c8ef81df7ff7be865de2cac5 + +2.2.0 cagebreak-socket.7 + + * sha 256: bf9bd35a17ab78cb93f0f5209daef27908bf02d0e31ae627ae05fabab162c984 + * sha 512: 023fb99c3a2c47543ae2870f19e8fd6fd8069834dc4fbeee93e890333b4ac24b4613d0e8dfd2bdffb2d5dc7f907868410b0c61f2e1346c76498955e15d0f3b89 + 2.1.2 cagebreak * sha 256: 7d07864a837ee577a52b2727bfbfe8834fe599712144f0685f458d508717e451 diff --git a/README.md b/README.md index 004239a..8f09d4f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.1.2)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.0)](https://repology.org/project/cagebreak/versions) ## Quick Introduction diff --git a/ipc_server.c b/ipc_server.c index ced183a..05614b3 100644 --- a/ipc_server.c +++ b/ipc_server.c @@ -127,10 +127,6 @@ ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { return 0; } - if(client->write_buffer_len <= 0) { - return 0; - } - if(fcntl(client->fd, F_GETFD) == -1) { return 0; } diff --git a/keybinding.c b/keybinding.c index 44ccffb..eaf2ae7 100644 --- a/keybinding.c +++ b/keybinding.c @@ -96,6 +96,12 @@ keybinding_free(struct keybinding *keybinding, bool recursive) { if(keybinding->data.c != NULL) { free(keybinding->data.c); } + break; + case KEYBINDING_SEND_CUSTOM_EVENT: + if(keybinding->data.c != NULL) { + free(keybinding->data.c); + } + break; default: break; } @@ -1245,6 +1251,12 @@ keybinding_display_message(struct cg_server *server, char *msg) { message_printf(server->curr_output, "%s", msg); } +void +keybinding_send_custom_event(struct cg_server *server, char *msg) { + ipc_send_event(server, + "{\"event_name\":\"custom_event\",\"message\":\"%s\"}", msg); +} + void keybinding_move_view_to_cycle_output(struct cg_server *server, bool reverse) { if(wl_list_length(&server->outputs) <= 1) { @@ -1706,6 +1718,9 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_DISPLAY_MESSAGE: keybinding_display_message(server, data.c); break; + case KEYBINDING_SEND_CUSTOM_EVENT: + keybinding_send_custom_event(server, data.c); + break; case KEYBINDING_RESIZE_TILE_HORIZONTAL: resize_tile(server, data.i, 0); break; diff --git a/keybinding.h b/keybinding.h index 6d6cf87..a5958f0 100644 --- a/keybinding.h +++ b/keybinding.h @@ -63,6 +63,7 @@ struct cg_server; KEYBINDING(KEYBINDING_SHOW_TIME, time) \ KEYBINDING(KEYBINDING_SHOW_INFO, show_info) \ KEYBINDING(KEYBINDING_DISPLAY_MESSAGE, message) \ + KEYBINDING(KEYBINDING_SEND_CUSTOM_EVENT, custom_event) \ KEYBINDING(KEYBINDING_CURSOR, cursor) \ \ KEYBINDING(KEYBINDING_SWAP_LEFT, exchangeleft) \ diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index b9632dd..5bf01c3 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.1.2" "Cagebreak Manual" +cagebreak-config(5) "Version 2.2.0" "Cagebreak Manual" # NAME @@ -81,9 +81,17 @@ configure_message display_time 4 *cursor [enable|disable]* Enable or disable cursor + This simply hides the cursor. Pointing and clicking is still possible. +*custom_event * + Send a custom event to the IPC socket + + This sends an event of type "custom_event" to all programs + listening to the IPC socket along with the string . + See *cagebreak-socket(7)* for more details. + *definekey * Bind to execute if pressed in - *definekey* is a more general version of *bind*. diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index 4c1a31a..2a5b623 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.1.2" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.2.0" "Cagebreak Manual" # NAME @@ -113,6 +113,17 @@ cg-ipc{"event_name":"configure_output","output":"eDP-1","output_id":1} cg-ipc{"event_name":"cursor_switch_tile","old_output":"eDP-1","old_output_id":1,"old_tile":2,"new_output":"eDP-1","new_output_id":1,"new_tile":3} ``` +*custom_event* + - Trigger: Cagebreak receives the *custom_event* command, either in the config file or via the IPC socket (see *cagebreak-config(5)*). + - JSON + - event_name: "custom_event" + - message: The message passed to the *custom_event* command + +``` +custom_event Hello World! +cg-ipc{"event_name":"custom_event","message":"Hello World!"} +``` + *cycle_outputs* - Trigger: *nextscreen* and *prevscreen* commands - JSON diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index c8fc85e..051c7e9 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.1.2" "Cagebreak Manual" +cagebreak(1) "Version 2.2.0" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index 777c8d3..5d782bb 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.1.2', +version : '2.2.0', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -208,7 +208,7 @@ reproducible_build_versions = { 'xkbcommon': '1.5.0', 'fontconfig': '2.14.2', 'libinput': '1.23.0', - 'libevdev': '1.13.0', + 'libevdev': '1.13.1', 'libudev': '253', 'pango': '1.50.14', 'cairo': '1.17.8', @@ -238,7 +238,7 @@ foreach name, dep : cagebreak_dependencies_dict endforeach reproducible_build_compiler = 'gcc' -reproducible_build_compiler_version = '12.2.1' +reproducible_build_compiler_version = '13.1.1' if cc.get_id() != reproducible_build_compiler warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in Hashes.md (' + reproducible_build_compiler + ').') @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1682363199 + secssinceepoch = 1685543842 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/parse.c b/parse.c index 68767c6..c163b3a 100644 --- a/parse.c +++ b/parse.c @@ -811,6 +811,15 @@ parse_command(struct cg_server *server, struct keybinding *keybinding, return -1; } keybinding->data.c = strdup(saveptr); + } else if(strcmp(action, "custom_event") == 0) { + keybinding->action = KEYBINDING_SEND_CUSTOM_EVENT; + if(saveptr == NULL) { + *errstr = + log_error("Not enough paramaters to \"custom_event\". Expected " + "string to send."); + return -1; + } + keybinding->data.c = strdup(saveptr); } else if(strcmp(action, "time") == 0) { keybinding->action = KEYBINDING_SHOW_TIME; } else if(strcmp(action, "nextscreen") == 0) { diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index 5f93ac2..85c0622 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.1.2 -2023-04-24 +2.2.0 +2023-05-31 diff --git a/seat.c b/seat.c index cd085be..1c88f49 100644 --- a/seat.c +++ b/seat.c @@ -1043,6 +1043,7 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { view_activate(prev_view, false); } wlr_seat_keyboard_clear_focus(wlr_seat); + process_cursor_motion(seat, -1); return; } diff --git a/signatures/2.1.2-cagebreak-config.5.sig b/signatures/2.1.2-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..f96713d95f03f5db4cb5d9f359f5a07efe261263 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XN%(x{vno|Sj7x0L`Rsk` zzccF>sPdtgaU4+77ayFBN zL^y190up?k#V_WR^AIUpXARKF?>7Pi;N+0Lad*>|^}Rjv`Ht-`WO^?`ltx=!!sIC# z^G!&A7B+INK_M#jzyF%$+1LiW?U!5%MOQc26B8*GTlnd%8Gs-0Cgn}~T}@eGpvtkc z2|6({wHX<0T{+EhR2>^Qu3-&A%G>TykPPs0n75m>G5w!naEvg1&=TW;)NzxOQ)H;- zdyPhRslELoykhP2>JIQlaFf_qf;3A&`kRqsX?xGRY_m;^0Ssze;3I25@-&3jv{%LO zlt`NJBEZ0hE4D+0HmHM!j!XPoad8u>E$czw*o&rfvIjyILMlzJA%PU^WO29|T4_{) Ey-4Q{fB*mh literal 0 HcmV?d00001 diff --git a/signatures/2.1.2-cagebreak-socket.7.sig b/signatures/2.1.2-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..fec631f4783791825b37c8b15a6c4e24cca58d55 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XVo?CTq)#T*vDA8Uv0yd-^z|q<4hqC}C^c;56vGqqV62Z0uy0F_8W35NU8g;5AHC59BNy2{Q?7)R%MQUM`Tb zFv4dkl&*4`9`fA59G5+%c*$F><(@z?}Q_4rlof-K!}(ISCRNGVfw7&vuT$iT2Q zVWn@xp0K@o{>#Qo+54}2Gv&Ie*M@P$Fihu;Z>%`5l1R$1bJq$PcKxs!7vH1l$HSYy z25=-=ZZAhjUn)CT;B~FWgS_E>2VF|gB&V2gstyT9sHUEzMrDT}x+H8X_i7%_B&~SG zc$EpgnHN}f*FPwKB3N6xv*{nsJ0o4zyNLx7Q!ncY^a{fXJ@Esa@=vK;a4I z8_RhqV5KRy4RQ$`<*%w7xi{-nI3^0@?6iLUl|JA7`dsicN7B8sb~X01qEI9okTQ%W zOWuS5w!uKv3cn0ID(_u`!SgLEqIz;TBZrJ^#!ZwIg`kVr$r|}OTS~AVgz`8TEF)`r EcpuIZNB{r; literal 0 HcmV?d00001 diff --git a/signatures/2.1.2-cagebreak.1.sig b/signatures/2.1.2-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..78947664f97a829d9260f7b0ca9893af52431597 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XH&Qj|3vE2#Y^6LfBEt(FD&bm>Bqcp_iBViwa^f(K{t0D?!V5CHZzL!ufR3! zyz?2YNBfCc<;3OqzTnrq{)>k(%&BnGYt+-axf3=(G}sl{lLQQd(H2-Q%@ZLau4>nu zNMW7d^VsREfMH!M$9$HYlEBM>|6kD35+1uI%UqIEo2^622DgP@O$tLHx$d*980Rch ze9j2`VDBw4m!f8}?pnyop;R#sbL;w(!;6n5Q?|ipbaVSgEArB?h2ZQ}bVO~HGhQ=o6v9P|u z4KR14ets86#>W%0L2u|GAFv`=<-QLkl{NUmeWNO1Vw-$QfZ}r)Hs?S_0^171zHVVB>-%pE z07BOgiY;zQt~Kpeg>xNLwD5d%byVna<{5cccreqy9i7=oUEYXECZ!VLI^CN@X*@eG zU?NWI*A_8U$?YU!z6ZQcoerhjMX#**W=jaACCetS+A0|TLm+B$cQw6#d+cxf&3K`i z&;|;4sZvB}Z)+zA)inhQsBVnI#q}>R5-8vgEvg!Ji!S;QKh1bCMttvf>C%7}qq(Zv6isAH)uV$hx9h5EgW5)k0pHgaa?dreFtjJ}VC2HAS-!2_VVT~S7 z{6U*9Cu|k%{*PikV04S2?Ev8Oci;@xz!x?3$)2s|Xnqk7b7QnkI#t zwVyvLx{CzDTgBJ=F-iyjBYM!{JQ7H>j-8}ugRvkD*P1CwehD6+%k@xn6=fU1iJcOP z&OPIBV2HPFk|h;oGCr3gcKN#{4kx=nwsf`+AGhtUxUKN!MgI{OMcn4rLlI(M1Sj@; z7)v089Y#=;RHKo#K7OLOaju2N%v`I5un~nncJ&)3Xj1aOM_>hO2=NC4mNQ|iPqwc_ zDhgzB^dL%&*>I#sE6mXceGoq4mDE?q?b)-QO|O%%;f{s|N_YXrue;sbY!zvg1b7RQ zTmJ>+R^LUI)KuX?eP6-c2T6~+4?iE{P_Xfq1rYPs=$%Cn$f6IjlvLn&z+Bfk%Ii{h zkG#@S4^bmNRX?m9@a>;|?+(*As=n+zcd%;jIbNcCB9o6ldd(5EnY|x{j51y6R4jC$ E=0t7`+5i9m literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index f96713d95f03f5db4cb5d9f359f5a07efe261263..93f0f2b137cbd2db36c5d259df125d1ee4ce8865 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g~AyR{0M+4*SYs%?X2XCrbAjt<-qtD?iV1Kfw1}o5o(7}#ldmfXe|Q8u&pUN z;1>pRlFj8Yk_EMN3sjM`D$qY&(#JfS9zLYZNbPtg%jnDr$o}gi@iba?1UHY}Mvbi1 zY9~$Wa>QV~IgblyBuBchM6UxhNgIv%DVT&=qZ^p~DV~Wi?>rtHa?L4$PVeu zGeNLKy3kI`Wv=$u2w3jk$&-FPJ#x@mun^;W7L^uSxh!a5(3e~VHC6$%s955WSf%ey zVJ1}ug<~oZrp6HAXfm;N3AsYJ?m@BDo@=%8QR+AOA?QH!C)ZXp`c~y6i;==GCtbI- z3|Gr%%}QK9NnWy*9SgR%nb#}vVx3(WB=f?S{LAIZL-CpIcyU|IhZLhP4~qRJuy0L`Rsk` zzccF>sPdtgaU4+77ayFBN zL^y190up?k#V_WR^AIUpXARKF?>7Pi;N+0Lad*>|^}Rjv`Ht-`WO^?`ltx=!!sIC# z^G!&A7B+INK_M#jzyF%$+1LiW?U!5%MOQc26B8*GTlnd%8Gs-0Cgn}~T}@eGpvtkc z2|6({wHX<0T{+EhR2>^Qu3-&A%G>TykPPs0n75m>G5w!naEvg1&=TW;)NzxOQ)H;- zdyPhRslELoykhP2>JIQlaFf_qf;3A&`kRqsX?xGRY_m;^0Ssze;3I25@-&3jv{%LO zlt`NJBEZ0hE4D+0HmHM!j!XPoad8u>E$czw*o&rfvIjyILMlzJA%PU^WO29|T4_{) Ey-4Q{fB*mh diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index fec631f4783791825b37c8b15a6c4e24cca58d55..6797b53851edea4d660a160ac39ba424933ae7f8 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g+Zea{x)wi3b^5yc8v34hV_xo2U4*B64J?O@^ujB@SfR)`9N$WWv_9+w&by=n`Z10L;^t8vHM+X(iItm0}>qK*Og% zlbE9RmmRv)50SHwjoB*V&Y)0du^L~sExk1)VX05X@pZLLRhRCrMuitA;|@uH6tbyu z0=v$LZLZ9k2E-e@bVigM&&0h*d~LsyPGJljz#woGKwPs^_9n3kxi~cKRR{Gv!(o0fj$|i))kL)H%&VAlFOoJ_n{IAezk-IbJq?vjWj&)>SmAinpS^tE|?i1)xVIgfBKXjMFF2D_TDUUu?LI15@* E$Vc%83jhEB literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XVo?CTq)#T*vDA8Uv0yd-^z|q<4hqC}C^c;56vGqqV62Z0uy0F_8W35NU8g;5AHC59BNy2{Q?7)R%MQUM`Tb zFv4dkl&*4`9`fA59G5+%c*$F><(@z?}Q_4rlof-K!}(ISCRNGVfw7&vuT$iT2Q zVWn@xp0K@o{>#Qo+54}2Gv&Ie*M@P$Fihu;Z>%`5l1R$1bJq$PcKxs!7vH1l$HSYy z25=-=ZZAhjUn)CT;B~FWgS_E>2VF|gB&V2gstyT9sHUEzMrDT}x+H8X_i7%_B&~SG zc$EpgnHN}f*FPwKB3N6xv*{nsJ0o4zyNLx7Q!ncY^a{fXJ@Esa@=vK;a4I z8_RhqV5KRy4RQ$`<*%w7xi{-nI3^0@?6iLUl|JA7`dsicN7B8sb~X01qEI9okTQ%W zOWuS5w!uKv3cn0ID(_u`!SgLEqIz;TBZrJ^#!ZwIg`kVr$r|}OTS~AVgz`8TEF)`r EcpuIZNB{r; diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 78947664f97a829d9260f7b0ca9893af52431597..feaa1b95be49162eb7671ea4979cc74164621b87 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g}5gV|69{W6PqAyw{Ts${y}qxJn)v={wL^78q%**t^CNm5hKTaLL2ebp1?Be zkWZ>8?_`%dlJjtyvpdy{MP+oJgoMW$e{<&RqZqkNm=BXRw~jTr%#NL5m_uGm>kNFJ z)l5^#*!?1Q5vr;y%`xY~?{ejc71P)pbxfk(VkmMD%9Re~ZcJU{#LHAHZh1BH^ zSO@%TjHI%I6R%A|ynv^{bvVMwGaZY0+#ie^ctHCt#D0h4 z7unn1{xs;A%Hw-(fPoMkqcZ{y-Z|0Xsoy_d(;c~llUeY$1TKvAt;KETzE{NpmjL{> zESmaV>v#%hm!v~>#$$$_<9w`N0~L8sMo8)B&ha%tax<1~C~ouWaCq(yO#f{w7dd8x zz>0kc_o>Dz6v@L_#`OvdtezWObX?4H@cVhTWjQFG-_C5oY{$xWo8aAM80_<#;%{EW zW~ZB{sF?|bl}B0>Y2zH?WhD9tl?0o>I98#@HW|7Ppp~y!!+aZX$a|<%YK;pC{w9PY zyuC-~$>b8uOTPHsFAZUlT&O-1Bg-GsLif~x?~;VRj2@^}mSkCbMINUG7yi)2>FrF#}5yVG_VejcR@jO&U!ZL(}}!2c(Npv`1M`>dX~zf&PEw?{SXalnF+ E@3eXtpa1{> literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XH&Qj|3vE2#Y^6LfBEt(FD&bm>Bqcp_iBViwa^f(K{t0D?!V5CHZzL!ufR3! zyz?2YNBfCc<;3OqzTnrq{)>k(%&BnGYt+-axf3=(G}sl{lLQQd(H2-Q%@ZLau4>nu zNMW7d^VsREfMH!M$9$HYlEBM>|6kD35+1uI%UqIEo2^622DgP@O$tLHx$d*980Rch ze9j2`VDBw4m!f8}?pnyop;R#sbL;w(!;6n5Q?|ipbaVSgEArB?h2ZQ}bVO~HGhQ=o6v9P|u z4KR14ets86#>W%0L2u|GAFv`=<-QLkl{NUmeWNO1Vw-$QfZ}r)Hs?S_0^171zHVVB>-%pE z07BOgiY;zQt~Kpeg>xNLwD5d%byVna<{5cccreqy9i7=oUEYXECZ!VLI^CN@X*@eG zU?NWI*A_8U$?YU!z6ZQcoerhjMX#**W=jaACCetS+A0|TLm+B$cQw6#d+cxf&3K`i z&;|;4sZvB}Z)+zA)inhQsBVnI#q}>R5-8vgEvg!Ji!S;QKh1bCMttvf>C%l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g*FTj0GBbR7ZKk&(;f$PRCOUZZ@;#u6kAhcBUSR2ZB!sriHqbS+drH+u~XCG z4se3GCD*Z8ZTu7~CR8y!*IeDPu<<@prQ|n}B<_w&YS!4ThnuQRF&Ufh_cmG;NyR=i z{5QwTudvO%g2aFbkA=0!DK|!+y9sM9(NREFLx)oIq0;)8 z`W>Yd{B?Qh>W>xpC}E(Mwv3k;lh;^M6YQXE4xZyCT9Ww`*V`x@T5Nwq#sFHQi%wZP zRY)V@aBW_asf3+O=qBvg0T5+p;G}fAYG5DFP-u!(dP5MMR0ZIKlZ2ZGTXb0W{U+TL zyZCUZ0vJE>M#Q6M-s9gx5m|~|CeedcgrJjL;9&09*Ll(?^sYqCLReE5(i~(FB%`#n zj}|@giK5}liydM0)ToXV5q#9e)LTdx0&kBhZ4UK>3T4^CU-229wv!r69t2aEERijS E8Y$-!@&Et; literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XMW!h0Eh!1R%k=hodX8nwACP9sFdtasp)hWtSn%_UH1!yDPCD!X4Y8UDKIVE zO)nk@R>7}qq(Zv6isAH)uV$hx9h5EgW5)k0pHgaa?dreFtjJ}VC2HAS-!2_VVT~S7 z{6U*9Cu|k%{*PikV04S2?Ev8Oci;@xz!x?3$)2s|Xnqk7b7QnkI#t zwVyvLx{CzDTgBJ=F-iyjBYM!{JQ7H>j-8}ugRvkD*P1CwehD6+%k@xn6=fU1iJcOP z&OPIBV2HPFk|h;oGCr3gcKN#{4kx=nwsf`+AGhtUxUKN!MgI{OMcn4rLlI(M1Sj@; z7)v089Y#=;RHKo#K7OLOaju2N%v`I5un~nncJ&)3Xj1aOM_>hO2=NC4mNQ|iPqwc_ zDhgzB^dL%&*>I#sE6mXceGoq4mDE?q?b)-QO|O%%;f{s|N_YXrue;sbY!zvg1b7RQ zTmJ>+R^LUI)KuX?eP6-c2T6~+4?iE{P_Xfq1rYPs=$%Cn$f6IjlvLn&z+Bfk%Ii{h zkG#@S4^bmNRX?m9@a>;|?+(*As=n+zcd%;jIbNcCB9o6ldd(5EnY|x{j51y6R4jC$ E=0t7`+5i9m diff --git a/test/environment-variables b/test/environment-variables index f1c9fac..a3753b5 100644 --- a/test/environment-variables +++ b/test/environment-variables @@ -22,7 +22,7 @@ cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/config" "${testdir}/env sed -i "s|CONFIGPATH|$testdir\/envvars\/socket|g" "${testdir}/envvars/config" (WLR_BACKENDS=headless ./cagebreak -e -c "${testdir}/envvars/config") sync -[[ ! $(cat "${testdir}/socket") = "${oldsocket}" ]] || RESULT=1 +[[ $(cat "${testdir}/envvars/socket") != "${oldsocket}" ]] || RESULT=1 # XDG_CONFIG_HOME cp "${MESONCURRENTCONFIGDIR}/test/testing-configurations/env-var-config" "${testdir}/cagebreak/config" diff --git a/workspace.c b/workspace.c index 3f84c6f..1dff244 100644 --- a/workspace.c +++ b/workspace.c @@ -107,6 +107,9 @@ workspace_free_tiles(struct cg_workspace *workspace) { workspace->focused_tile) { workspace->output->server->seat->cursor_tile = NULL; } + if(workspace->focused_tile == workspace->server->seat->cursor_tile) { + workspace->server->seat->cursor_tile = NULL; + } struct cg_tile *next = workspace->focused_tile->next; free(workspace->focused_tile); workspace->focused_tile = next; From 61e7f8aeffa5eb8695788453a94619476bee0b64 Mon Sep 17 00:00:00 2001 From: project-repo Date: Mon, 21 Aug 2023 09:33:36 +0200 Subject: [PATCH 15/19] Release 2.2.1 * Fix Issue 65 (fix calibration matrix) * Thanks to Oliver Friedmann for providing a PR * Fix minor inelegance in README * Adjust dependency versions --- Bugs.md | 12 +++++++++++ Hashes.md | 20 ++++++++++++++++++ README.md | 8 ++++--- input_manager.c | 5 +++++ man/cagebreak-config.5.md | 2 +- man/cagebreak-socket.7.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 8 +++---- release-non-auto-checks/Bugs.md | 4 ++-- release-non-auto-checks/FAQ.md | 4 ++-- release-non-auto-checks/SECURITY.md | 4 ++-- release-non-auto-checks/WLR_XDG_VERSION | 4 ++-- .../acknowledge-contributors | 2 ++ release-non-auto-checks/changelog-major-minor | 4 ++-- release-non-auto-checks/internal-wiki | 4 ++-- release-non-auto-checks/release-note | 4 ++-- .../reproducibility-checked | 4 ++-- .../security-to-man-page-info-transfer | 4 ++-- signatures/2.1.2-cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/2.1.2-cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/2.1.2-cagebreak.1.sig | Bin 566 -> 566 bytes signatures/2.1.2-cagebreak.sig | Bin 566 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 26 files changed, 69 insertions(+), 28 deletions(-) create mode 100644 release-non-auto-checks/acknowledge-contributors diff --git a/Bugs.md b/Bugs.md index 4536616..ee38c63 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1223,3 +1223,15 @@ Steps to reproduce: * Observe that the element in the previously focussed window was clicked. +## Issue 65 + + * github issue number: N/A + * Fixed: 2.2.1 + +Up until cagebreak 2.2.0, the configuration for the calibration matrix of +a libinput device was not propagated correctly when internally copying +the configuration. This meant that effectively, the calibration matrix +configuration was a NoOp. Starting with version 2.2.1, the calibration +matrix can be set as documented. + +Thanks to Oliver Friedmann for providing a pull request. diff --git a/Hashes.md b/Hashes.md index 22a179e..240925f 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.2.1 cagebreak + + * sha 256: 96469a78eeaddf9476c82e0ab8a0e35a95b3119bf83633a54feb8f3f5780df2f + * sha 512: 41135e9d81c79519a1db4955c742f50a375c4e4db80b51a02d618eb1520452c059a3df48013d11f17410a590ac43634da606daf6e95d0987af19284964bbcb5e + +2.2.1 cagebreak.1 + + * sha 256: 458259b066def0571b7604f4a87105f0ce608106abd7946e4697aa5ec5028ccf + * sha 512: aeed13e27e78ea8b30ee21f6ef41725f2808f484f0a3e6125cf70c601705954eb4a4a67ba9d6898ff994a79c20a0213557332d7f06a42098084aff3fe47ca21a + +2.2.1 cagebreak-config.5 + + * sha 256: 4ec5a18fae8d1170ff9d67126133a12ca7b1f7adae318d77f6fca8092c138761 + * sha 512: 9b35fde46191979dee5839873eaab4a673256f75dce533df141f43f7d8282381e1e3820d1cf97403c50846b1f4ddf1924271e961d519029ed58e76e31aef4c04 + +2.2.1 cagebreak-socket.7 + + * sha 256: 51911ee02637261e46164d861c4327ec338904221795a03895684582c361ef81 + * sha 512: db848faefbf5f1eff6d4f0ad1fc4e2169beb7fd0ada620b39fe64a319376e4c7e672c48a3e446943af40d23055467b001b8e1c38b4b72648258b6f7b14c1034d + 2.2.0 cagebreak * sha 256: 67660297290a18b7822a818d1d43343e4e6f4dc27427ed9099ff803f218aa9b4 diff --git a/README.md b/README.md index 8f09d4f..1781cc3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.0)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.1)](https://repology.org/project/cagebreak/versions) ## Quick Introduction @@ -582,8 +582,8 @@ by at least one of the above collection. We registered project-repo.co and added mail addresses after release `1.3.0`. -We now have a mail address and its key is signed by signing keys. See Security -Bugs for details. +We now have a mail address and its key is signed by signing keys. See [SECURITY.md](SECURITY.md) +for details. The full public keys can be found in `keys/` along with any revocation certificates. @@ -747,6 +747,8 @@ see [SECURITY.md](SECURITY.md). * Oliver Friedmann * [Add output scaling](https://github.com/project-repo/cagebreak/pull/34), released in 2.0.0 with slight modifications + * [Fix: calibration matrix](https://github.com/project-repo/cagebreak/pull/49), + released in 2.2.1 with slight modifications * Tom Greig * Fix bug in merge_output_configs in 2.1.2 diff --git a/input_manager.c b/input_manager.c index cfde2c9..fcdd684 100644 --- a/input_manager.c +++ b/input_manager.c @@ -229,6 +229,11 @@ input_manager_merge_input_configs(struct cg_input_config *cfg1, } else { out_cfg->repeat_rate = cfg1->repeat_rate; } + if(cfg1->calibration_matrix.configured == false) { + out_cfg->calibration_matrix = cfg2->calibration_matrix; + } else { + out_cfg->calibration_matrix = cfg1->calibration_matrix; + } return out_cfg; } diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index 5bf01c3..f894d04 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.2.0" "Cagebreak Manual" +cagebreak-config(5) "Version 2.2.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index 2a5b623..210a4f9 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.2.0" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.2.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 051c7e9..d99a87a 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.2.0" "Cagebreak Manual" +cagebreak(1) "Version 2.2.1" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index 5d782bb..fb83017 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.2.0', +version : '2.2.1', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -209,7 +209,7 @@ reproducible_build_versions = { 'fontconfig': '2.14.2', 'libinput': '1.23.0', 'libevdev': '1.13.1', - 'libudev': '253', + 'libudev': '254', 'pango': '1.50.14', 'cairo': '1.17.8', 'pangocairo': '1.50.14', @@ -238,7 +238,7 @@ foreach name, dep : cagebreak_dependencies_dict endforeach reproducible_build_compiler = 'gcc' -reproducible_build_compiler_version = '13.1.1' +reproducible_build_compiler_version = '13.2.1' if cc.get_id() != reproducible_build_compiler warning('The compiler "' + cc.get_id() + '" differs from the one used to generate to binary specified in Hashes.md (' + reproducible_build_compiler + ').') @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1685543842 + secssinceepoch = 1692353837 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index 85c0622..d340262 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index 85c0622..d340262 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index 85c0622..d340262 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index 85c0622..d340262 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/acknowledge-contributors b/release-non-auto-checks/acknowledge-contributors new file mode 100644 index 0000000..d340262 --- /dev/null +++ b/release-non-auto-checks/acknowledge-contributors @@ -0,0 +1,2 @@ +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index 85c0622..d340262 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index 85c0622..d340262 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index 85c0622..d340262 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index 85c0622..d340262 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index 85c0622..d340262 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.2.0 -2023-05-31 +2.2.1 +2023-08-21 diff --git a/signatures/2.1.2-cagebreak-config.5.sig b/signatures/2.1.2-cagebreak-config.5.sig index f96713d95f03f5db4cb5d9f359f5a07efe261263..93f0f2b137cbd2db36c5d259df125d1ee4ce8865 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g~AyR{0M+4*SYs%?X2XCrbAjt<-qtD?iV1Kfw1}o5o(7}#ldmfXe|Q8u&pUN z;1>pRlFj8Yk_EMN3sjM`D$qY&(#JfS9zLYZNbPtg%jnDr$o}gi@iba?1UHY}Mvbi1 zY9~$Wa>QV~IgblyBuBchM6UxhNgIv%DVT&=qZ^p~DV~Wi?>rtHa?L4$PVeu zGeNLKy3kI`Wv=$u2w3jk$&-FPJ#x@mun^;W7L^uSxh!a5(3e~VHC6$%s955WSf%ey zVJ1}ug<~oZrp6HAXfm;N3AsYJ?m@BDo@=%8QR+AOA?QH!C)ZXp`c~y6i;==GCtbI- z3|Gr%%}QK9NnWy*9SgR%nb#}vVx3(WB=f?S{LAIZL-CpIcyU|IhZLhP4~qRJuy0L`Rsk` zzccF>sPdtgaU4+77ayFBN zL^y190up?k#V_WR^AIUpXARKF?>7Pi;N+0Lad*>|^}Rjv`Ht-`WO^?`ltx=!!sIC# z^G!&A7B+INK_M#jzyF%$+1LiW?U!5%MOQc26B8*GTlnd%8Gs-0Cgn}~T}@eGpvtkc z2|6({wHX<0T{+EhR2>^Qu3-&A%G>TykPPs0n75m>G5w!naEvg1&=TW;)NzxOQ)H;- zdyPhRslELoykhP2>JIQlaFf_qf;3A&`kRqsX?xGRY_m;^0Ssze;3I25@-&3jv{%LO zlt`NJBEZ0hE4D+0HmHM!j!XPoad8u>E$czw*o&rfvIjyILMlzJA%PU^WO29|T4_{) Ey-4Q{fB*mh diff --git a/signatures/2.1.2-cagebreak-socket.7.sig b/signatures/2.1.2-cagebreak-socket.7.sig index fec631f4783791825b37c8b15a6c4e24cca58d55..6797b53851edea4d660a160ac39ba424933ae7f8 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g+Zea{x)wi3b^5yc8v34hV_xo2U4*B64J?O@^ujB@SfR)`9N$WWv_9+w&by=n`Z10L;^t8vHM+X(iItm0}>qK*Og% zlbE9RmmRv)50SHwjoB*V&Y)0du^L~sExk1)VX05X@pZLLRhRCrMuitA;|@uH6tbyu z0=v$LZLZ9k2E-e@bVigM&&0h*d~LsyPGJljz#woGKwPs^_9n3kxi~cKRR{Gv!(o0fj$|i))kL)H%&VAlFOoJ_n{IAezk-IbJq?vjWj&)>SmAinpS^tE|?i1)xVIgfBKXjMFF2D_TDUUu?LI15@* E$Vc%83jhEB literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XVo?CTq)#T*vDA8Uv0yd-^z|q<4hqC}C^c;56vGqqV62Z0uy0F_8W35NU8g;5AHC59BNy2{Q?7)R%MQUM`Tb zFv4dkl&*4`9`fA59G5+%c*$F><(@z?}Q_4rlof-K!}(ISCRNGVfw7&vuT$iT2Q zVWn@xp0K@o{>#Qo+54}2Gv&Ie*M@P$Fihu;Z>%`5l1R$1bJq$PcKxs!7vH1l$HSYy z25=-=ZZAhjUn)CT;B~FWgS_E>2VF|gB&V2gstyT9sHUEzMrDT}x+H8X_i7%_B&~SG zc$EpgnHN}f*FPwKB3N6xv*{nsJ0o4zyNLx7Q!ncY^a{fXJ@Esa@=vK;a4I z8_RhqV5KRy4RQ$`<*%w7xi{-nI3^0@?6iLUl|JA7`dsicN7B8sb~X01qEI9okTQ%W zOWuS5w!uKv3cn0ID(_u`!SgLEqIz;TBZrJ^#!ZwIg`kVr$r|}OTS~AVgz`8TEF)`r EcpuIZNB{r; diff --git a/signatures/2.1.2-cagebreak.1.sig b/signatures/2.1.2-cagebreak.1.sig index 78947664f97a829d9260f7b0ca9893af52431597..feaa1b95be49162eb7671ea4979cc74164621b87 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g}5gV|69{W6PqAyw{Ts${y}qxJn)v={wL^78q%**t^CNm5hKTaLL2ebp1?Be zkWZ>8?_`%dlJjtyvpdy{MP+oJgoMW$e{<&RqZqkNm=BXRw~jTr%#NL5m_uGm>kNFJ z)l5^#*!?1Q5vr;y%`xY~?{ejc71P)pbxfk(VkmMD%9Re~ZcJU{#LHAHZh1BH^ zSO@%TjHI%I6R%A|ynv^{bvVMwGaZY0+#ie^ctHCt#D0h4 z7unn1{xs;A%Hw-(fPoMkqcZ{y-Z|0Xsoy_d(;c~llUeY$1TKvAt;KETzE{NpmjL{> zESmaV>v#%hm!v~>#$$$_<9w`N0~L8sMo8)B&ha%tax<1~C~ouWaCq(yO#f{w7dd8x zz>0kc_o>Dz6v@L_#`OvdtezWObX?4H@cVhTWjQFG-_C5oY{$xWo8aAM80_<#;%{EW zW~ZB{sF?|bl}B0>Y2zH?WhD9tl?0o>I98#@HW|7Ppp~y!!+aZX$a|<%YK;pC{w9PY zyuC-~$>b8uOTPHsFAZUlT&O-1Bg-GsLif~x?~;VRj2@^}mSkCbMINUG7yi)2>FrF#}5yVG_VejcR@jO&U!ZL(}}!2c(Npv`1M`>dX~zf&PEw?{SXalnF+ E@3eXtpa1{> literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XH&Qj|3vE2#Y^6LfBEt(FD&bm>Bqcp_iBViwa^f(K{t0D?!V5CHZzL!ufR3! zyz?2YNBfCc<;3OqzTnrq{)>k(%&BnGYt+-axf3=(G}sl{lLQQd(H2-Q%@ZLau4>nu zNMW7d^VsREfMH!M$9$HYlEBM>|6kD35+1uI%UqIEo2^622DgP@O$tLHx$d*980Rch ze9j2`VDBw4m!f8}?pnyop;R#sbL;w(!;6n5Q?|ipbaVSgEArB?h2ZQ}bVO~HGhQ=o6v9P|u z4KR14ets86#>W%0L2u|GAFv`=<-QLkl{NUmeWNO1Vw-$QfZ}r)Hs?S_0^171zHVVB>-%pE z07BOgiY;zQt~Kpeg>xNLwD5d%byVna<{5cccreqy9i7=oUEYXECZ!VLI^CN@X*@eG zU?NWI*A_8U$?YU!z6ZQcoerhjMX#**W=jaACCetS+A0|TLm+B$cQw6#d+cxf&3K`i z&;|;4sZvB}Z)+zA)inhQsBVnI#q}>R5-8vgEvg!Ji!S;QKh1bCMttvf>C%l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g*FTj0GBbR7ZKk&(;f$PRCOUZZ@;#u6kAhcBUSR2ZB!sriHqbS+drH+u~XCG z4se3GCD*Z8ZTu7~CR8y!*IeDPu<<@prQ|n}B<_w&YS!4ThnuQRF&Ufh_cmG;NyR=i z{5QwTudvO%g2aFbkA=0!DK|!+y9sM9(NREFLx)oIq0;)8 z`W>Yd{B?Qh>W>xpC}E(Mwv3k;lh;^M6YQXE4xZyCT9Ww`*V`x@T5Nwq#sFHQi%wZP zRY)V@aBW_asf3+O=qBvg0T5+p;G}fAYG5DFP-u!(dP5MMR0ZIKlZ2ZGTXb0W{U+TL zyZCUZ0vJE>M#Q6M-s9gx5m|~|CeedcgrJjL;9&09*Ll(?^sYqCLReE5(i~(FB%`#n zj}|@giK5}liydM0)ToXV5q#9e)LTdx0&kBhZ4UK>3T4^CU-229wv!r69t2aEERijS E8Y$-!@&Et; literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%S()fdC2#5J?I6 zOsG4!XMW!h0Eh!1R%k=hodX8nwACP9sFdtasp)hWtSn%_UH1!yDPCD!X4Y8UDKIVE zO)nk@R>7}qq(Zv6isAH)uV$hx9h5EgW5)k0pHgaa?dreFtjJ}VC2HAS-!2_VVT~S7 z{6U*9Cu|k%{*PikV04S2?Ev8Oci;@xz!x?3$)2s|Xnqk7b7QnkI#t zwVyvLx{CzDTgBJ=F-iyjBYM!{JQ7H>j-8}ugRvkD*P1CwehD6+%k@xn6=fU1iJcOP z&OPIBV2HPFk|h;oGCr3gcKN#{4kx=nwsf`+AGhtUxUKN!MgI{OMcn4rLlI(M1Sj@; z7)v089Y#=;RHKo#K7OLOaju2N%v`I5un~nncJ&)3Xj1aOM_>hO2=NC4mNQ|iPqwc_ zDhgzB^dL%&*>I#sE6mXceGoq4mDE?q?b)-QO|O%%;f{s|N_YXrue;sbY!zvg1b7RQ zTmJ>+R^LUI)KuX?eP6-c2T6~+4?iE{P_Xfq1rYPs=$%Cn$f6IjlvLn&z+Bfk%Ii{h zkG#@S4^bmNRX?m9@a>;|?+(*As=n+zcd%;jIbNcCB9o6ldd(5EnY|x{j51y6R4jC$ E=0t7`+5i9m diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index 93f0f2b137cbd2db36c5d259df125d1ee4ce8865..4a959e13f13ef5987a24bbb6bc8c7c921738b108 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%YHX-2e&+5J?I6 zOsG4!XQo~c{So||y?|0?M)3u$CcFzF)_LZS7Pymc>5n`Ri!1#cUhO4VUuudz^%-%h zwJ)E8oVzp~{~R2H%V8C~W$3TAx;v0NVmnaz2@|gODF=%M4k9HzfgT0J%nc*ATOvuk z!^W^{qu(kzt+?JcqCkFrso8HuoOP2<1#A5qGZ7Fyw!1{(`!ufUYC+kNvDIJSvudkx zt1zJ{B-`}bP?t`+m!QeZ;R?u7m+ju=9J((NIsU48Dyjsa0^mzL5!)<|({8*RHb3c6 zK}5h3978c|e=VzESOfzCVw^D#1ZD2WXbDL-^YW#P^Bx1BQ8*$87o4V>w5G#o^@jiO z)GdC+b4SbUUd`E;Tz%?J;z>FbK~eWc=%q#}As&+aQm!7l) z$Fd^(t8!#twP8d?1;7`hEe3hq+RHp6G_?qSgxy-8KK=nL%CaSjkeA=mWs|NL9Gn-h EAUQ`3sQ>@~ literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g~AyR{0M+4*SYs%?X2XCrbAjt<-qtD?iV1Kfw1}o5o(7}#ldmfXe|Q8u&pUN z;1>pRlFj8Yk_EMN3sjM`D$qY&(#JfS9zLYZNbPtg%jnDr$o}gi@iba?1UHY}Mvbi1 zY9~$Wa>QV~IgblyBuBchM6UxhNgIv%DVT&=qZ^p~DV~Wi?>rtHa?L4$PVeu zGeNLKy3kI`Wv=$u2w3jk$&-FPJ#x@mun^;W7L^uSxh!a5(3e~VHC6$%s955WSf%ey zVJ1}ug<~oZrp6HAXfm;N3AsYJ?m@BDo@=%8QR+AOA?QH!C)ZXp`c~y6i;==GCtbI- z3|Gr%%}QK9NnWy*9SgR%nb#}vVx3(WB=f?S{LAIZL-CpIcyU|IhZLhP4~qRJuy7+`G$243s*U-wVAgR7{w%0~6-t?7tf3~ahutq3?# zjl|Nnk6uqbhtavYDi!lu$o9qCCdpvf5e(nAVQASsYYp!dEvwi^ee0|PipH{?HXchI z&c75I{w!>=As-Gp;ayjxe&fU)RRjI54>%e7bw_zVx|J=FTFg8d3^+Q)Ofxvn{X9{` zT7~)InN|+RCKblN&hD9P$4FzYL2+kR|KR^ww6mxNAL11jcslAvV-&73!Pr0I1<$lL z)ObUzLz35 zip~M0*p34ZhN?t4s}T>e3mOIDU>T>LC!DVU+Ui#>i8A1$#w3!`u0#r%c;oC~Eh}Y5 zt1J7s=?e<2{yaxgO)t-w_0Fy9B2%x9x=Rh#YFZVD<7AoN_@0;v zOGEK1#gotcETyjpIyp)bKrl1*pxP71ME^Emzz)_#TuEZF7f1Me_x+EZG5{AqR#UAT EKn)iNFaQ7m literal 566 zcmV-60?GY}0y6{v0SEvc79j*$>l!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g+Zea{x)wi3b^5yc8v34hV_xo2U4*B64J?O@^ujB@SfR)`9N$WWv_9+w&by=n`Z10L;^t8vHM+X(iItm0}>qK*Og% zlbE9RmmRv)50SHwjoB*V&Y)0du^L~sExk1)VX05X@pZLLRhRCrMuitA;|@uH6tbyu z0=v$LZLZ9k2E-e@bVigM&&0h*d~LsyPGJljz#woGKwPs^_9n3kxi~cKRR{Gv!(o0fj$|i))kL)H%&VAlFOoJ_n{IAezk-IbJq?vjWj&)>SmAinpS^tE|?i1)xVIgfBKXjMFF2D_TDUUu?LI15@* E$Vc%83jhEB diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index feaa1b95be49162eb7671ea4979cc74164621b87..cdbd7812f165dad1f19ea2b2b9181f53b4825f6f 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%YHX-2e&+5J?I6 zOsG4!XQlBF0Erx3YeY2@5K4l&J*~(huos~pT;6m~#SOJViF|eoCy;;jHjy zl64=uqIcd~)dw3^bjE)7*84}rS-@%%JEj@|uRxA&@B{s(Hv%B0vKLM!-a-2X_zll^ zC!tN`TGxcas0q4$69%gMMqiorHm3FvqUqff^os?^mZVNCS|Vjw(;()AR}Ue5)N#*T zY%wX6f0=6{uqA|=)gBh&JnryQRnF!A(1q?uV7;nZLz!OoZx99ADYs$M(Dv$KxR$|? zuA8V)y(;<1HAUW~j|}*Ld65^fTX}+#N#b=17R#3Z-$DA?e`RK1|Ol)RKy6n_G z<99;!K)q#7lBTggtU8V;yg8Y)pB5YPi4u^+@o=(}rj+l)g{LA6?GmC650m}u_^3ZC zI48;Ea8hF%R2oLfSt{)Il7!jvvGl~)*x=r1zWWl!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g}5gV|69{W6PqAyw{Ts${y}qxJn)v={wL^78q%**t^CNm5hKTaLL2ebp1?Be zkWZ>8?_`%dlJjtyvpdy{MP+oJgoMW$e{<&RqZqkNm=BXRw~jTr%#NL5m_uGm>kNFJ z)l5^#*!?1Q5vr;y%`xY~?{ejc71P)pbxfk(VkmMD%9Re~ZcJU{#LHAHZh1BH^ zSO@%TjHI%I6R%A|ynv^{bvVMwGaZY0+#ie^ctHCt#D0h4 z7unn1{xs;A%Hw-(fPoMkqcZ{y-Z|0Xsoy_d(;c~llUeY$1TKvAt;KETzE{NpmjL{> zESmaV>v#%hm!v~>#$$$_<9w`N0~L8sMo8)B&ha%tax<1~C~ouWaCq(yO#f{w7dd8x zz>0kc_o>Dz6v@L_#`OvdtezWObX?4H@cVhTWjQFG-_C5oY{$xWo8aAM80_<#;%{EW zW~ZB{sF?|bl}B0>Y2zH?WhD9tl?0o>I98#@HW|7Ppp~y!!+aZX$a|<%YK;pC{w9PY zyuC-~$>b8uOTPHsFAZUlT&O-1Bg-GsLif~x?~;VRj2@^}mSkCbMINUG7yi)2>FrF#}5yVG_VejcR@jO&U!ZL(}}!2c(Npv`1M`>dX~zf&PEw?{SXalnF+ E@3eXtpa1{> diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index 4e3a176d1b3d0b26465a5adc8f4e83e069da9a33..f24848b41bc840338eb87ca186d8f1e2fc61b9c7 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%YHX-2e&+5J?I6 zOsG4!XF{_N{wD^_EjlrBNF8RJUth`RH`N1Vh}EIJH>TrLR-A$D$vn(8ppR$z`|@*t zdlat~vmxysYApsx)#+>|Qsg0oi)#=i*XRd-{NmC|E78#B>-kRju~Df3AqB)adYaVMaV0QXM>4W1aF{Y4d zW1W@fidlyGUbSc*L+%C|Yr2}$p2)+`)Nu5o(i)#}_j^qf{vW{edYxOxs=x;H&KCvS z+*qq!d`%&AIv{T>A`ls(1OIGZ(ZC5q$Hv+#Oi#Be8|tO(6W_*>g<>m!%ghD;=9!0K z(3N=YHgS$tFUnUAzno+B<&FctvxoC*0G+<`Xoe!pP$F)LEBUut|8P0NE-ppQOYB3a zkOQR*pRyWf9g&I#%kSX;y7E`I>2j4qxt)_aM95c3M)_~buX#*$TCx>WE+&y==Ic^D z2P1jjq%}y$o;~|=o%249x0{WCwq!-o&*BYiqS-Il!Yw(LZP72CP}!49FYc2K|Kv0%UifGXM$+5ZnyN z8{h{0g*FTj0GBbR7ZKk&(;f$PRCOUZZ@;#u6kAhcBUSR2ZB!sriHqbS+drH+u~XCG z4se3GCD*Z8ZTu7~CR8y!*IeDPu<<@prQ|n}B<_w&YS!4ThnuQRF&Ufh_cmG;NyR=i z{5QwTudvO%g2aFbkA=0!DK|!+y9sM9(NREFLx)oIq0;)8 z`W>Yd{B?Qh>W>xpC}E(Mwv3k;lh;^M6YQXE4xZyCT9Ww`*V`x@T5Nwq#sFHQi%wZP zRY)V@aBW_asf3+O=qBvg0T5+p;G}fAYG5DFP-u!(dP5MMR0ZIKlZ2ZGTXb0W{U+TL zyZCUZ0vJE>M#Q6M-s9gx5m|~|CeedcgrJjL;9&09*Ll(?^sYqCLReE5(i~(FB%`#n zj}|@giK5}liydM0)ToXV5q#9e)LTdx0&kBhZ4UK>3T4^CU-229wv!r69t2aEERijS E8Y$-!@&Et; From 61fb97b070b65335bab573daed4caeab97ad9a46 Mon Sep 17 00:00:00 2001 From: project-repo Date: Mon, 4 Dec 2023 12:22:24 +0100 Subject: [PATCH 16/19] Release 2.2.2 - Adjust Cagebreak to wlroot 0.17 - Improve README & SECURITY.md --- Hashes.md | 20 +++++++ README.md | 51 ++++++++---------- SECURITY.md | 33 ++++++------ cagebreak.c | 28 +++++----- fuzz/fuzz-lib.c | 10 ++-- idle_inhibit_v1.c | 4 +- keybinding.c | 24 ++++----- man/cagebreak-config.5.md | 2 +- man/cagebreak-socket.7.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 18 +++---- message.c | 1 - output.c | 37 ++++--------- output.h | 2 +- release-non-auto-checks/Bugs.md | 4 +- release-non-auto-checks/FAQ.md | 4 +- release-non-auto-checks/SECURITY.md | 4 +- release-non-auto-checks/WLR_XDG_VERSION | 4 +- .../acknowledge-contributors | 4 +- release-non-auto-checks/changelog-major-minor | 4 +- release-non-auto-checks/internal-wiki | 4 +- release-non-auto-checks/release-note | 4 +- .../reproducibility-checked | 4 +- .../security-to-man-page-info-transfer | 4 +- seat.c | 48 ++++++++--------- server.h | 4 +- signatures/2.2.1-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.2.1-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.2.1-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.2.1-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes view.c | 1 - view.h | 4 ++ workspace.c | 3 -- xdg_shell.c | 18 ++++--- xwayland.c | 40 ++++++++++---- xwayland.h | 2 + 40 files changed, 205 insertions(+), 189 deletions(-) create mode 100644 signatures/2.2.1-cagebreak-config.5.sig create mode 100644 signatures/2.2.1-cagebreak-socket.7.sig create mode 100644 signatures/2.2.1-cagebreak.1.sig create mode 100644 signatures/2.2.1-cagebreak.sig diff --git a/Hashes.md b/Hashes.md index 240925f..ace89e4 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.2.2 cagebreak + + * sha 256: 98e0dfe870a7242fdf7c6fb1a5c520cfe7d1154b3f139560da6cb86b2430b2a0 + * sha 512: c335f8f6e226203e797e232caead74db9b1e7f24d5edf80dd99a0c00c5f4e81351a5ddcad4f601a12618ebed5c62be547462c4f06ae4ccb6a622a869ee8741ec + +2.2.2 cagebreak.1 + + * sha 256: c655fff018377b5ee541854ee428559ba4c5080d44f87247fe608f18651b0764 + * sha 512: 7cbef17cbe3c59cde21466d6c76e1a34ffce748d2d9011a77bd7703f605b737e344cabaad1e3a599316321481524cb860b2533ab6bef2e7714c00b2641fe962c + +2.2.2 cagebreak-config.5 + + * sha 256: b799e0252d7224befc92bdd143d00dc3f42a38e39f510f3ace575b03f293a788 + * sha 512: 3778db9ff07429efb74b4b07476193844698e07ea91a742aac078391ba38fb07987dc61ba312c30b6eb04ad2d847ee552826e7a09be8dc572be5626c27059df3 + +2.2.2 cagebreak-socket.7 + + * sha 256: dd10359fd1840909bb817858668e67bdd433f367b0ed199328e4b29c99529322 + * sha 512: 67f8c39864472c9b2396946a943ce249297b1b9fc5e452a4051f0512fd61b4a22906e1a16aee1c2bf6cacb3b9cd7a11da19c5d760c192020402008eab379eee1 + 2.2.1 cagebreak * sha 256: 96469a78eeaddf9476c82e0ab8a0e35a95b3119bf83633a54feb8f3f5780df2f diff --git a/README.md b/README.md index 1781cc3..f2fd64d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.1)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.2)](https://repology.org/project/cagebreak/versions) ## Quick Introduction @@ -9,25 +9,21 @@ based on [Cage](https://github.com/Hjdskes/cage) and inspired by [ratpoison](htt ### Purpose -The goal of this project is to provide a successor to ratpoison for Wayland. +This project provides a successor to ratpoison for Wayland. However, this is no reimplementation of ratpoison. #### New Features, Bugs and Contact Information -Should you want to know if a feature will be implemented, file a bug or -get in touch, [open an issue](https://github.com/project-repo/cagebreak/issues/new) +You can [open an issue](https://github.com/project-repo/cagebreak/issues/new) or write an e-mail (See [SECURITY.md](SECURITY.md) for details.). -The Roadmap section outlines what is planned for the future. +The Roadmap section outlines our plans. #### Compatibility & Development Distribution Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the libraries -(and software versions) as they are obtained through [pacman](https://wiki.archlinux.org/title/Pacman) -at the time of release. Any other use is out of scope. - -Most other setups probably work with a bit of luck. We -make no guarantees. +and versions from extra and core at the time of release. +Most other setups work with a bit of luck. ### Quick Installation @@ -42,17 +38,12 @@ details on getting started and the documentation for everything else. ### Documentation - * the rest of this file - * the man pages: - * [cagebreak](man/cagebreak.1.md) - * [configuration](man/cagebreak-config.5.md) - * [socket](man/cagebreak-socket.7.md) - * the [FAQ](FAQ.md) - * [SECURITY.md](SECURITY.md) + * the man pages: [cagebreak](man/cagebreak.1.md), [configuration](man/cagebreak-config.5.md) & [socket](man/cagebreak-socket.7.md) + * the [README](README.md), [FAQ](FAQ.md) & [SECURITY.md](SECURITY.md) #### What's new? -See the [Changelog](Changelog.md). +Check the [Changelog](Changelog.md). ### Uninstallation @@ -60,9 +51,9 @@ See the [Changelog](Changelog.md). ### Contributing - * Just [open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your idea. - We will consider the proposal and get back to you. - * Don't open a pull request. We might not accept your code and + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your idea. + We will get back to you. + * Ask before you open a pull request. We might not accept your code and it would be sad to waste the effort. * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never had to intervene - Keep it that way!) @@ -208,16 +199,16 @@ as a source of inspiration and explanations for certain particularities. ## Contributing * Read this document. - * Just [open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your feature request. - We will consider the proposal and get back to you. - * Don't open a pull request without asking first. We might not accept your + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your feature request. + We will get back to you. + * Ask before opening a pull request. We might not accept your code and it would be sad to waste the effort. * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never had to intervene - Please keep it that way!) ### Good First Contributions - * Reviewing the project is always welcome. + * Reviews are always welcome. * Read the code. * Read the documentation. * Test whether the documentation matches the code. @@ -225,12 +216,12 @@ as a source of inspiration and explanations for certain particularities. * Compile the code. * Ideas on improving the testing and quality assurance are particularly welcome. - * If you want, you can share your cagebreak scripts and we might include them - in the repository provided you agree to release them under MIT and we agree - with the use case and coding style. - * Iff you are happy with Cagebreak and use Arch Linux, you may vote for + * You can share your cagebreak scripts and we might include them with Cagebreak + provided you agree to release them under MIT and we agree with the + use case and coding style. + * If you are happy with Cagebreak under Arch Linux, you may vote for [Cagebreak in the AUR](https://aur.archlinux.org/packages/cagebreak). - * The points above still apply. + * The points from the Contributing section above still apply. ### Philosophy diff --git a/SECURITY.md b/SECURITY.md index 2f33197..a55a2b4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -51,11 +51,10 @@ public key or provide the fingerprint and directions to obtain the key. ## Threat Model -Cagebreak is a wayland compositor run by the user of the system -and thus has access to whichever resources this user has access to. -Cagebreak can restrict other programs in no way, because this would hamper -usability (consider a web browser unable to write a downloaded file to disk -for instance). +Cagebreak is a wayland compositor run by a user and has access to +the resources the user has access to. +Cagebreak cannot restrict other programs (consider a web browser +unable to write a downloaded file for instance). There is no transmission of information by cagebreak other than to the screens, ipc and potentially other documented local channels. @@ -63,38 +62,36 @@ screens, ipc and potentially other documented local channels. ### STRIDE Threat List This is not a thorough analysis, just an overview of the ways in which cagebreak -has (no) attack surface. Please reference the man pages for details but especially -the -e and --bs options. +has (no) attack surface. Please reference the man pages (especially options -e and --bs ). #### Spoofing -Not applicable - Using Cagebreak already requires a login as a user. +Not applicable - Cagebreak is executed after user login. #### Tampering -Not applicable - Cagebreak must allow system manipulation for user software. +Not applicable - Cagebreak allows system manipulation for user software. #### Repudiation Not applicable - There are no prohibited operations (See Tampering above.). -While cagebreak does send events over documented channels there is no logging -activated by default, though, of course, this can be changed by the user -by logging socket output (if enabled) for example. +Cagebreak sends events over documented channels. There is no logging +activated by default - this can be changed by logging the socket (if enabled) for example. #### Information Disclosure -Not applicable - Information disclosure over documented channels is a feature -and any software run by the user may exfiltrate any data the user has access to. +Not applicable - Information disclosure over documented channels is a feature. +Any user software may exfiltrate any data the user has access to. #### Denial of Service -Not applicable - Cagebreak offers functionality to terminate itself, which is -available to all user software over the socket if the socket is enabled. +Not applicable - Cagebreak offers functionality to terminate itself. This is +available to user software over the socket (if enabled). #### Elevation of Privilege -Software may gain arbitrary code execution rights if it has access to the -Cagebreak socket. Privilege escalation to root is unlikely since privileges +Software may gain arbitrary code execution if it has access to the +socket (if enabled). Privilege escalation to root is unlikely since privileges are dropped before any user input is accepted. ## GPG Keys of the Cagebreak Repository diff --git a/cagebreak.c b/cagebreak.c index 4437331..66afdf3 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -368,7 +368,7 @@ main(int argc, char *argv[]) { wl_event_loop_add_signal(event_loop, SIGPIPE, handle_signal, &server); server.event_loop = event_loop; - backend = wlr_backend_autocreate(server.wl_display); + backend = wlr_backend_autocreate(server.wl_display, &server.session); if(!backend) { wlr_log(WLR_ERROR, "Unable to create the wlroots backend"); ret = 1; @@ -428,9 +428,10 @@ main(int argc, char *argv[]) { ret = 1; goto end; } - wlr_scene_attach_output_layout(server.scene, server.output_layout); + server.scene_output_layout = + wlr_scene_attach_output_layout(server.scene, server.output_layout); - compositor = wlr_compositor_create(server.wl_display, server.renderer); + compositor = wlr_compositor_create(server.wl_display, 6, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); ret = 1; @@ -474,14 +475,8 @@ main(int argc, char *argv[]) { goto end; } - server.idle = wlr_idle_create(server.wl_display); - if(!server.idle) { - wlr_log(WLR_ERROR, "Unable to create the idle tracker"); - ret = 1; - goto end; - } - server.idle_inhibit_v1 = wlr_idle_inhibit_v1_create(server.wl_display); + server.idle = wlr_idle_notifier_v1_create(server.wl_display); if(!server.idle_inhibit_v1) { wlr_log(WLR_ERROR, "Cannot create the idle inhibitor"); ret = 1; @@ -687,6 +682,12 @@ main(int argc, char *argv[]) { wl_display_run(server.wl_display); +#if CG_HAS_XWAYLAND + if(server.xwayland != NULL) { + wlr_xwayland_destroy(server.xwayland); + } +#endif + wl_display_destroy_clients(server.wl_display); end: @@ -734,11 +735,6 @@ end: if(server.seat != NULL) { seat_destroy(server.seat); } -#if CG_HAS_XWAYLAND - if(server.xwayland != NULL) { - wlr_xwayland_destroy(server.xwayland); - } -#endif if(sigint_source != NULL) { wl_event_source_remove(sigint_source); diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index d331880..650d8a8 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -25,10 +25,9 @@ #include #include #include -#include #include +#include #include -#include #include #include #include @@ -271,9 +270,10 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { ret = 1; goto end; } - wlr_scene_attach_output_layout(server.scene, server.output_layout); + server.scene_output_layout = + wlr_scene_attach_output_layout(server.scene, server.output_layout); - compositor = wlr_compositor_create(server.wl_display, server.renderer); + compositor = wlr_compositor_create(server.wl_display, 5, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); ret = 1; @@ -310,7 +310,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { goto end; } - server.idle = wlr_idle_create(server.wl_display); + server.idle = wlr_idle_notifier_v1_create(server.wl_display); if(!server.idle) { wlr_log(WLR_ERROR, "Unable to create the idle tracker"); ret = 1; diff --git a/idle_inhibit_v1.c b/idle_inhibit_v1.c index b4f91f9..019d47b 100644 --- a/idle_inhibit_v1.c +++ b/idle_inhibit_v1.c @@ -2,8 +2,8 @@ // SPDX-License-Identifier: MIT #include -#include #include +#include #include "idle_inhibit_v1.h" #include "server.h" @@ -24,7 +24,7 @@ idle_inhibit_v1_check_active(struct cg_server *server) { /* As of right now, this does not check whether the inhibitor * is visible or not.*/ bool inhibited = !wl_list_empty(&server->inhibitors); - wlr_idle_set_enabled(server->idle, NULL, !inhibited); + wlr_idle_notifier_v1_set_inhibited(server->idle, inhibited); } #if CG_HAS_FANALYZE #pragma GCC diagnostic pop diff --git a/keybinding.c b/keybinding.c index eaf2ae7..6da0cc6 100644 --- a/keybinding.c +++ b/keybinding.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -506,11 +505,10 @@ keybinding_workspace_fullscreen(struct cg_server *server) { // Switch to a differerent virtual terminal static int -keybinding_switch_vt(struct wlr_backend *backend, unsigned int vt) { - if(wlr_backend_is_multi(backend)) { - struct wlr_session *session = wlr_backend_get_session(backend); - if(session) { - wlr_session_change_vt(session, vt); +keybinding_switch_vt(struct cg_server *server, unsigned int vt) { + if(wlr_backend_is_multi(server->backend)) { + if(server->session) { + wlr_session_change_vt(server->session, vt); } return 0; } @@ -1627,11 +1625,11 @@ void set_cursor(bool enabled, struct cg_seat *seat) { if(enabled == true) { seat->enable_cursor = true; - wlr_xcursor_manager_set_cursor_image(seat->xcursor_manager, - DEFAULT_XCURSOR, seat->cursor); + wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, + DEFAULT_XCURSOR); } else { seat->enable_cursor = false; - wlr_cursor_set_image(seat->cursor, NULL, 0, 0, 0, 0, 0, 0); + wlr_cursor_unset_image(seat->cursor); } } @@ -1645,7 +1643,7 @@ run_action(enum keybinding_action action, struct cg_server *server, server->running = false; break; case KEYBINDING_CHANGE_TTY: - return keybinding_switch_vt(server->backend, data.u); + return keybinding_switch_vt(server, data.u); case KEYBINDING_CURSOR: set_cursor(data.i, server->seat); break; @@ -1688,9 +1686,9 @@ run_action(enum keybinding_action action, struct cg_server *server, if(data.u != server->seat->default_mode) { wlr_seat_pointer_notify_clear_focus(server->seat->seat); if(server->seat->enable_cursor == true) { - wlr_xcursor_manager_set_cursor_image( - server->seat->xcursor_manager, "dot_box_mask", - server->seat->cursor); + wlr_cursor_set_xcursor(server->seat->cursor, + server->seat->xcursor_manager, + "dot_box_mask"); } } server->seat->mode = data.u; diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index f894d04..c04c757 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.2.1" "Cagebreak Manual" +cagebreak-config(5) "Version 2.2.2" "Cagebreak Manual" # NAME diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index 210a4f9..d61e498 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.2.1" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.2.2" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index d99a87a..7e0c421 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.2.1" "Cagebreak Manual" +cagebreak(1) "Version 2.2.2" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index fb83017..e28557e 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.2.1', +version : '2.2.2', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -55,7 +55,7 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: ['>=0.16.1', '< 0.17.0']) +wlroots = dependency('wlroots', version: ['>=0.16.1', '< 0.17.1']) wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') @@ -204,15 +204,15 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.22.0', 'wayland_cursor': '1.22.0', - 'wlroots': '0.16.2', - 'xkbcommon': '1.5.0', + 'wlroots': '0.17.0', + 'xkbcommon': '1.6.0', 'fontconfig': '2.14.2', - 'libinput': '1.23.0', + 'libinput': '1.24.0', 'libevdev': '1.13.1', 'libudev': '254', - 'pango': '1.50.14', - 'cairo': '1.17.8', - 'pangocairo': '1.50.14', + 'pango': '1.51.0', + 'cairo': '1.18.0', + 'pangocairo': '1.51.0', 'math': '-1' } @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1692353837 + secssinceepoch = 1701680868 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/message.c b/message.c index 74b1d0a..d74b8cf 100644 --- a/message.c +++ b/message.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/output.c b/output.c index 506f5bd..d4fef70 100644 --- a/output.c +++ b/output.c @@ -15,9 +15,9 @@ #include #endif #include +#include #include #include -#include #include #include #include @@ -42,7 +42,7 @@ void output_clear(struct cg_output *output) { struct cg_server *server = output->server; - wlr_output_layout_remove(server->output_layout, output->wlr_output); + wlr_scene_output_destroy(output->scene_output); if(server->running && server->curr_output == output && wl_list_length(&server->outputs) > 1) { @@ -118,7 +118,6 @@ output_destroy(struct cg_output *output) { int outp_num = output_get_num(output); wl_list_remove(&output->destroy.link); - wl_list_remove(&output->mode.link); wl_list_remove(&output->commit.link); wl_list_remove(&output->frame.link); @@ -166,7 +165,7 @@ handle_output_frame(struct wl_listener *listener, void *data) { if(scene_output == NULL) { return; } - wlr_scene_output_commit(scene_output); + wlr_scene_output_commit(scene_output, NULL); struct timespec now = {0}; clock_gettime(CLOCK_MONOTONIC, &now); @@ -439,8 +438,9 @@ handle_output_commit(struct wl_listener *listener, void *data) { return; } - if(event->committed & - (WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_SCALE)) { + if(event->state->committed & + (WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_SCALE | + WLR_OUTPUT_STATE_MODE)) { struct cg_view *view; wl_list_for_each( view, &output->workspaces[output->curr_workspace]->views, link) { @@ -451,23 +451,6 @@ handle_output_commit(struct wl_listener *listener, void *data) { } } -static void -handle_output_mode(struct wl_listener *listener, void *data) { - struct cg_output *output = wl_container_of(listener, output, mode); - - if(!output->wlr_output->enabled || output->workspaces == NULL) { - return; - } - - struct cg_view *view; - wl_list_for_each(view, &output->workspaces[output->curr_workspace]->views, - link) { - if(view_is_visible(view)) { - view_maximize(view, view->tile); - } - } -} - void output_make_workspace_fullscreen(struct cg_output *output, int ws) { struct cg_server *server = output->server; @@ -517,6 +500,7 @@ handle_new_output(struct wl_listener *listener, void *data) { } struct cg_output *output = calloc(1, sizeof(struct cg_output)); + output->scene_output = wlr_scene_output_create(server->scene, wlr_output); if(!output) { wlr_log(WLR_ERROR, "Failed to allocate output"); return; @@ -568,8 +552,8 @@ handle_new_output(struct wl_listener *listener, void *data) { if(server->curr_output == NULL) { server->curr_output = output; } - wlr_xcursor_manager_set_cursor_image(server->seat->xcursor_manager, - DEFAULT_XCURSOR, server->seat->cursor); + wlr_cursor_set_xcursor(server->seat->cursor, server->seat->xcursor_manager, + DEFAULT_XCURSOR); wlr_cursor_warp(server->seat->cursor, NULL, 0, 0); output->destroy.notify = handle_output_destroy; @@ -578,8 +562,7 @@ handle_new_output(struct wl_listener *listener, void *data) { wl_signal_add(&wlr_output->events.frame, &output->frame); output->commit.notify = handle_output_commit; wl_signal_add(&wlr_output->events.commit, &output->commit); - output->mode.notify = handle_output_mode; - wl_signal_add(&wlr_output->events.mode, &output->mode); + ipc_send_event(server, "{\"event_name\":\"new_output\",\"output\":\"%s\",\"output_" "id\":%d,\"priority\":%d}", diff --git a/output.h b/output.h index 90cd615..c1d4853 100644 --- a/output.h +++ b/output.h @@ -16,8 +16,8 @@ struct cg_output { struct cg_server *server; struct wlr_output *wlr_output; struct wlr_scene_rect *bg; + struct wlr_scene_output *scene_output; - struct wl_listener mode; struct wl_listener commit; struct wl_listener destroy; struct wl_listener frame; diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index d340262..9388d0a 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index d340262..9388d0a 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index d340262..9388d0a 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index d340262..9388d0a 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/acknowledge-contributors b/release-non-auto-checks/acknowledge-contributors index d340262..9388d0a 100644 --- a/release-non-auto-checks/acknowledge-contributors +++ b/release-non-auto-checks/acknowledge-contributors @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index d340262..9388d0a 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index d340262..9388d0a 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index d340262..9388d0a 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index d340262..9388d0a 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index d340262..9388d0a 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.2.1 -2023-08-21 +2.2.2 +2023-12-04 diff --git a/seat.c b/seat.c index 1c88f49..80206e9 100644 --- a/seat.c +++ b/seat.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -59,10 +59,10 @@ update_capabilities(const struct cg_seat *seat) { /* Hide cursor if the seat doesn't have pointer capability. */ if(((caps & WL_SEAT_CAPABILITY_POINTER) == 0) || seat->enable_cursor == false) { - wlr_cursor_set_image(seat->cursor, NULL, 0, 0, 0, 0, 0, 0); + wlr_cursor_unset_image(seat->cursor); } else { - wlr_xcursor_manager_set_cursor_image(seat->xcursor_manager, - DEFAULT_XCURSOR, seat->cursor); + wlr_cursor_set_xcursor(seat->cursor, seat->xcursor_manager, + DEFAULT_XCURSOR); } } @@ -169,7 +169,7 @@ handle_modifier_event(struct wlr_input_device *device, struct cg_seat *seat) { wlr_seat_set_keyboard(seat->seat, keyboard); wlr_seat_keyboard_notify_modifiers(seat->seat, &keyboard->modifiers); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } void @@ -205,12 +205,11 @@ handle_command_key_bindings(struct cg_server *server, xkb_keysym_t sym, &server->scene->tree.node, server->seat->cursor->x, server->seat->cursor->y, &sx, &sy); if(server->seat->enable_cursor) { - wlr_xcursor_manager_set_cursor_image(server->seat->xcursor_manager, - "left_ptr", - server->seat->cursor); + wlr_cursor_set_xcursor(server->seat->cursor, + server->seat->xcursor_manager, "left_ptr"); if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer( + wlr_scene_surface_try_from_buffer( wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { surface = scene_surface->surface; @@ -239,7 +238,7 @@ handle_command_key_bindings(struct cg_server *server, xkb_keysym_t sym, } message_clear(group->seat->server->curr_output); run_action((*keybinding)->action, server, (*keybinding)->data); - wlr_idle_notify_activity(server->idle, server->seat->seat); + wlr_idle_notifier_v1_notify_activity(server->idle, server->seat->seat); return true; } else if(mode != 0) { run_action(KEYBINDING_NOOP, server, (union keybinding_params){NULL}); @@ -312,7 +311,7 @@ handle_key_event(struct cg_keyboard_group *group, struct cg_seat *seat, event->keycode, event->state); } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -589,7 +588,7 @@ handle_touch_down(struct wl_listener *listener, void *data) { uint32_t serial = 0; if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { serial = wlr_seat_touch_notify_down( seat->seat, scene_surface->surface, event->time_msec, @@ -603,7 +602,7 @@ handle_touch_down(struct wl_listener *listener, void *data) { seat->touch_ly = ly; } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -616,7 +615,7 @@ handle_touch_up(struct wl_listener *listener, void *data) { } wlr_seat_touch_notify_up(seat->seat, event->time_msec, event->touch_id); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -638,7 +637,7 @@ handle_touch_motion(struct wl_listener *listener, void *data) { if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { wlr_seat_touch_point_focus(seat->seat, scene_surface->surface, @@ -657,7 +656,7 @@ handle_touch_motion(struct wl_listener *listener, void *data) { seat->touch_ly = ly; } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -665,7 +664,7 @@ handle_cursor_frame(struct wl_listener *listener, void *_data) { struct cg_seat *seat = wl_container_of(listener, seat, cursor_frame); wlr_seat_pointer_notify_frame(seat->seat); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -676,7 +675,7 @@ handle_cursor_axis(struct wl_listener *listener, void *data) { wlr_seat_pointer_notify_axis(seat->seat, event->time_msec, event->orientation, event->delta, event->delta_discrete, event->source); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -686,7 +685,7 @@ handle_cursor_button(struct wl_listener *listener, void *data) { wlr_seat_pointer_notify_button(seat->seat, event->time_msec, event->button, event->state); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -701,7 +700,7 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { if(node && node->type == WLR_SCENE_NODE_BUFFER) { struct wlr_scene_surface *scene_surface = - wlr_scene_surface_from_buffer(wlr_scene_buffer_from_node(node)); + wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node)); if(scene_surface != NULL) { surface = scene_surface->surface; if(surface != NULL) { @@ -722,7 +721,7 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { drag_icon_update_position(drag_icon); } - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); /* Check if cursor switched tile */ struct wlr_output *c_outp = wlr_output_layout_output_at( @@ -749,7 +748,8 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { break; } } - if(seat->cursor_tile != NULL && seat->cursor_tile != c_tile) { + if(seat->cursor_tile != NULL && seat->cursor_tile != c_tile && + seat->server->running) { ipc_send_event(seat->server, "{\"event_name\":\"cursor_switch_tile\",\"old_output\":" "\"%s\",\"old_output_id\":%d," @@ -772,7 +772,7 @@ handle_cursor_motion_absolute(struct wl_listener *listener, void *data) { wlr_cursor_warp_absolute(seat->cursor, &event->pointer->base, event->x, event->y); process_cursor_motion(seat, event->time_msec); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void @@ -783,7 +783,7 @@ handle_cursor_motion(struct wl_listener *listener, void *data) { wlr_cursor_move(seat->cursor, &event->pointer->base, event->delta_x, event->delta_y); process_cursor_motion(seat, event->time_msec); - wlr_idle_notify_activity(seat->server->idle, seat->seat); + wlr_idle_notifier_v1_notify_activity(seat->server->idle, seat->seat); } static void diff --git a/server.h b/server.h index 9f6eca6..0c067ec 100644 --- a/server.h +++ b/server.h @@ -26,17 +26,19 @@ struct cg_server { struct cg_seat *seat; struct cg_input_manager *input; struct wlr_backend *backend; - struct wlr_idle *idle; + struct wlr_idle_notifier_v1 *idle; struct wlr_idle_inhibit_manager_v1 *idle_inhibit_v1; struct wl_listener new_idle_inhibitor_v1; struct wl_list inhibitors; struct wlr_output_layout *output_layout; + struct wlr_scene_output_layout *scene_output_layout; struct wl_list disabled_outputs; struct wl_list outputs; struct cg_output *curr_output; struct wl_listener new_output; struct wl_list output_priorities; + struct wlr_session *session; struct wlr_renderer *renderer; struct wlr_allocator *allocator; diff --git a/signatures/2.2.1-cagebreak-config.5.sig b/signatures/2.2.1-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..4a959e13f13ef5987a24bbb6bc8c7c921738b108 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%YHX-2e&+5J?I6 zOsG4!XQo~c{So||y?|0?M)3u$CcFzF)_LZS7Pymc>5n`Ri!1#cUhO4VUuudz^%-%h zwJ)E8oVzp~{~R2H%V8C~W$3TAx;v0NVmnaz2@|gODF=%M4k9HzfgT0J%nc*ATOvuk z!^W^{qu(kzt+?JcqCkFrso8HuoOP2<1#A5qGZ7Fyw!1{(`!ufUYC+kNvDIJSvudkx zt1zJ{B-`}bP?t`+m!QeZ;R?u7m+ju=9J((NIsU48Dyjsa0^mzL5!)<|({8*RHb3c6 zK}5h3978c|e=VzESOfzCVw^D#1ZD2WXbDL-^YW#P^Bx1BQ8*$87o4V>w5G#o^@jiO z)GdC+b4SbUUd`E;Tz%?J;z>FbK~eWc=%q#}As&+aQm!7l) z$Fd^(t8!#twP8d?1;7`hEe3hq+RHp6G_?qSgxy-8KK=nL%CaSjkeA=mWs|NL9Gn-h EAUQ`3sQ>@~ literal 0 HcmV?d00001 diff --git a/signatures/2.2.1-cagebreak-socket.7.sig b/signatures/2.2.1-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..c2006c13f278568e1f3dcf9c7987f024611c72d6 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%YHX-2e&+5J?I6 zOsG4!XGNqC0Hz9+wC;n0Gi?5@lJY#U^YIRf{|^*8eRtER7;$M0Qb${|8_~tEj))HH z=dd5<`J0kI!Ij%qLvdD_CVl}Rb&js>7+`G$243s*U-wVAgR7{w%0~6-t?7tf3~ahutq3?# zjl|Nnk6uqbhtavYDi!lu$o9qCCdpvf5e(nAVQASsYYp!dEvwi^ee0|PipH{?HXchI z&c75I{w!>=As-Gp;ayjxe&fU)RRjI54>%e7bw_zVx|J=FTFg8d3^+Q)Ofxvn{X9{` zT7~)InN|+RCKblN&hD9P$4FzYL2+kR|KR^ww6mxNAL11jcslAvV-&73!Pr0I1<$lL z)ObUzLz35 zip~M0*p34ZhN?t4s}T>e3mOIDU>T>LC!DVU+Ui#>i8A1$#w3!`u0#r%c;oC~Eh}Y5 zt1J7s=?e<2{yaxgO)t-w_0Fy9B2%x9x=Rh#YFZVD<7AoN_@0;v zOGEK1#gotcETyjpIyp)bKrl1*pxP71ME^Emzz)_#TuEZF7f1Me_x+EZG5{AqR#UAT EKn)iNFaQ7m literal 0 HcmV?d00001 diff --git a/signatures/2.2.1-cagebreak.1.sig b/signatures/2.2.1-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..cdbd7812f165dad1f19ea2b2b9181f53b4825f6f GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%YHX-2e&+5J?I6 zOsG4!XQlBF0Erx3YeY2@5K4l&J*~(huos~pT;6m~#SOJViF|eoCy;;jHjy zl64=uqIcd~)dw3^bjE)7*84}rS-@%%JEj@|uRxA&@B{s(Hv%B0vKLM!-a-2X_zll^ zC!tN`TGxcas0q4$69%gMMqiorHm3FvqUqff^os?^mZVNCS|Vjw(;()AR}Ue5)N#*T zY%wX6f0=6{uqA|=)gBh&JnryQRnF!A(1q?uV7;nZLz!OoZx99ADYs$M(Dv$KxR$|? zuA8V)y(;<1HAUW~j|}*Ld65^fTX}+#N#b=17R#3Z-$DA?e`RK1|Ol)RKy6n_G z<99;!K)q#7lBTggtU8V;yg8Y)pB5YPi4u^+@o=(}rj+l)g{LA6?GmC650m}u_^3ZC zI48;Ea8hF%R2oLfSt{)Il7!jvvGl~)*x=r1zWWTrLR-A$D$vn(8ppR$z`|@*t zdlat~vmxysYApsx)#+>|Qsg0oi)#=i*XRd-{NmC|E78#B>-kRju~Df3AqB)adYaVMaV0QXM>4W1aF{Y4d zW1W@fidlyGUbSc*L+%C|Yr2}$p2)+`)Nu5o(i)#}_j^qf{vW{edYxOxs=x;H&KCvS z+*qq!d`%&AIv{T>A`ls(1OIGZ(ZC5q$Hv+#Oi#Be8|tO(6W_*>g<>m!%ghD;=9!0K z(3N=YHgS$tFUnUAzno+B<&FctvxoC*0G+<`Xoe!pP$F)LEBUut|8P0NE-ppQOYB3a zkOQR*pRyWf9g&I#%kSX;y7E`I>2j4qxt)_aM95c3M)_~buX#*$TCx>WE+&y==Ic^D z2P1jjq%}y$o;~|=o%249x0{WCwq!-o&*BYiqS-I+Hg={^|yMxhAMp#(r@TjP?IuP_3~Vk zdnB5WIxqxUM(1WfPPO#7agQOnJf*P+$lX&SlL}tj@{w|5hnD8j1_}>gi_nUBiv*Ac z1*oj{31I(2Wq%~EkUwErc1mnnLAbJe;0-8ACY7zE^ouZE$yA3d&;{&y6jl@o-a@7g zNO9A&W^oX28CD`};&`U3e2pnGZCyobS!bPflc4?q!XkQcpq9v*k3!X}oSxa|m9SBy zBLDxKoO%w0WJcI@`P`hHf2t44z%nA1ZEre9Q`2>L(|=;MyDvs;ZC}Hhw+rIJL2{(} zzT%?eQDqpytUf&f4k*err?qLMkuyxyq~Yv#`mJik@q@E{4%MtIWr%0~yEg=q!rA=> zaXGR~n77M0^g0bM1qdG$2fU#ftYD<&!x7l4TSBMS)5zVv&&j&j)Skqst%&j>rE}pz hL4_pcau|GV0%E3Ogq#{tp%vU9^+DsLs{GR9^L1@G3Ag|N delta 543 zcmV+)0^t3&1hxc_B7bDxh1~!O2@pvM_)MrfxM!wb5B(ARo4tTiW=8P^ttPw+A=Y{3 zj~2L-Zt0Ia5Q{7Q9A51uSYK+2KJ^)Ks-sK#+ zFA+KZs(LD_1fT-oOFR+VERNG|yc{+^=}|#Mz!DroF>HS=t6*3J0|H{4F%JY~?#E~e zNjLNIrHu0)1Am}VI3foZoTi(!ro(9UhX3%?Eq=vwN6YM9&Dob+edCG*%D(WNNE7%RntaZt&JyZoYs5|CYcGg;@(U`!+{r>dM(bQm!7l)$Fd^(t8!#twP8d?1;7`hEe3hq+RHp6 hG_?qSgc#jgpg#TqEXuMaijbGz(q)sb7#y4zupnI`2VMXG diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index c2006c13f278568e1f3dcf9c7987f024611c72d6..e46522fc40240c6f9b09db2bf27cfdd64bf76e96 100644 GIT binary patch delta 543 zcmV+)0^t3&1hxc_B7bFVu;Ks;2@pvM_)MrfxM%5#5CF-V!k0qVjS%xt1huT9r$2|3 zT$OuJ5cNENS_}C*d%QA-RB)snkED!%WW&up)p^F4HAv@XGGT{qPFsNAOkaxAC8MHV z;}HhfrUw;N7}gg@R}aAiGAB4B~qjQqjZtHD2aj+DBFz zT*e1-{P2J6*MDn$O;sNot(7}%dvsB)o&2*_^PkwxXu0yB0uHGJaE?CU7L*hu3=LD^ z<(=;%>%*QKN($bD)Jrl$oZ=^iw<#gfIzK=`2Po7Sofu#vDDqcYUdxPi-44B%ZXFoK zN~`c^VRsrnJ1^5VJ2Mr#Vx!ew<6mX@GCkRzpsg-5nSY@Vv^6E$u=xb|YNZIX5ZuXZ zY?6uBJypXYor5KI29?U?pk>oIb(2T0QQA9?3u67W|3Pd}fK>dfuQ4h8{-iQGo*$t{ z0u0{UFgf%A4!l9rH>ARW27GtA3hL>D`AdT~eNf~Q+eU>-5Pp}@Z3~eMNv}-71@`j& hN+Kd&R~UgX)(X>?Jk`_L^D&m?5#cM!Y|GY}pE3?Y04o3h delta 543 zcmV+)0^t3&1hxc_B7bDxh1~!O2@pvM_)MrfxMxMA5CEnMm9*}IgEMUYu9EURvGef` zivJH3I(>K3rx*uf^=J}hFKf#sTRzq=CnI?V#Aa#ze?HFKf z1qNR0^k4T+xP@R%f(t$#u|?pS&y}!mcJKcka!XaDE?fsH4}Ym)&}dV){(T|WFk{Le zi#4mz5e({B!-&d8_3EwZh+YhAx>~IWI8lwn(zcIYPd$gxxw$G8^IFLE#oH#yVAv51 z-?w3C**$9w?-VVo*hhWqtOJV1vYj>_OC8R?6dL|4Y_cIA4m#moSEPR9#2r-w{jLu< z8T)ldc|N+8Eq{?(%sd$kI6B2lGdRxuJW<42h56!{Ru0D|6~@2L?wM@INMo)+ac5Tl z;Qv{)v#16i;uRKnI_gGa6s|JC*gxV0&$Kqwcv0__j)!R)R!uz-LsxNug{HfE1G<+# z2laUQ&0o{do+;>ItsAJ@p9MObx?L5%mm)Wc&H<&^j(-CVhN?t4s}T>e3mOIDU>T>L zC!DVU+Ui#>i8A1$#w3!`u0#r%c;oC~Eh}Y5t1J7s=?e<2{yaxg zO)t-w_0Fy9B2%x9x=Rh#YFZVD<7AoN_@0;vOGEK1#gotcETyjpIyp)bKrl1*pxP71 hME^Emz!(nJL|jQ?u@^`9d-wg1oiYFyKvq+&8$dKf0p$Py diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index cdbd7812f165dad1f19ea2b2b9181f53b4825f6f..36b2c99c6362034807b3beb0c00a4aa236f3e13e 100644 GIT binary patch delta 543 zcmV+)0^t3&1hxc_B7bFVu;Ks;2@pvM_)MrfxMy_!5CEu?Eyqc}+97z+9jwQ zG=?LB$)6xBq7;qYA0~VSn6jb_lUO(zai%}KYRCd%Xl}Berhmt=pR++@jmz%?k?{l+ zT*06xQw|*Ip89!#w5>}VDxd|u!7n2{C~*hHwg_$7a;EMr`WYcpT%iyr*qo=zKi#J;Q7C@!BwGfOK4j1rq`p#pN}{qk{EmxMlF=*dVeF{0D21#XMOOGOW~@cLINRpP7->NaYty+7Fv-uZ!+?oMe0=$Y8rBN zddQajRrfPRIIdYixy*N*BNSCMX6v3weE^7+81)$5WmP-AUe=ew?=SkKgY#54DXFsr9?geAE{Tr7h0)KRsgm=2G$gXhc&3wH+jmVOg zDTITrvk?Ecfs zA6(vaL^uk~@9cE}3Oq$N?|w?G(&4P|XOeXvyP|jATh#{}R&>UG_tyJI#aX~=5<8|E z0k1%gZtw&BrZ)m0rm`1KCf-5&1^5lmcqgGvS4H+!H}+-s8PKt`N=g!-ldNW_<(tl7qMG;f|5z* zWBgi8SkM0)Gk>f1WD70H7~DgH3AGz5dknk2DJZT?Wuq>}t}#mBw{0Z^S4mhgA|(Kq zBWgk!J)5Pb9_`OojcvU()J(%aR|PDRUTpMO*8(mS$}*ND9~?t_&a_J@hr_H>P~TZD zLSp0Uy}KoBKZYWGRK|!AzUO zXO6-GxLPb|bb>2aB?Z$n>OGI_-0wnx3=va{Ygfn7TLvTdMt|L`3F)$9xMtwVGVe58 zLXnuq@3qN;`^1S8nmLY+FB7K?nR|y>50A$t_?V_r2lbje>Bo)a3IwlF0YBAoc}(EZ zI@03L-%yr3hXZ0cSJoH>SuW05KtZ;vZ{q@-JOA@2cG+-+3P9#@ zkns_jd?UPV5Py%+%sj~Ha~N*-|GQeRyKgdU4LhShXpYzL*c(?P$nb-YKI-=-MPbP8 zUxKoXXL$$fi8xFog4m{Oq|)Dq6wGAcOx?SUeWCClm&gZfL2)W$byv2G9nf>`cMDiP zmmlCQ8McuVD4oO)7*bOAS7%@S?>fGNsTbkw?gGiZOMfy=m~h?Ol_pt6b!a08qW7{` z8oBb#l1cngsaRgFFXKY}2t@I4!@$_2uy#(&n#EOT2&33>w_GZ6K%ERqS;&h0pUp}C zMb21sc@@Z~-r|$cL+Exh he5i+X!5C#`Ms3!3%fN+%`%r9;(fyl8TXlczjIq?=4Q&7b delta 543 zcmV+)0^t3&1hxc_B7bDxh1~!O2@pvM_)MrfxMxDM5B?_x%`G}Ha!4I!oL^tb=Qq^@ zWQf(Fy*H-gQ&yaT?a4gMHK31Y`up;8e|r?K6|*7j9%?NHNY&|VCQ{@fgo|qsCD-T& zfBfRoN-NRO=j-`S__0x`0U^w}8&Sm1!dX6L1wKxFQWs-(qJKYTgR%v2K3Gs1>4+Mt6h9eA#^$*Z!97Z8KMLKY+lj82}8%m z+AB;?w<;UzrGM-b-^P)JVk>~l%mx4EnTKJ}m3ZwoagJ6m%2y7*oMZLnjsw55hx2Oy zoxbyEh9b;RB5sK*`L|mCa5=&*E=A2t>_e!K1Ema~vKnU{k%|V(@8JNt@>jR%a+N~4 zos&64$X7{5`ESavc}#U$vK3Pry=jBYEDWHGfFRo;~|=o%249x0{WCwq!-o z&*BYiqS-I #include #include -#include #include #include #include diff --git a/view.h b/view.h index a3b61ed..b9ec0a1 100644 --- a/view.h +++ b/view.h @@ -28,6 +28,10 @@ struct cg_view { struct cg_tile *tile; struct wlr_scene_tree *scene_tree; + struct wl_listener destroy; + struct wl_listener unmap; + struct wl_listener map; + /* The view has a position in output coordinates. */ int ox, oy; diff --git a/workspace.c b/workspace.c index 1dff244..3f84c6f 100644 --- a/workspace.c +++ b/workspace.c @@ -107,9 +107,6 @@ workspace_free_tiles(struct cg_workspace *workspace) { workspace->focused_tile) { workspace->output->server->seat->cursor_tile = NULL; } - if(workspace->focused_tile == workspace->server->seat->cursor_tile) { - workspace->server->seat->cursor_tile = NULL; - } struct cg_tile *next = workspace->focused_tile->next; free(workspace->focused_tile); workspace->focused_tile = next; diff --git a/xdg_shell.c b/xdg_shell.c index afa3352..79f322f 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -23,12 +23,14 @@ static struct cg_view * popup_get_view(struct wlr_xdg_popup *popup) { while(true) { - if(popup->parent == NULL || - !wlr_surface_is_xdg_surface(popup->parent)) { + if(popup->parent == NULL) { return NULL; } struct wlr_xdg_surface *xdg_surface = - wlr_xdg_surface_from_wlr_surface(popup->parent); + wlr_xdg_surface_try_from_wlr_surface(popup->parent); + if(xdg_surface == NULL) { + return NULL; + } switch(xdg_surface->role) { case WLR_XDG_SURFACE_ROLE_TOPLEVEL: return xdg_surface->data; @@ -244,9 +246,10 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { xdg_shell_view->xdg_surface = xdg_surface; xdg_shell_view->map.notify = handle_xdg_shell_surface_map; - wl_signal_add(&xdg_surface->events.map, &xdg_shell_view->map); + wl_signal_add(&xdg_surface->surface->events.map, &xdg_shell_view->map); xdg_shell_view->unmap.notify = handle_xdg_shell_surface_unmap; - wl_signal_add(&xdg_surface->events.unmap, &xdg_shell_view->unmap); + wl_signal_add(&xdg_surface->surface->events.unmap, + &xdg_shell_view->unmap); xdg_shell_view->destroy.notify = handle_xdg_shell_surface_destroy; wl_signal_add(&xdg_surface->events.destroy, &xdg_shell_view->destroy); xdg_shell_view->request_fullscreen.notify = @@ -265,7 +268,10 @@ handle_xdg_shell_surface_new(struct wl_listener *listener, void *data) { struct wlr_scene_tree *parent_scene_tree = NULL; struct wlr_xdg_surface *parent = - wlr_xdg_surface_from_wlr_surface(popup->parent); + wlr_xdg_surface_try_from_wlr_surface(popup->parent); + if(parent == NULL) { + return; + } switch(parent->role) { case WLR_XDG_SURFACE_ROLE_TOPLEVEL:; parent_scene_tree = view->scene_tree; diff --git a/xwayland.c b/xwayland.c index ece9e5a..21cc2ba 100644 --- a/xwayland.c +++ b/xwayland.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -42,8 +41,12 @@ xwayland_view_should_manage(const struct cg_view *view) { static pid_t get_pid(const struct cg_view *view) { struct wlr_xwayland_surface *surf = - wlr_xwayland_surface_from_wlr_surface(view->wlr_surface); - return surf->pid; + wlr_xwayland_surface_try_from_wlr_surface(view->wlr_surface); + if(surf == NULL) { + return -1; + } else { + return surf->pid; + } } static char * @@ -154,8 +157,6 @@ handle_xwayland_surface_destroy(struct wl_listener *listener, void *_data) { wl_container_of(listener, xwayland_view, destroy); struct cg_view *view = &xwayland_view->view; - wl_list_remove(&xwayland_view->map.link); - wl_list_remove(&xwayland_view->unmap.link); wl_list_remove(&xwayland_view->destroy.link); wl_list_remove(&xwayland_view->request_fullscreen.link); xwayland_view->xwayland_surface = NULL; @@ -173,6 +174,25 @@ static const struct cg_view_impl xwayland_view_impl = { .destroy = destroy, }; +static void +handle_xwayland_surface_associate(struct wl_listener *listener, void *data) { + struct cg_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, associate); + struct wlr_xwayland_surface *xsurface = xwayland_view->xwayland_surface; + wl_signal_add(&xsurface->surface->events.unmap, &xwayland_view->unmap); + xwayland_view->unmap.notify = handle_xwayland_surface_unmap; + wl_signal_add(&xsurface->surface->events.map, &xwayland_view->map); + xwayland_view->map.notify = handle_xwayland_surface_map; +} + +static void +handle_xwayland_surface_dissociate(struct wl_listener *listener, void *data) { + struct cg_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, dissociate); + wl_list_remove(&xwayland_view->map.link); + wl_list_remove(&xwayland_view->unmap.link); +} + void handle_xwayland_surface_new(struct wl_listener *listener, void *data) { struct cg_server *server = @@ -190,10 +210,12 @@ handle_xwayland_surface_new(struct wl_listener *listener, void *data) { server); xwayland_view->xwayland_surface = xwayland_surface; - xwayland_view->map.notify = handle_xwayland_surface_map; - wl_signal_add(&xwayland_surface->events.map, &xwayland_view->map); - xwayland_view->unmap.notify = handle_xwayland_surface_unmap; - wl_signal_add(&xwayland_surface->events.unmap, &xwayland_view->unmap); + xwayland_view->associate.notify = handle_xwayland_surface_associate; + wl_signal_add(&xwayland_surface->events.associate, + &xwayland_view->associate); + xwayland_view->dissociate.notify = handle_xwayland_surface_dissociate; + wl_signal_add(&xwayland_surface->events.dissociate, + &xwayland_view->dissociate); xwayland_view->destroy.notify = handle_xwayland_surface_destroy; wl_signal_add(&xwayland_surface->events.destroy, &xwayland_view->destroy); xwayland_view->request_fullscreen.notify = diff --git a/xwayland.h b/xwayland.h index 71a0b7a..79c265a 100644 --- a/xwayland.h +++ b/xwayland.h @@ -13,6 +13,8 @@ struct cg_xwayland_view { struct wl_listener destroy; struct wl_listener unmap; struct wl_listener map; + struct wl_listener associate; + struct wl_listener dissociate; struct wl_listener request_fullscreen; }; From 5dbefccb59d93d3b9683fb243458674a9267da56 Mon Sep 17 00:00:00 2001 From: project-repo Date: Tue, 5 Dec 2023 14:42:22 +0100 Subject: [PATCH 17/19] Release 2.2.3 - Fix positioning of outputs (#66) - Fix version specification of wlroots (#65) - Add version check to prevent #65 in the future --- Bugs.md | 17 +++++++++++++++ Hashes.md | 20 ++++++++++++++++++ README.md | 2 +- man/cagebreak-config.5.md | 2 +- man/cagebreak-socket.7.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 6 +++--- output.c | 11 +++++++--- release-non-auto-checks/Bugs.md | 4 ++-- release-non-auto-checks/FAQ.md | 4 ++-- release-non-auto-checks/SECURITY.md | 4 ++-- release-non-auto-checks/WLR_XDG_VERSION | 4 ++-- .../acknowledge-contributors | 4 ++-- release-non-auto-checks/changelog-major-minor | 4 ++-- release-non-auto-checks/internal-wiki | 4 ++-- release-non-auto-checks/release-note | 4 ++-- .../reproducibility-checked | 4 ++-- .../security-to-man-page-info-transfer | 4 ++-- release-non-auto-checks/version-restrictions | 2 ++ signatures/2.2.2-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.2.2-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.2.2-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.2.2-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 27 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 release-non-auto-checks/version-restrictions create mode 100644 signatures/2.2.2-cagebreak-config.5.sig create mode 100644 signatures/2.2.2-cagebreak-socket.7.sig create mode 100644 signatures/2.2.2-cagebreak.1.sig create mode 100644 signatures/2.2.2-cagebreak.sig diff --git a/Bugs.md b/Bugs.md index ee38c63..be04464 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1235,3 +1235,20 @@ configuration was a NoOp. Starting with version 2.2.1, the calibration matrix can be set as documented. Thanks to Oliver Friedmann for providing a pull request. + +## Issue 66 + + * github issue number: #65 + * Fixed 2.2.3 + +In Cagebreak 2.2.2 the compatible wlroots versions were wrongly specified. +To stop this from reoccurring, we have added a check to our release checks. + +## Issue 67 + + * github issue number: #66 + * Fixed 2.2.3 + +In Cagebreak 2.2.2 dual monitors were mirrored instead of extended, changing +established behaviour. + diff --git a/Hashes.md b/Hashes.md index ace89e4..867692b 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.2.3 cagebreak + + * sha 256: 265a9d09622272ca6ea79ddcdbdc6003704106814eb05a2b7547a77a982263de + * sha 512: 757f837a7e6ddd71fed88c4e1aab5cab9d4d07e8b76f280eed9afa35a2eaee23c0553299fe49a0139c754179d0df68c1303725f1f909921d078516e14ba3f21f + +2.2.3 cagebreak.1 + + * sha 256: 275698641476efa40fc1b33a8025e6dbba3ec931fbaf0a627c0748dad987ed4d + * sha 512: 617891ded06657e31daefee84a03191ad6e03892118f1790a5ebaa6e847c4d18d4b6849edc00841bd68abc9e0e0a111153efe102db02ce3d408c903b0d045927 + +2.2.3 cagebreak-config.5 + + * sha 256: 5967e9131d1ee16ffa046a732911c902e41f2e18f3170d11a47b9be596b4978a + * sha 512: 6d3c5fbb2b95a75d7c5a8ed8b5922cfcc4135857b389652572c5d9c211c6da9cf8ef0b5dc0e8eaa540c6b1c2dd215f512df2ef49ce80c34e8e5ad170bfb7134e + +2.2.3 cagebreak-socket.7 + + * sha 256: cb1bde8a6fb2a1fa2b7b8db7fdef9b933cd471ca604e15d1dd9133859fa6eea3 + * sha 512: 1d99672cb7ac7323790d47986d206bf8c392698db0cd52978963deb6e85118c6822e2d45c7fa66e8636e95214f8893d963a3157ca24239d2fd2d78b1e26f11e7 + 2.2.2 cagebreak * sha 256: 98e0dfe870a7242fdf7c6fb1a5c520cfe7d1154b3f139560da6cb86b2430b2a0 diff --git a/README.md b/README.md index f2fd64d..1ca4ce5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Wayland Tiling Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.2)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.3)](https://repology.org/project/cagebreak/versions) ## Quick Introduction diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index c04c757..d5b4969 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.2.2" "Cagebreak Manual" +cagebreak-config(5) "Version 2.2.3" "Cagebreak Manual" # NAME diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index d61e498..19365d6 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.2.2" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.2.3" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 7e0c421..bdd469f 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.2.2" "Cagebreak Manual" +cagebreak(1) "Version 2.2.3" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index e28557e..aeb3346 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.2.2', +version : '2.2.3', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -55,7 +55,7 @@ if is_freebsd ) endif -wlroots = dependency('wlroots', version: ['>=0.16.1', '< 0.17.1']) +wlroots = dependency('wlroots', version: ['>=0.17.0', '< 0.18.0']) wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_server = dependency('wayland-server') wayland_cursor = dependency('wayland-cursor') @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1701680868 + secssinceepoch = 1701768836 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/output.c b/output.c index d4fef70..0a482f0 100644 --- a/output.c +++ b/output.c @@ -282,15 +282,20 @@ output_apply_config(struct cg_server *server, struct cg_output *output, wlr_output_commit(wlr_output); return; } - wlr_output_layout_add(server->output_layout, wlr_output, config->pos.x, - config->pos.y); + struct wlr_output_layout_output *lo = wlr_output_layout_add( + server->output_layout, wlr_output, config->pos.x, config->pos.y); + wlr_scene_output_layout_add_output(server->scene_output_layout, lo, + output->scene_output); /* Since the size of the output may have changed, we * reinitialize all workspaces with a fullscreen layout */ for(unsigned int i = 0; i < output->server->nws; ++i) { output_make_workspace_fullscreen(output, i); } } else { - wlr_output_layout_add_auto(server->output_layout, wlr_output); + struct wlr_output_layout_output *lo = + wlr_output_layout_add_auto(server->output_layout, wlr_output); + wlr_scene_output_layout_add_output(server->scene_output_layout, lo, + output->scene_output); struct wlr_output_mode *preferred_mode = wlr_output_preferred_mode(wlr_output); diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/acknowledge-contributors b/release-non-auto-checks/acknowledge-contributors index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/acknowledge-contributors +++ b/release-non-auto-checks/acknowledge-contributors @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index 9388d0a..16e03cd 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.2.2 -2023-12-04 +2.2.3 +2023-12-05 diff --git a/release-non-auto-checks/version-restrictions b/release-non-auto-checks/version-restrictions new file mode 100644 index 0000000..16e03cd --- /dev/null +++ b/release-non-auto-checks/version-restrictions @@ -0,0 +1,2 @@ +2.2.3 +2023-12-05 diff --git a/signatures/2.2.2-cagebreak-config.5.sig b/signatures/2.2.2-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..811fe372025fbcaaa8f497ef6bc25d9d37641be9 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dKm;s6Q>5J?I6 zOsG4!XJMfb0E>`au^^z8E*v#Fd9jxSr%FdRbeic+={rm$M))f-=$6&xrq{OVP9ncaEXyy zAm(BmYFS|7U3ot(_njmrb6^i@efjvv!bFfE-9V|jzLe+S=)^oS4@KmC#38hfayR0W z7!ulWP+;}9dcB4!eG$@c=vPpaGFbKUT$6hwnvgm$1X@PtW<=F$cV4`7SXig}9!kOl>)to8|D|3hUYuaG}sS$0ZnSwXn6d*BTy zNhX!8r1Xn0UCC63EYJn)c@$O@3Eo1c4M=g*v}SP-Zy8o1Y~pyPt9*?qGHqQ&YFTHU zb(5g}0m34BaiEsSnvX)&tDK(M=asNgq$2vc++CFyDvs;ZC}Hhw+rIJL2{(}zT%?eQDqpytUf&f4k*err?qLMkuyxyq~Yv# z`mJik@q@E{4%MtIWr%0~yEg=q!rA=>aXGR~n77M0^g0bM1qdG$2fU#ftYD<&!x7l4 zTSBMS)5zVv&&j&j)Skqst%&j>rE}pzL4_pca(rz9Vy0q*oElM~72F{8LF1&V{Li0{{R3 literal 0 HcmV?d00001 diff --git a/signatures/2.2.2-cagebreak-socket.7.sig b/signatures/2.2.2-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..e46522fc40240c6f9b09db2bf27cfdd64bf76e96 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dKm;s6Q>5J?I6 zOsG4!XX%O%0LhxdmqOQ#5c5z3wXCA2KZlfDm3vSS^*n!C3;8>HyfTMWaHJiNq>O-M z!_7U_dB&JENatoUVTW!`TY%q8Uy9QuqoQ8p5eC?%2NhHp))z-t55WX7Cr>E?I}sDZ zlY5I6_9_-Ev{PoIb(2T0QQA9? z3u67W|3Pd}fK>dfuQ4h8{-iQGo*$t{0u0{UFgf%A4!l9rH>ARW27GtA3hL>D`AdT~ zeNf~Q+eU>-5Pp}@Z3~eMNv}-71@`j&N+Kd&SAj6r3e%T7)zjJYF_z^K;Va5)%hs8n EGW&xDb^rhX literal 0 HcmV?d00001 diff --git a/signatures/2.2.2-cagebreak.1.sig b/signatures/2.2.2-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..36b2c99c6362034807b3beb0c00a4aa236f3e13e GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dKm;s6Q>5J?I6 zOsG4!XLSA$0H~8K$4S51D7#=L&$@HYeL^A-m#)@d(K;Fs##`LxdqzbB9uTZji zPb2qRTpo|xFBiRf@{*5~n_wlc^jwkJC8!)Uh9iQ>pCBxv6ph^agn)VAE>uBdeTNMl;?UQ-T-}k#R?8&lXydHg7WWoki+Z5NaB7b$ZB_{Z;ofML4cmLAlI#oFf!fG-m6bNqqo_ zl^FFH-epxgzFyXs!tXEo*?IS*Hgh&1Hi><4ys%p+`6EInLc%Wz*=!h!Q)fT0T5J?I6 zOsG4!X9fQd0J=kb54SFRiT$(tSOAYXE>H=2ikF(>)G421sRWpML`=yU9(L`jSXq;m zCDv57c`KO24HQJXhzxF<`#$z$DTV35Oq;`Jj=}=CS}bUEf-6@g1=BO?J&)|%??QnL z5mSq6SI5y?1|#=I-K+`evSYYr;K?%YG+aWFn8)w6$%FgEi4&SRj*c%Arwy5VhglDg z$0qogrcwv>nmg&ojpPahuTcR%)p2=D;L$qL;?LhumOO_8VmVjV7zJ4_&ROIFJbYMm z2nxv_y4xno_B!bwcYoyZOhZM|Y;7r}S zjeVi;AD74nY(a4w_GZ6K%ERqS;&h0pUp}CMb21sc@@Z~-r|$cL+Exhe5i+X!DVJfZPs|pz=eeSP;8IU{hLQyb${%P Ev8itpxBvhE literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index 811fe372025fbcaaa8f497ef6bc25d9d37641be9..6d7f6c16507165c9ac9b5646e45cb4cc3a89863b 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY$rm&HxGt5J?I6OsG4!XG8W6|9R#;J{FE-UT8#I!Fi4#zi*ov z9Xy@$5_IOwHC)DCP)s(==UVe6N7@7-A^-dEBpXnVsr`4u3uKdL`06E&J>;c^ zGLT`#D);5PsU0#YBhuT9^r&UtpG(X0;-JsYjD3_^N;Ir-Z4`a^&NZPoP-LJkDQJ$o ztQ%ax0n<}on}0qm-E=?OPj+n3|IHg!ysgT4hzK_?Sq&d!Kgo1rnqfYJm8tUa_@E0X zGwBQWd8UZnmlLz7;_pf@-9yZ31Xv5g2Dp2_lGah%M#l3=wKveJy6lK`1$QE)a>i+V9|LMnm=&&EfQ)cl5iM@4?FK45J?I6OsG4!XJMfb0E>`au^^z8E*v#Fd9jxSr%FdR zbeic+={rm$M))f-=$6&xrq{OVP9ncaEXyyAm(BmYFS|7U3ot(_kW!vCUam9YJK_m$ihUB zA>BZ!y1ta>;ON9WG7m-MeZ(QOj&e8RlNb`(a8O|Nw|c#XDt!^sZ|GN0lQLNK@?4X9 zB$|*qFa%mg=Vm`nwe+}gk0H4{rLhRe-BTiy3SQgtk#b{)mgdq13J+k5(29AB1ds*= zsI2x0VE;p9B!91vKVeyRN^Ds{xUzfT4Jb(_m93=oi!fcuREI3k1?+hgRul=|LZ%H! zanrPBaS(4ARw8WTc&4j-jVUs1T}5hHXPtGEp#A~EB6@M4mdKiqLe;CBp4sP>uu-HU z|NoqvdJctTM%Z-u+?<_%st?M*G9s33Z#qX)({*^$Vt=)}FGg%_U&ETW3*y2-a-{mc z;-ceGWf;P&K0N^rD9SXawP~c0GfdT_;p}$$t!l;bgR^}O)vPRKh-d!0Hw2Qx+5HA_ zIkHTcx63*7It?!c2p<#&yrCJaV5H^45!kC+LZ{Z#$lbor$-3Cop2VoFi1H$(bKyck gg(T&2d>3s3Vy0q*oElM~72F{8LF1&V{L2q+@7Wxi}6Hz zo4QkhM=B3~=^{TsW09d;k=38L|LYbj1!=3-gW5sDChrA{ofASO33n6-ALc z``%qt;VT?b7m1kQtJ1;6F#huuPxn_#&+lo-{`EPe&XpXzX=C8`hoUcR6|+`!a|PN> zciV6IEV}yy0L@;GyI|86s8Dz`uciE$nd4J_no9tZ8B}nzsNyn-471wYEU68SG;1S3J5OeK%SL1K#C$M@LKZpTVt;c1ylX$o=)VKke_W<%YFJE| znZp2ZU7>pX<<~}N74ZYNtoct%N@|a#bq@LI-V}Ede@>@3<6^wVZZbir4 gMmn>Z>=$cw@HwBgkA;5J?I6OsG4!XX%O%0LhxdmqOQ#5c5z3wXCA2KZlfD zm3vSS^*n!C3;8>HyfTMWaHJiNq>O-M!_7U_dB&JENatoUVTW!`TY%q8Uy9QuqoQ8p z5eC?%2NhHp))z-t55WX7Cr>E?I}sDZlY5I6_9_-Ev{PX_4ygoijy~WPloTWk4O8Le zo$n*-!=4*T3f_d&OEN>8;wOc-DIw81KR`hTDAX987+@nP@>g13%Zzp14!xId9T>$* ztMF%GcN#uBFVi+VGZnjHqt#yHUuF3+J=vb1tu8Z}p??pwH6`1y`2_fCr3kYS+{tWg zl8M(nRl^~jgC%wbmCEIyWz#rylSi*n+B=U6V*RxLL2OWfRQ#;3F)982q%u05AE8GA z4Bp!?IrISzyg}19q{4v)e0RDE>gj{|OM^CjP~;NZMukccewWd03y};-uS~%O_VWEo gA|hT_ffq2=3e%T7)zjJYF_z^K;Va5)%hs8nGCKSJw*UYD diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 36b2c99c6362034807b3beb0c00a4aa236f3e13e..14ac7ab7fd60b8337eaa18e060f7a24402925528 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY$rm%>W7s5J?I6OsG4!XL#rj{T+Al-oPBN+x!MHM~QdkHzBr| zCl+us_ro^WM3!tDhfsBw7Pq%1Z{ zRD62N4N=i9+{y)3(Ru$V?xv1!7mfQcC$)a&YY~(X8+6uKa(^@a*FaJm=k2d5e#8K? zBk6`gZwAL|l3suRPlWha7l0#wTP{f8V%IzhA|Hj?QK3mn&r+$yiSr?mJIkC)*B8*l z^?kvE-xrH4amP7nO~E_Tu1Dh%2Xwp3baa*}C6f&Akz5Rxnu1dnOJ4}*c_2nu#Urv8 z0_Wt1JoS%$CVv2)?ob#t9F1I9CwmObFHhlK0B=@Gy2fFG=nutuJn!u0rEjd%hRr0L zDV&tKE^s7L=meU@45+$n^2=q2Z zKGSc-f6OXa(-RiFI5$3$B4FvEw0qnbznO;dx_atDeSg03=IHb!5N(c}OK?nzC0we5 ze-Mb7on$b#S2mp2$R?^F3`0olF1~xBqx2rE_C%c_i$VvgIG;0l7$1L9gu*LB)Yn5= zgL)0@BBh-*cY6YeN2O~J+*Fv<3Q0v*FLa<8B3v8CS{4i{UeNFo0`+wHghwX}jEorq g{nwU}ofqGe=tDjJ_J`^&YaK-^$7k{&2ct;QrwVKVasU7T delta 542 zcmV+(0^$9(1hxc_BY$nM;s6Q>5J?I6OsG4!XLSA$0H~8K$4S51D7#=L&$@HYeL^A- zm#)@d(K;Fs##`LxdqzbB9uTZjiPb2qRTpo|xFBiRf@{*5~n_wlc^jwkJC8!)U zh9iQ>pCBxv6ph^QxYG8gg}d z$d>(8_cKK}u3163%y*n46jd~4>z+w{0Em?s^%&k|RXe_3)|bNXFZ$Ve_oOy+HX$~N zeQ~_7TPXP>LMKAPFA3Rf7>ZM8Kd@Zx1!K1T8=51AF&=8-?(k8|=EJiVF?YLGRHU}Mc3##Z*-{!b*WBZ}?8(nZozCMtk6kL)X*~bp gq}hT_G#3N4Gj~13RXcEo3$FSz)?Jh1$@?FoWvD9$QUCw| diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index ca4ae146f6b80b7f5a7a9a0bf899cdcdbf702f21..b06130553f46759a6b0c15d2ec5e4a7f3fe3714d 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY$rm%>W7s5J?I6OsG4!XRMG9{S^4?G%^Y3m5el0Q_7oaILK}l zji>EKqg2qNLmPHp`AzALIN3h@;a~B)ymaY@9KZ9Z?6L?yxsZ1pU=68cL;~wowNV!k z(}NRXx`~nO6O%vds-sG3-$iS`TqsdTy69<hg$9cnnvIX5buFPT?}bec==AAn%a)WHBcL;2;Q62OBxqO(ho2hv)@zL66N; zf(fQUFNaz;Kj!_GB!V1(u^jHTIy*BgL2T918hT0bUVf*l#8WDb5s0L1(=6n|n&9EXz2OXhW(;d5tfbi<^( z!ohzPb!2@G7VUn&`)d4m4?A&lzlu`&pJa~C+7%PdLU&*W1~(ns z?No(pk1)m;|NP?m;@)x*!ANT243?wj$lPbRVIgrP!IDVo?z54G1ivR!s delta 542 zcmV+(0^$9(1hxc_BY$nM;s6Q>5J?I6OsG4!X9fQd0J=kb54SFRiT$(tSOAYXE>H=2 zikF(>)G421sRWpML`=yU9(L`jSXq;mCDv57c`KO24HQJXhzxF<`#$z$DTV35Oq;`J zj=}=CS}bUEf-6@g1=BO?J&)|%??QnL5mSq6SI5y?1|#=I-G8hJ>9S+EX5h&(?=)OO zk(kHtwaJ6~#EBD{IgXAm6Q>QCdxu#MkH;qXn5I$(^_n~B$BpC)1g}v6Kh<%0OyJQv z(&EqGP?kK017bN>)))m@F3wrx0z7HslK<06f z@e!GPBfM=8kAKn3Jjm&D7;g9fyIQZiZ!&8QJEK2nj@R(m8&@O9@Pm&&>h~r^VaV-Y zg0hTfc?au>I7}ph*rscw(%**^%w*t9-Mfu_q3|D<$OmjeaVleVSGJ5D&~xs03s^pv zAK)z+wviJkox~3qQd0Lmp-2mk;8 From d19c32d7a4ce9e884dc0b82c698f6abfeddfc18e Mon Sep 17 00:00:00 2001 From: project-repo Date: Fri, 26 Jan 2024 10:53:03 +0000 Subject: [PATCH 18/19] Release 2.3.0 Functionality: * Add configuration to anchor position of messages (#60, 71 in Bugs.md). * Add output priorisation (#38, 68 in Bugs.md). * Print whether output is active in dump. Bug Fixes: * Fix gamma control (72 in Bugs.md). * Add missing commands to example config. * Add message_config to dump output. Example Scripts: * Add screenshot script. * Make example scripts standalone. Documentation: * Escape html tags in config man page. (#68, 69 in Bugs.md) * Improve README.md (#62, 70 in Bugs.md). * Improve SECURITY.md. * Add CONTRIBUTING.md (#62, 70 in Bugs.md). * FAQ: Add Firefox screenshare instructions for wayland. * FAQ: Add wlroots downgrading instructions for workaround in case of temporary wlroots incompatibility. * Update copyright notices to 2024. Development Tooling: * Add new gpg keys (signed by the old ones). * Add PR template. * Add dev-FAQ. * Remove now-unnecessary fanalyzer pragmas. --- Bugs.md | 52 ++ CONTRIBUTING.md | 464 ++++++++++++ Changelog.md | 184 +++-- FAQ.md | 37 +- Hashes.md | 20 + LICENSE | 2 +- README.md | 690 +++--------------- SECURITY.md | 69 +- cagebreak.c | 23 +- docs/dev-FAQ.md | 67 ++ docs/pull_request_template.md | 26 + example_scripts/screenshot_script | 44 ++ ...orkspace_views.sh => show_workspace_views} | 20 +- examples/config | 58 +- fuzz/execl_override.c | 2 +- fuzz/fuzz-lib.c | 4 +- fuzz/fuzz-lib.h | 2 +- fuzz/fuzz-parse.c | 2 +- idle_inhibit_v1.c | 9 +- idle_inhibit_v1.h | 2 +- img/archwiki.svg | 1 + img/aur.svg | 1 + img/contributing.svg | 1 + img/faq.svg | 1 + img/mail.svg | 1 + img/manuals.svg | 1 + img/web-artefacts.svg | 1 + img/web-open-issue.svg | 1 + input.h | 2 +- input_manager.c | 2 +- input_manager.h | 2 +- ipc_server.c | 2 +- ipc_server.h | 2 +- keybinding.c | 150 ++-- keybinding.h | 2 +- keys/cagebreak@project-repo.co.pub | 157 ++-- keys/cagebreak@project-repo.co.pub-legacy-4 | 87 +++ ...gebreak_signing_key_13@project-repo.co.pub | 76 ++ ...gebreak_signing_key_14@project-repo.co.pub | 76 ++ libinput.c | 4 +- man/cagebreak-config.5.md | 154 ++-- man/cagebreak-socket.7.md | 176 ++++- man/cagebreak.1.md | 10 +- manuals.md | 5 + meson.build | 24 +- meson_options.txt | 4 +- message.c | 105 ++- message.h | 10 +- output.c | 333 ++++++--- output.h | 21 +- pango.c | 2 +- pango.h | 2 +- parse.c | 41 +- parse.h | 2 +- release-non-auto-checks/Bugs.md | 4 +- release-non-auto-checks/FAQ.md | 4 +- release-non-auto-checks/SECURITY.md | 4 +- release-non-auto-checks/WLR_XDG_VERSION | 4 +- .../acknowledge-contributors | 4 +- release-non-auto-checks/archwiki | 2 + release-non-auto-checks/changelog-major-minor | 4 +- release-non-auto-checks/internal-wiki | 4 +- release-non-auto-checks/release-note | 4 +- .../reproducibility-checked | 4 +- .../security-to-man-page-info-transfer | 4 +- release-non-auto-checks/version-restrictions | 4 +- scripts/adjust-epoch | 2 +- scripts/create-release-artefacts | 2 +- scripts/create-signatures | 2 +- scripts/fuzz | 2 +- scripts/git-tag | 2 +- scripts/install-development-environment | 2 +- scripts/output-hashes | 2 +- scripts/set-version | 4 +- seat.c | 75 +- seat.h | 2 +- server.c | 5 +- server.h | 5 +- signatures/2.2.3-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.2.3-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.2.3-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.2.3-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes test/arguments | 2 +- test/build-w-o-warnings | 2 +- test/build-w-o-xwayland | 2 +- test/check-artefacts | 2 +- test/clang-format | 2 +- test/copyright-license | 4 +- test/environment-variables | 2 +- test/git-tag | 2 +- test/gpg-signatures | 2 +- test/gpg-validity | 24 +- test/hashes-md | 2 +- test/illegal-strings | 14 +- test/man-pages | 37 + test/non-auto-tests | 2 +- test/scan-build | 2 +- test/script-executability | 19 + test/script-header | 17 + test/shellcheck | 2 +- test/testing-configurations/-c-config | 2 +- .../cb_script_header.sh | 4 +- test/testing-configurations/config | 2 +- test/testing-configurations/env-var-config | 2 +- test/testing-configurations/my-scan-build | 2 +- test/versions | 2 +- util.c | 2 +- util.h | 2 +- view.c | 26 +- view.h | 2 +- workspace.c | 31 +- workspace.h | 3 +- xdg_shell.c | 24 +- xdg_shell.h | 2 +- xwayland.c | 24 +- xwayland.h | 2 +- 120 files changed, 2310 insertions(+), 1348 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 docs/dev-FAQ.md create mode 100644 docs/pull_request_template.md create mode 100755 example_scripts/screenshot_script rename example_scripts/{show_workspace_views.sh => show_workspace_views} (54%) mode change 100644 => 100755 create mode 100644 img/archwiki.svg create mode 100644 img/aur.svg create mode 100644 img/contributing.svg create mode 100644 img/faq.svg create mode 100644 img/mail.svg create mode 100644 img/manuals.svg create mode 100644 img/web-artefacts.svg create mode 100644 img/web-open-issue.svg create mode 100644 keys/cagebreak@project-repo.co.pub-legacy-4 create mode 100644 keys/cagebreak_signing_key_13@project-repo.co.pub create mode 100644 keys/cagebreak_signing_key_14@project-repo.co.pub create mode 100644 manuals.md create mode 100644 release-non-auto-checks/archwiki mode change 100644 => 100755 scripts/install-development-environment create mode 100644 signatures/2.2.3-cagebreak-config.5.sig create mode 100644 signatures/2.2.3-cagebreak-socket.7.sig create mode 100644 signatures/2.2.3-cagebreak.1.sig create mode 100644 signatures/2.2.3-cagebreak.sig create mode 100644 test/man-pages create mode 100644 test/script-executability create mode 100644 test/script-header rename {example_scripts => test/testing-configurations}/cb_script_header.sh (89%) diff --git a/Bugs.md b/Bugs.md index be04464..4ecef6c 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1252,3 +1252,55 @@ To stop this from reoccurring, we have added a check to our release checks. In Cagebreak 2.2.2 dual monitors were mirrored instead of extended, changing established behaviour. +## Issue 68 + + * github issue numner: #38 + * Fixed: 2.3.0 + +After extensive discussion of how to deal with turning off outputs, the +output command was ammended by two settings (permanent & peripheral). +See man pages for details. + +Thanks to sodface for the great cooperation. + +## Issue 69 + + * github issue numner: #68 + * Fixed: 2.3.0 + +The config man page (5) was badly formatted up to version 2.3.0. + +Particularly unescaped html tags caused not all information to be +shown in the web browser view of our repo. + +## Issue 70 + + * github issue numner: #62 + * Fixed: 2.3.0 + +The README contained a few non-intuitive phrases up to version 2.3.0. + +To alleviate this, the following changes were made: + +- Rephrase README.md (for more clarity) +- Add CONTRIBUTING.md (to remove dev detail from README) +- Add PR template (to present relevant info during a PR) + +## Issue 71 + + * github issue numner: #60 + * Fixed: 2.3.0 + +Cagebreak up to 2.3.0 did not have configuration for the message location. + +This has been added through the initiative of unsigned-enby to improve +accessibility. + +## Issue 72 + + * github issue numner: N/A + * Fixed: 2.3.0 + +A Cagebreak version before 2.3.0 broke the gamma toolkit used to tune the +monitor colors. + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4da2ae2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,464 @@ +# Contributing + + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your feature request. + We will get back to you. + * Read this document, [README.md](README.md) and [docs/dev-FAQ.md](docs/dev-FAQ.md). + * Ask before opening a pull request. We might not accept your + code and it would be sad to waste the effort. + * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never + had to intervene - Please keep it that way!) + +## Good First Contributions + + * Reviews are always welcome. + * Read the code. + * Read the documentation. + * Test whether the documentation matches the code. + * Test Cagebreak in more esoteric setups (many monitors, for instance). + * Compile the code. + * Ideas on improving the testing and quality assurance are particularly + welcome. + * You can share your cagebreak scripts and we might include them with Cagebreak + provided you agree to release them under MIT and we agree with the + use case and coding style. + * If you are happy with Cagebreak under Arch Linux, you may vote for + [Cagebreak in the AUR](https://aur.archlinux.org/packages/cagebreak). + * The points from the Contributing section above still apply. + +## Philosophy + +Cagebreak is currently developed to fit the needs of its creators. + +The feature set is intentionally limited - we removed +support for a desktop background image for example. + +Nonetheless, don't be intimidated by any other part of this file. +Do your best and we will collaborate toward a solution. + +# Development + +## Compatibility & Development Distribution + +Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the libraries +versions as they are obtained from extra and core +at the time of release. + +However, Cagebreak may also work on other distributions given the +proper library versions (Some package maintainers have done this and it +seems to work (To date, we dealt with a few Issues and never felt the +need to ask for the distribution the user was having the issue on.)). + +[![Packaging status](https://repology.org/badge/vertical-allrepos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) + +You should use Arch Linux if you want to modify Cagebreak +for yourself. + +## Review Requirements + +Project-repo will review your proposal before your implementation for feasibility +and desirability. After your pull request, the code will be reviewed in conjunction +with all other changes before the release as per the release procedure. + +All reviews performed by project-repo are verified by at least two people internally. + +## Developer Certificate of Origin (DCO) + +On any pull requests please include a + +``` +signed-off-by: YOUR IDENTIFIER OR NAME +``` + +DCO statement. + +By doing this you claim that you are legally allowed to contribute the +code and agree to let project-repo publish it under the MIT License. + +### Development Environment + +CAVEAT: This script works exclusively on Arch Linux, which, as outlined above, +is the development distribution of Cagebreak. + +Cloning the Cagebreak repository and building it is sufficient as a starting point. + +All other dependencies can be installed by invoking + +``` +meson compile devel-install -C build +``` + +if meson is already available or + +``` +./scripts/install-development-environment +``` + +otherwise. + +### Scripts + +Cagebreak provides a few convenience tools to facilitate development. + +#### Fuzzing + +If your fuzzing corpus is located in the directory `fuzz_corpus` you can +just call: + +``` +meson compile fuzz -C build +``` + +If you want to use a different directory, configure cagebreak with +`-Dcorpus=OTHERDIRECTORY` or call `./scripts/fuzz OTHERDIRECTORY`. + +#### Adjusting Epoch + +To facilitate the creation of reproducible man pages an arbitrary release +time has to be set in `meson.build`: + +``` +meson compile adjust-epoch -C build +``` + +or + +``` +./scripts/adjust-epoch +``` + +#### Git tag + +If you are on the master branch, everything is ready and you want to create +a release tag you can call: + +``` +meson compile git-tag -C build +``` + +If you want to use another signing key than the prespecified one, configure +Cagebreak with `-Dgpg_id=GPGID`. + +``` +./scripts/git-tag GPGID CBVERSION +``` + +can be used alternatively. + +#### Output Hashes + +Hashes of release versions of all binaries can be output to `local-hashes.txt` +via: + +``` +meson compile output-hashes -C build +``` + +Or + +``` +./scripts/output-hashes VERSION +``` + +if meson is unavailable. + +#### Create Signatures + +Creation of signatures for releases can be achieved through: + +``` +meson compile create-sigs -C build +``` + +Configure Cagebreak with `-Dgpg_id=GPGID` for a different gpg signing +key. + +Without meson use: + +``` +./scripts/create-signatures GPGID +``` + +#### Set Version Number + +Once the version number is set within meson.build, you can use + +``` +meson compile set-ver -C build +``` + +to set the version number in the man pages and README repology minversion. + +Use of the script without meson is discouraged because meson.build is +not touched by the script. + +#### Create Release Artefacts + +The following command generates the release artefacts which must be created +once a release is completely ready to be published (the commit is tagged with +the version of the master branch, etc.): + +``` +meson compile create-artefacts -C build +``` + +Use of the script version is discouraged. + +## GCC and -fanalyzer + +Cagebreak should compile with any reasonably new gcc or clang. Consider +a gcc version of at least [10.1](https://gcc.gnu.org/gcc-10/changes.html) if +you want to get the benefit of the +[-fanalyzer](https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html) +flag. However, this new flag sometimes produces false-postives and we +selectively disable warnings for affected code segments as described below. + +Meson is configured to set `CG_HAS_FANALYZE` if `-fanalyzer` is available. +Therefore, to maintain portability, false-positive fanalyzer warnings are to be +disabled using the following syntax: + +``` +#if CG_HAS_FANALYZE +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "WARNING OPTION" +#endif +``` +and after + +``` +#if CG_HAS_FANALYZE +#pragma GCC diagnostic pop +#endif +``` + +## Test Suite + +``` +meson test -C build +``` + +invokes all tests. This is required for a release to occur. + +There are four test suites: + + * basic: tests actual outward-facing functionality + * Note optional dependencies for efficient socket interaction + * nc (openbsd-netcat) + * jq + * devel: tests internal properties of the repository + * Note potentially heavier dependencies such as + * shellcheck + * clang-format + * devel-long: applies more costly testing + * Note potentially heavier dependencies such as + * scan-build (static analysis (including security-relevant issues)) + * release: tests release specific considerations + * Note that this is only expected to pass just before + a release. This checks mostly administrative things + to check that a release is ready. + * Note that non-auto tests are files in `release-non-auto-checks` + and have to contain the release version and current date in + YYYY-mm-dd format on seperate lines. This is our imperfect attempt + to guarantee some hard-to-automate checks are carried out before + a release is undertaken. + +Every commit should pass at least the basic and devel suites. + +It is expected that cagebreak passes at least the +basic, devel and devel-long suites when commits are pushed: + +``` +meson test -C build --suite basic --suite devel +``` + +The basic suite can be used to test a binary. This is +useful for PKGBUILDs and their equivalents in other +systems. + +``` +meson test -C build --suite basic +``` + +## Fuzzing + +Along with the project source code, a fuzzing framework based on `libfuzzer` is +supplied. This allows for the testing of the parsing code responsible for reading +the `cagebreak` configuration file. When `libfuzzer` is available (please +use the `clang` compiler to enable it), building the fuzz-testing software can +be enabled by passing `-Dfuzz=true` to meson. This generates a `build/fuzz/fuzz-parse` +binary according to the `libfuzzer` specifications. Further documentation on +how to run this binary can be found [here](https://llvm.org/docs/LibFuzzer.html). + +Here is an example workflow: + +``` +rm -rf build +CC=clang meson setup build -Dfuzz=true -Db_sanitize=address,undefined -Db_lundef=false +ninja -C build/ +mkdir build/fuzz_corpus +cp examples/config build/fuzz_corpus/ +WLR_BACKENDS=headless ./build/fuzz-parse -jobs=12 -max_len=50000 -close_fd_mask=3 build/fuzz_corpus/ +``` + +You may want to tweak `-jobs` or add other options depending on your own setup. +We have found code path discovery to increase rapidly when the fuzzer is supplied +with an initial config file. We are working on improving our fuzzing coverage to +find bugs in other areas of the code. + +### Caveat + +Currently, there are memory leaks which do not seem to stem from our code but rather +the code of wlroots or some other library we depend on. We are working on the problem. +In the meantime, add `-Db_detect-leaks=0` to the meson command to exclude memory leaks. + +## Reproducible Builds + +Cagebreak offers reproducible builds given the exact library versions specified +in `meson.build`. Should a version mismatch occur, a warning will be emitted. We have +decided on this compromise to allow flexibility and security. In general we will +adapt the versions to the packages available under Arch Linux at the time of +release. + +There are reproducibility issues up to and including release `1.2.0`. See +`Issue 5` in [Bugs.md](Bugs.md). + +### Reproducible Build Instructions + +All hashes and signatures are provided for the following build instructions. + +``` +meson setup build -Dxwayland=true -Dman-pages=true --buildtype=release +ninja -C build +``` + +### Hashes for Builds + +For every release after 1.0.5, hashes will be provided. + +For every release after 1.7.0, hashes will be provided for man pages too. + +See [Hashes.md](Hashes.md) + +### GPG Signatures + +For every release after 1.0.5, a GPG signature will be provided in `signatures`. + +The current signature is called `cagebreak.sig`, whereas all older signatures +will be named after their release version. + +Due to errors in the release process, the releases 1.7.1 and 1.7.2 did not include the release +signatures in the appropriate folder of the git repository. However, signatures were provided +as release-artefacts at the time of release. The signatures were introduced into the +repository with 1.7.3. The integrity of cagebreak is still the same because the signatures were +provided as release-artefacts (which were themselves signed) and the hashes in Hashes.md +are part of a signed release tag. + +### Signing Keys + +All releases are signed by at least one of the following collection of +keys. + + * E79F6D9E113529F4B1FFE4D5C4F974D70CEC2C5B (expired) + * 4739D329C9187A1C2795C20A02ABFDEC3A40545F (expired) + * 7535AB89220A5C15A728B75F74104CC7DCA5D7A8 (expired) + * 827BC2320D535AEAD0540E6E2E66F65D99761A6F (expired) + * A88D7431E5BAAD0B6EAE550AC8D61D8BD4FA3C46 (expired) + * 8F872885968EB8C589A32E9539ACC012896D450F (expired) + * 896B92AF738C974E0065BF42F2576BD366156BB9 (expired) + * AA927AFD50AF7C6810E69FE8274F2C605359E31B (expired) + * BE2DED372287BC4EB2213E13A0C743848A638955 (expired) + * 0F3476E4B2404F95EC41600683D5810F7911B020 (expired) + * [4E82C72C6B3E58A7BC4FF8554909F84CA83BB867](keys/cagebreak_signing_key_11@project-repo.co.pub) + * [5AEB1A2EB0D13F67E306AC59DC0CC81BE006FD85](keys/cagebreak_signing_key_12@project-repo.co.pub) + * [438C27DDB5D174673DF4D67B451205B3528C7C63](keys/cagebreak_signing_key_13@project-repo.co.pub) + * [81372DDB8124349F0303B77448D7E2EE3343E3AA](keys/cagebreak_signing_key_14@project-repo.co.pub) + +Should we at any point retire a key, we will only replace it with keys signed +by at least one of the above collection. + +We registered project-repo.co and added mail addresses after release `1.3.0`. + +We now have a mail address and its key is signed by signing keys. See [SECURITY.md](SECURITY.md) +for details. + +The full public keys can be found in `keys/` along with any revocation certificates. + +## Versioning & Branching Strategy + +Cagebreak uses [semantic versioning](https://semver.org). + +There are three permanent branches in cagebreak: + + * `master` (for releases) + * `development` (for polishing code between releases) + * `hotfix` (for small emergent releases, usually up-to-date with master) + +Releases are merged to master as per the release procedure, with +reasonable exceptions as the situation requires. + +The release commit is tagged with the release version. + +In the past, our git history did not perfectly reflect this scheme. + +## Release Procedure + +The release procedure outlines the process for a release to occur. + + * [ ] `git checkout development` + * [ ] `git pull origin development` + * [ ] `git push origin development` + * [ ] Arch Build System is up to date + * [ ] `meson test -C build/` just to get an overview + * [ ] Update internal wiki + * [ ] Adjust version number in meson.build + * [ ] `meson compile set-ver -C build` + * [ ] Add new files to meson.build or hardcoded testing variable + * [ ] Commit changes + * [ ] `git push origin development` + * [ ] Complete relevant documentation + * [ ] New features + * [ ] tests added and old test scripts adjusted + * [ ] man pages + * [ ] cagebreak + * [ ] cagebreak-config + * [ ] cagebreak-socket + * [ ] example config + * [ ] FAQ.md + * [ ] Changelog.md for major and minor releases but not patches + * [ ] Check changes for SECURITY.md relevance (changes to socket scope for example) + * [ ] Synchronize any socket changes to cagebreak-socket man page + * [ ] Document fixed bugs in Bugs.md + * [ ] Include issue discussion from github, where applicable + * [ ] `meson compile adjust-epoch -C build` + * [ ] Commit changes + * [ ] `git push origin development` + * [ ] Testing + * [ ] Manual testing + * [ ] `meson compile fuzz -C build` for at least one hour + * [ ] Adjust Hashes.md - Use `meson compile output-hashes -C build` to add Hashes or aid in repro check + * [ ] Commit changes + * [ ] `git push origin development` + * [ ] Complete release-non-auto-checks + * [ ] `meson compile create-sigs -C build` + * [ ] Commit and push signatures, hashes and non-auto-check files + * [ ] `meson test -C build` passes everything except some release tests + * [ ] `git add` relevant files + * [ ] `git commit` + * [ ] `git push origin development` + * [ ] `git checkout master` + * [ ] `git pull --tags origin master` + * [ ] `git merge --squash development` + * [ ] `git commit` and insert message + * [ ] `meson compile git-tag -C build` + * [ ] `meson compile create-artefacts -C build` + * [ ] `meson test -C build` THIS MUST PASS WITHOUT ANY FAILURES WHATSOEVER + * [ ] `git push --tags origin master` + * [ ] `git checkout development` (merge to development depends on whether release was a hotfix) + * [ ] `git merge master` + * [ ] `git push --tags origin development` + * [ ] `git checkout hotfix` (hotfix is to be kept current with master after releases) + * [ ] `git merge master` + * [ ] `git push --tags origin hotfix` + * [ ] Upload archives and signatures as release assets + * [ ] Delete feature branches if appropriate + * [ ] Manage package release + diff --git a/Changelog.md b/Changelog.md index b9f7461..a3223e5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,40 +1,100 @@ # Changelog -## Release 1.0.0 +## Release 2.3.0 -Adds basic tiling window manager functionality to cage. +Functionality: + * Add configuration to anchor position of messages (#60, 71 in Bugs.md). + * Add output priorisation (#38, 68 in Bugs.md). + * Print whether output is active in dump. -## Release 1.1.0 +Bug Fixes: + * Fix gamma control (72 in Bugs.md). + * Add missing commands to example config. + * Add message_config to dump output. -Unifies commands and actions. See Issue 4 in Bugs.md. +Example Scripts: + * Add screenshot script. + * Make example scripts standalone. -## Release 1.2.0 +Documentation: + * Escape html tags in config man page. (#68, 69 in Bugs.md) + * Improve README.md (#62, 70 in Bugs.md). + * Improve SECURITY.md. + * Add CONTRIBUTING.md (#62, 70 in Bugs.md). + * FAQ: Add Firefox screenshare instructions for wayland. + * FAQ: Add wlroots downgrading instructions for workaround in case of temporary wlroots incompatibility. + * Update copyright notices to 2024. -Adds output configuration as described in the man pages. +Development Tooling: + * Add new gpg keys (signed by the old ones). + * Add PR template. + * Add dev-FAQ. + * Remove now-unnecessary fanalyzer pragmas. -## Release 1.3.0 +## Release 2.2.0 -Adds IPC as described in the man pages. + * Add custom events + * Fix Issue 62 (#46 Github) + * Fix Issue 63 (environment variables test) + * Fix Issue 64 (pointer focus bug) -## Release 1.4.0 +## Release 2.1.0 -Adds close command for windows as described in the man pages. + * Add -bs (bad security) option + * Fix Issue 57 (SPDX spelling error #39) + * Fix Issue 59 (meson install settings) + * Fix Issue 55 (npd) + * Fix Issue 56 (npd) + * Fix Issue 58 (#40 config) + * Improve release procedure + * Add miniscule test suite + * Adjust Cagebreak to wlroots 0.16.2 + * New GPG Keys -## Release 1.5.0 +## Release 2.0.0 -Adds options to disable or enable outputs. See Issue 22 in Bugs.md and Issue #2 on github. +This is a major release and includes BREAKING changes! -## Release 1.6.0 +Breaking Changes: -Adds support for non-build dependencies and an option for builds without pandoc. + * More intuitive switch of focus, next, prev and exchange (#20, 40 in Bugs.md) + Cagebreak will probably still feel broadly the same though. + * Remove -r flag - This is replaced by output configuration. + * Socket disabled by default - The socket is enabled by invoking Cagebreak with the -e flag. + * Socket permissions restricted to the user of the Cagebreak process (700) + This may require modification of scripts interacting with the socket with + different UIDs than the UID of the Cagebreak process. + * Rename "Current frame" indicator to "Current tile" -## Release 1.7.0 +Changelog: -Improves window ordering. - -## Release 1.8.0 - -Adds libinput configuration and virtual keyboard and pointer support. + * Move to wlr_scene + * Add events displaying change over the socket + * this enables scripting tools + * Add support for scaling outputs (thanks to Oliver Friedmann) + * Remove -r flag + * Add rotation to output configuration + * Add cursor enable|disable flag + * Add input keyboard configuration + * Custom path flag for configuration file + * Restrict socket permissions to the user running cagebreak (700) + * Fix Issue #31 (resolve some terminology) 38 in Bugs.md + * Fix Issue #30 - 39 in Bugs.md + * Fix Issue #20 - 40 in Bugs.md + * Fix Issue #12 - 41 in Bugs.md (dump + events over socket) + * Fix Bugs found via scan-build static analysis (42 - 45 in Bugs.md) + * Fix Issue #33 - 46 in Bugs.md + * Fix Issue #32 - 47 in Bugs.md + * Fix Issue #16 - 48 in Bugs.md + * Fix Issue #3 - 49 in Bugs.md (disabling keybinding interpretation for specific keyboards is now possible) + * Fix Issue #26 - 50 in Bugs.md + * Fix Issue #7 - 51 in Bugs.md (Change cursor to square while Cagebreak is waiting for a key) + * Fix config bug for some commands - 52 in Bugs.md + * Fix Issue #35 - 53 in Bugs.md (update to wlroots 0.16.1) + * Improve FAQ.md (related to some Issues) + * Disable outputs when unable to set any mode (crashed previously) + * Add Code of Conduct + * Print version number on startup ## Release 1.9.0 @@ -64,65 +124,39 @@ Adds libinput configuration and virtual keyboard and pointer support. - Add new cagebreak email contact gpg key - Add new project-repo AUR gpg key (relevant for cagebreak-pkgbuild) -## Release 2.0.0 +## Release 1.8.0 -This is a major release and includes BREAKING changes! +Adds libinput configuration and virtual keyboard and pointer support. -Breaking Changes: - * More intuitive switch of focus, next, prev and exchange (#20, 40 in Bugs.md) - Cagebreak will probably still feel broadly the same though. - * Remove -r flag - This is replaced by output configuration. - * Socket disabled by default - The socket is enabled by invoking Cagebreak with the -e flag. - * Socket permissions restricted to the user of the Cagebreak process (700) - This may require modification of scripts interacting with the socket with - different UIDs than the UID of the Cagebreak process. - * Rename "Current frame" indicator to "Current tile" +## Release 1.7.0 -Changelog: - * Move to wlr_scene - * Add events displaying change over the socket - * this enables scripting tools - * Add support for scaling outputs (thanks to Oliver Friedmann) - * Remove -r flag - * Add rotation to output configuration - * Add cursor enable|disable flag - * Add input keyboard configuration - * Custom path flag for configuration file - * Restrict socket permissions to the user running cagebreak (700) - * Fix Issue #31 (resolve some terminology) 38 in Bugs.md - * Fix Issue #30 - 39 in Bugs.md - * Fix Issue #20 - 40 in Bugs.md - * Fix Issue #12 - 41 in Bugs.md (dump + events over socket) - * Fix Bugs found via scan-build static analysis (42 - 45 in Bugs.md) - * Fix Issue #33 - 46 in Bugs.md - * Fix Issue #32 - 47 in Bugs.md - * Fix Issue #16 - 48 in Bugs.md - * Fix Issue #3 - 49 in Bugs.md (disabling keybinding interpretation for specific keyboards is now possible) - * Fix Issue #26 - 50 in Bugs.md - * Fix Issue #7 - 51 in Bugs.md (Change cursor to square while Cagebreak is waiting for a key) - * Fix config bug for some commands - 52 in Bugs.md - * Fix Issue #35 - 53 in Bugs.md (update to wlroots 0.16.1) - * Improve FAQ.md (related to some Issues) - * Disable outputs when unable to set any mode (crashed previously) - * Add Code of Conduct - * Print version number on startup +Improves window ordering. -## Release 2.1.0 +## Release 1.6.0 - * Add -bs (bad security) option - * Fix Issue 57 (SPDX spelling error #39) - * Fix Issue 59 (meson install settings) - * Fix Issue 55 (npd) - * Fix Issue 56 (npd) - * Fix Issue 58 (#40 config) - * Improve release procedure - * Add miniscule test suite - * Adjust Cagebreak to wlroots 0.16.2 - * New GPG Keys +Adds support for non-build dependencies and an option for builds without pandoc. -## Release 2.2.0 +## Release 1.5.0 + +Adds options to disable or enable outputs. See Issue 22 in Bugs.md and Issue #2 on github. + +## Release 1.4.0 + +Adds close command for windows as described in the man pages. + +## Release 1.3.0 + +Adds IPC as described in the man pages. + +## Release 1.2.0 + +Adds output configuration as described in the man pages. + +## Release 1.1.0 + +Unifies commands and actions. See Issue 4 in Bugs.md. + +## Release 1.0.0 + +Adds basic tiling window manager functionality to cage. - * Add custom events - * Fix Issue 62 (#46 Github) - * Fix Issue 63 (environment variables test) - * Fix Issue 64 (pointer focus bug) diff --git a/FAQ.md b/FAQ.md index d8918a0..83fd29b 100644 --- a/FAQ.md +++ b/FAQ.md @@ -2,14 +2,9 @@ ## How do I do a particular thing with cagebreak? - * Check the man pages - * [cagebreak config](man/cagebreak-config.5.md) (probably where you find the answer) - * [cagebreak](man/cagebreak.1.md) (command line options etc.) - * [cagebreak-socket](man/cagebreak-socket.7.md) (socket information, mostly useful for scritping) - * Check the rest of this FAQ - * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) or otherwise get in touch with the development team (See section Email Contact in [SECURITY.md](SECURITY.md)). - -Note that the feature set of cagebreak is intentionally limited. + * Check the [man pages](manuals.md). + * Check the rest of this file. + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) or get in touch (See section Email Contact in [SECURITY.md](SECURITY.md)). ## How do I remap Caps Lock? @@ -17,6 +12,21 @@ Remapping Caps Lock globally seems to be the best option. Follow instructions [here](https://wiki.archlinux.org/title/Linux_console/Keyboard_configuration) to achieve this (should be roughly distribution-agnostic). +## What do I do if Cagebreak does not work with the current wlroots version? + +You can probably downgrade wlroots with + +``` +$ pacman -U /var/cache/pacman/pkg/old-version +``` + +If you have cleared your package cache, see instructions in the [ArchWiki](https://wiki.archlinux.org/title/downgrading_packages#Return_to_an_earlier_package_version). + +Cagebreak should start working again after the downgrade. + +After a new release, the downgrading will no longer be necessary (in fact, +downgrading will probably break your setup). + ## How do I get firefox to run under wayland? Set the following environment variables @@ -26,6 +36,17 @@ Set the following environment variables to activate wayland support for firefox. +## How do I get firefox to screenshare properly? + +Execute the following commands with the appropriate env vars: + +``` +export XDG_SESSION_TYPE=wayland +export XDG_CURRENT_DESKTIP=sway +/usr/lib/xdg-desktop-portal -r +/usr/lib/xdg-desktop-portal-wlr +``` + ## How do I map characters which are not on the Keyboard? Suppose you want to use a command like `bind` for a character diff --git a/Hashes.md b/Hashes.md index 867692b..2930148 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.3.0 cagebreak + + * sha 256: 549e82f6bb1af87c9272fb92d39c6f235b0f780885b066c32db5a5c7588da378 + * sha 512: d05e5ac9e4295bed93b8872a815b1f8aaf8ddc2448c01f84d5d29b4d5610bb5c0c50f87b15653bb663a9f772a899dc7b8215042db3ac86aa1ba3000ccb9757d2 + +2.3.0 cagebreak.1 + + * sha 256: 11cbe6ea82fa19064ee5b9d8346dbaa8ca8251948c5f5eee7387516edcfbeab0 + * sha 512: 76f15788aeebb2cab5a0a477f1427646964c6011c20d64f43f6c445bf08e5371971607a7565017fd05f4f2d75c66da5d79948643618eeb4d3619bc7e6128cffe + +2.3.0 cagebreak-config.5 + + * sha 256: dc8755bbed108cd0cf76f05eee0c6d08550373eab5f75895755abddb7b86e84c + * sha 512: b93caa7cd4ec9085409472982ce72a8e55a369cb830a7d3132801b24db0660e4259a3e9b229dbaf960bc28c4d8a384a19f7bbb11e74f7c4e3f90b04d2b5280ee + +2.3.0 cagebreak-socket.7 + + * sha 256: f33abe5f18cb087ab421c3b647437c31a01e5c731638cac859a9b9ea1f88099e + * sha 512: f973bd2a67d9ca8b4bf2d150c4f1151163f379c7048e1e4be098d8032a424c77bd4dfaa98635bb8cdefa0b2da147b9b6a87bcbcaa87c378b5040e708f8ca5a97 + 2.2.3 cagebreak * sha 256: 265a9d09622272ca6ea79ddcdbdc6003704106814eb05a2b7547a77a982263de diff --git a/LICENSE b/LICENSE index e0aba93..462eccf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2023 The Cagebreak authors +Copyright (c) 2020-2024 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes Copyright (c) 2019 The Sway authors diff --git a/README.md b/README.md index 1ca4ce5..79397ea 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,55 @@ -# Cagebreak: A Wayland Tiling Compositor +# Cagebreak: A Tiling Wayland Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.2.3)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.3.0)](https://repology.org/project/cagebreak/versions) -## Quick Introduction +[![Contact](img/mail.svg)](SECURITY.md) [![Manuals](img/manuals.svg)](manuals.md) [![FAQ](img/faq.svg)](FAQ.md) [![CONTRIBUTING](img/contributing.svg)](CONTRIBUTING.md) [![ArchWiki](img/archwiki.svg)](https://wiki.archlinux.org/title/Cagebreak) [![AUR](img/aur.svg)](https://aur.archlinux.org/packages?O=0&K=cagebreak) -Cagebreak is a [Wayland](https://wayland.freedesktop.org/) tiling compositor -based on [Cage](https://github.com/Hjdskes/cage) and inspired by [ratpoison](https://www.nongnu.org/ratpoison/). +## Introduction -### Purpose +Cagebreak provides a [ratpoison](https://www.nongnu.org/ratpoison/)-inspired, [cage](https://github.com/Hjdskes/cage)-based, tiling [Wayland](https://wayland.freedesktop.org/) compositor. -This project provides a successor to ratpoison for Wayland. -However, this is no reimplementation of ratpoison. - -#### New Features, Bugs and Contact Information - -You can [open an issue](https://github.com/project-repo/cagebreak/issues/new) -or write an e-mail (See [SECURITY.md](SECURITY.md) for details.). - -The Roadmap section outlines our plans. - -#### Compatibility & Development Distribution - -Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the libraries -and versions from extra and core at the time of release. -Most other setups work with a bit of luck. - -### Quick Installation - -This assumes Arch Linux: - -1. Use the [cagebreak PKGBUILD](https://aur.archlinux.org/packages/cagebreak). -2. Add an example config such as [config](examples/config) to `$USER/.config/cagebreak/config` -3. Execute cagebreak like any other binary. - -See the [ArchWiki](https://wiki.archlinux.org/title/Cagebreak#Getting_started) for -details on getting started and the documentation for everything else. - -### Documentation - - * the man pages: [cagebreak](man/cagebreak.1.md), [configuration](man/cagebreak-config.5.md) & [socket](man/cagebreak-socket.7.md) - * the [README](README.md), [FAQ](FAQ.md) & [SECURITY.md](SECURITY.md) - -#### What's new? - -Check the [Changelog](Changelog.md). - -### Uninstallation - -`pacman -R cagebreak` should be sufficient. - -### Contributing - - * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your idea. - We will get back to you. - * Ask before you open a pull request. We might not accept your code and - it would be sad to waste the effort. - * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never - had to intervene - Keep it that way!) - -### Name - -Cagebreak is based on [Cage](https://github.com/Hjdskes/cage), a Wayland kiosk -compositor. Since it breaks the kiosk into tiles the name -Cagebreak seemed appropriate. + * Bugs, Contact Information and New Features: + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new). + * Write an e-mail (See [SECURITY.md](SECURITY.md)). + * The Roadmap below outlines our plans. + * Compatibility & Development Distribution: + * Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the library + versions from extra and core at the time of release. + Most other setups work with a [bit of luck](https://repology.org/project/cagebreak/versions). + * Quick Installation (on ArchLinux, more [here (ArchWiki)](https://wiki.archlinux.org/title/Cagebreak)): + 1. Use the [cagebreak PKGBUILD](https://aur.archlinux.org/packages/cagebreak). + 2. Add an example config such as [config](examples/config) to `$USER/.config/cagebreak/config` + 3. Execute cagebreak like any other binary. + * Documentation: + * [man pages](manuals.md) + * [README](README.md), [FAQ](FAQ.md) & [SECURITY.md](SECURITY.md) + * What's new?: [Changelog](Changelog.md) + * Uninstallation: `pacman -R cagebreak` + * Contributing: + * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your idea. + We will get back to you. + * Ask before you open a pull request. We might not accept your code and + it would be sad to waste the effort. + * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we've never + had to intervene. - Keep it that way!) + * Name: Cagebreak breaks the kiosk of [Cage](https://github.com/Hjdskes/cage) into tiles, hence the name. ## Installation -On Arch Linux, just use the PKGBUILDs from the [AUR](https://aur.archlinux.org/): +On [Arch Linux](https://archlinux.org/), use the [AUR](https://aur.archlinux.org/) [PKGBUILDs](https://wiki.archlinux.org/title/PKGBUILD): * Using [cagebreak](https://aur.archlinux.org/packages/cagebreak), Cagebreak is - compiled on the target system (since release 1.3.0) + built on the target system (since release 1.3.0) * Using [cagebreak-bin](https://aur.archlinux.org/packages/cagebreak-bin), - the pre-built binaries are extracted to - appropriate paths on the target system (since release 1.3.2) + pre-built binaries are extracted + to the target system (since release 1.3.2) See [cagebreak-pkgbuild](https://github.com/project-repo/cagebreak-pkgbuild) for details. +You may check out other distros here: + +[![Packaging status](https://repology.org/badge/vertical-allrepos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) + ### Obtaining Source Code There are different ways to obtain cagebreak source: @@ -85,61 +59,69 @@ There are different ways to obtain cagebreak source: #### Verifying Source Code -There are corresponding methods of verifying that you obtained the correct code: +There are ways to verify that you obtained the correct source (See `keys/` +and [CONTRIBUTING](CONTRIBUTING.md)): - * our git history includes signed tags for releases - * release assets starting at release 1.2.1 contain a signature for the tarball + * signature for the tarball of release assets starting at release 1.2.1 + * signed tags for releases in the git history ## Building Cagebreak -You can build Cagebreak with the [meson](https://mesonbuild.com/) build system. It -requires wayland, wlroots and xkbcommon to be installed. Note that Cagebreak is -developed against the latest tag of wlroots, in order not to constantly chase -breaking changes as soon as they occur. +Cagebreak uses the [meson](https://mesonbuild.com/) build system. -Simply execute the following steps to build Cagebreak: +Cagebreak is developed against the latest tag of wlroots, so as not to constantly +chase breaking changes. + +Execute the following commands to build Cagebreak: ``` -$ meson setup build +$ meson setup build -Dxwayland=true -Dman-pages=true --buildtype=release $ ninja -C build ``` -#### Release Build +### Man Pages -By default, this builds a debug build. To build a release build, use `meson -setup build --buildtype=release`. +Remove `-Dman-pages=true` to disable man page generation. -##### Xwayland Support +To generate man pages, make sure that you have [scdoc](https://archlinux.org/packages/extra/x86_64/scdoc/) installed. -Cagebreak comes with compile-time support for XWayland. To enable this, -first make sure that your version of wlroots is compiled with this -option. Then, add `-Dxwayland=true` to the `meson` command above. Note -that you'll need to have the XWayland binary installed on your system -for this to work. +### Release Build -##### Man Pages +To obtain a debug build, remove `--buildtype=release`. -Cagebreak has man pages. To use them, make sure that you have `scdoc` -installed. Then, add `-Dman-pages=true` to the `meson` command. +The release build is reproducible under conditions outlined in [CONTRIBUTING](CONTRIBUTING.md). -### Running Cagebreak +### Xwayland Support -You can start Cagebreak by running `./build/cagebreak`. If you run it from -within an existing X11 or Wayland session, it will open in a virtual output as -a window in your existing session. If you run it in a TTY, it'll run with the -KMS+DRM backend. Note that a configuration file is required. For more -configuration options, see the man pages. +To build Cagebreak without XWayland support, remove `-Dxwayland=true`. -Please see `example_scripts/` for example scripts and a basis to customize -from. +To use XWayland make sure that your version of wlroots is compiled with +XWayland support. -#### Usage Philosophy +You'll need to have [XWayland](https://archlinux.org/packages/extra/x86_64/xorg-xwayland/) installed for XWayland support to work. -Cagebreak was originally built to suit the needs of its creators. This section outlines +## Running Cagebreak + +``` +$ ./build/cagebreak +``` + +If you run Cagebreak within an existing X11 or Wayland session, it will +open in a virtual output as a window in your existing session. + +If you run it in a TTY, it'll run with the KMS+DRM backend. + +Note that a configuration file is required. For more configuration options, see the [man pages](manuals.md). + +Please see `example_scripts/` for a basis to customize from. + +### Usage Philosophy + +Cagebreak was built to suit the needs of its creators. This outlines how we intended some parts of cagebreak and might ease learning how to use cagebreak a -little bit. Please note that this does not replace the man pages or the FAQ. -Also, this is in no way intended as a guide on how cagebreak must be used but rather -as a source of inspiration and explanations for certain particularities. +little bit. Please note that this does not replace the [man pages](manuals.md) or the [FAQ](FAQ.md). +Also, this is not intended as a guide on how cagebreak must be used but +as a source of inspiration and explanation for certain particularities. 1. Cagebreak is keyboard-based. Everything regarding cagebreak can be done through the keyboard and it is our view that it should be. This does not mean @@ -196,467 +178,6 @@ as a source of inspiration and explanations for certain particularities. > Example scripts can be found in the repository under `example_scripts/`. -## Contributing - - * Read this document. - * [Open an issue](https://github.com/project-repo/cagebreak/issues/new) and state your feature request. - We will get back to you. - * Ask before opening a pull request. We might not accept your - code and it would be sad to waste the effort. - * Respect the [Code of Conduct](CODE_OF_CONDUCT.md) (To date, we never - had to intervene - Please keep it that way!) - -### Good First Contributions - - * Reviews are always welcome. - * Read the code. - * Read the documentation. - * Test whether the documentation matches the code. - * Test Cagebreak in more esoteric setups (many monitors, for instance). - * Compile the code. - * Ideas on improving the testing and quality assurance are particularly - welcome. - * You can share your cagebreak scripts and we might include them with Cagebreak - provided you agree to release them under MIT and we agree with the - use case and coding style. - * If you are happy with Cagebreak under Arch Linux, you may vote for - [Cagebreak in the AUR](https://aur.archlinux.org/packages/cagebreak). - * The points from the Contributing section above still apply. - -### Philosophy - -Cagebreak is currently developed to fit the needs of its creators. - -The feature set is intentionally limited - we removed -support for a desktop background image for example. - -Nonetheless, don't be intimidated by any other part of this file. -Do your best and we will collaborate toward a solution. - -## Development - -### Compatibility & Development Distribution - -Cagebreak supports [Arch Linux](https://archlinux.org/) and uses the libraries -(and software versions) as they are obtained through [pacman](https://wiki.archlinux.org/title/Pacman) -at the time of release. Any other use is out of scope. - -However, Cagebreak may also work on other distributions given the -proper library versions (Some package maintainers have done this and it -seems to work (To date, we dealt with a few Issues and never felt the -need to ask for the distribution the user was having the issue on.)). - -[![Packaging status](https://repology.org/badge/vertical-allrepos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) - -You should use Arch Linux if you want to modify Cagebreak -for yourself. - -### Review Requirements - -Project-repo will review your proposal before your implementation for feasibility -and desirability. After your pull request, the code will be reviewed in conjunction -with all other changes before the release as per the release procedure. - -All reviews performed by project-repo are verified by at least two people internally. - -### Developer Certificate of Origin (DCO) - -On any pull requests please include a - -``` -signed-off-by: YOUR IDENTIFIER OR NAME -``` - -DCO statement. - -By doing this you claim that you are legally allowed to contribute the -code and agree to let project-repo publish it under the MIT License. - -#### Development Environment - -CAVEAT: This script works exclusively on Arch Linux, which, as outlined above, -is the development distribution of Cagebreak. - -Cloning the Cagebreak repository and building it is sufficient as a starting point. - -All other dependencies can be installed by invoking - -``` -meson compile devel-install -C build -``` - -if meson is already available or - -``` -./scripts/install-development-environment -``` - -otherwise. - -#### Scripts - -Cagebreak provides a few convenience tools to facilitate development. - -##### Fuzzing - -If your fuzzing corpus is located in the directory `fuzz_corpus` you can -just call: - -``` -meson compile fuzz -C build -``` - -If you want to use a different directory, configure cagebreak with -`-Dcorpus=OTHERDIRECTORY` or call `./scripts/fuzz OTHERDIRECTORY`. - -##### Adjusting Epoch - -To facilitate the creation of reproducible man pages an arbitrary release -time has to be set in `meson.build`: - -``` -meson compile adjust-epoch -C build -``` - -or - -``` -./scripts/adjust-epoch -``` - -##### Git tag - -If you are on the master branch, everything is ready and you want to create -a release tag you can call: - -``` -meson compile git-tag -C build -``` - -If you want to use another signing key than the prespecified one, configure -Cagebreak with `-Dgpg_id=GPGID`. - -``` -./scripts/git-tag GPGID CBVERSION -``` - -can be used alternatively. - -##### Output Hashes - -Hashes of release versions of all binaries can be output to `local-hashes.txt` -via: - -``` -meson compile output-hashes -C build -``` - -Or - -``` -./scripts/output-hashes VERSION -``` - -if meson is unavailable. - -##### Create Signatures - -Creation of signatures for releases can be achieved through: - -``` -meson compile create-sigs -C build -``` - -Configure Cagebreak with `-Dgpg_id=GPGID` for a different gpg signing -key. - -Without meson use: - -``` -./scripts/create-signatures GPGID -``` - -##### Set Version Number - -Once the version number is set within meson.build, you can use - -``` -meson compile set-ver -C build -``` - -to set the version number in the man pages and README repology minversion. - -Use of the script without meson is discouraged because meson.build is -not touched by the script. - -##### Create Release Artefacts - -The following command generates the release artefacts which must be created -once a release is completely ready to be published (the commit is tagged with -the version of the master branch, etc.): - -``` -meson compile create-artefacts -C build -``` - -Use of the script version is discouraged. - -### GCC and -fanalyzer - -Cagebreak should compile with any reasonably new gcc or clang. Consider -a gcc version of at least [10.1](https://gcc.gnu.org/gcc-10/changes.html) if -you want to get the benefit of the brand-new -[-fanalyzer](https://gcc.gnu.org/onlinedocs/gcc/Static-Analyzer-Options.html) -flag. However, this new flag sometimes produces false-postives and we -selectively disable warnings for affected code segments as described below. - -Meson is configured to set `CG_HAS_FANALYZE` if `-fanalyzer` is available. -Therefore, to maintain portability, false-positive fanalyzer warnings are to be -disabled using the following syntax: - -``` -#if CG_HAS_FANALYZE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "WARNING OPTION" -#endif -``` -and after - -``` -#if CG_HAS_FANALYZE -#pragma GCC diagnostic pop -#endif -``` - -### Test Suite - -``` -meson test -C build -``` - -invokes all tests. This is required for a release to occur. - -There are four test suites: - - * basic: tests actual outward-facing functionality - * Note optional dependencies for efficient socket interaction - * nc (openbsd-netcat) - * jq - * devel: tests internal properties of the repository - * Note potentially heavier dependencies such as - * shellcheck - * clang-format - * devel-long: applies more costly testing - * Note potentially heavier dependencies such as - * scan-build (static analysis (including security-relevant issues)) - * release: tests release specific considerations - * Note that this is only expected to pass just before - a release. This checks mostly administrative things - to check that a release is ready. - * Note that non-auto tests are files in `release-non-auto-checks` - and have to contain the release version and current date in - YYYY-mm-dd format on seperate lines. This is our imperfect attempt - to guarantee some hard-to-automate checks are carried out before - a release is undertaken. - -Every commit should pass at least the basic and devel suites. - -It is expected that cagebreak passes at least the -basic, devel and devel-long suites when commits are pushed: - -``` -meson test -C build --suite basic --suite devel -``` - -The basic suite can be used to test a binary. This is -useful for PKGBUILDs and their equivalents in other -systems. - -``` -meson test -C build --suite basic -``` - -### Fuzzing - -Along with the project source code, a fuzzing framework based on `libfuzzer` is -supplied. This allows for the testing of the parsing code responsible for reading -the `cagebreak` configuration file. When `libfuzzer` is available (please -use the `clang` compiler to enable it), building the fuzz-testing software can -be enabled by passing `-Dfuzz=true` to meson. This generates a `build/fuzz/fuzz-parse` -binary according to the `libfuzzer` specifications. Further documentation on -how to run this binary can be found [here](https://llvm.org/docs/LibFuzzer.html). - -Here is an example workflow: - -``` -rm -rf build -CC=clang meson setup build -Dfuzz=true -Db_sanitize=address,undefined -Db_lundef=false -ninja -C build/ -mkdir build/fuzz_corpus -cp examples/config build/fuzz_corpus/ -WLR_BACKENDS=headless ./build/fuzz-parse -jobs=12 -max_len=50000 -close_fd_mask=3 build/fuzz_corpus/ -``` - -You may want to tweak `-jobs` or add other options depending on your own setup. -We have found code path discovery to increase rapidly when the fuzzer is supplied -with an initial config file. We are working on improving our fuzzing coverage to -find bugs in other areas of the code. - -#### Caveat - -Currently, there are memory leaks which do not seem to stem from our code but rather -the code of wlroots or some other library we depend on. We are working on the problem. -In the meantime, add `-Db_detect-leaks=0` to the meson command to exclude memory leaks. - -### Reproducible Builds - -Cagebreak offers reproducible builds given the exact library versions specified -in `meson.build`. Should a version mismatch occur, a warning will be emitted. We have -decided on this compromise to allow flexibility and security. In general we will -adapt the versions to the packages available under Arch Linux at the time of -release. - -There are reproducibility issues up to and including release `1.2.0`. See -`Issue 5` in [Bugs.md](Bugs.md). - -#### Reproducible Build Instructions - -All hashes and signatures are provided for the following build instructions. - -``` -meson setup build -Dxwayland=true -Dman-pages=true --buildtype=release -ninja -C build -``` - -#### Hashes for Builds - -For every release after 1.0.5, hashes will be provided. - -For every release after 1.7.0, hashes will be provided for man pages too. - -See [Hashes.md](Hashes.md) - -#### GPG Signatures - -For every release after 1.0.5, a GPG signature will be provided in `signatures`. - -The current signature is called `cagebreak.sig`, whereas all older signatures -will be named after their release version. - -Due to errors in the release process, the releases 1.7.1 and 1.7.2 did not include the release -signatures in the appropriate folder of the git repository. However, signatures were provided -as release-artefacts at the time of release. The signatures were introduced into the -repository with 1.7.3. The integrity of cagebreak is still the same because the signatures were -provided as release-artefacts (which were themselves signed) and the hashes in Hashes.md -are part of a signed release tag. - -#### Signing Keys - -All releases are signed by at least one of the following collection of -keys. - - * E79F6D9E113529F4B1FFE4D5C4F974D70CEC2C5B - * 4739D329C9187A1C2795C20A02ABFDEC3A40545F - * 7535AB89220A5C15A728B75F74104CC7DCA5D7A8 - * 827BC2320D535AEAD0540E6E2E66F65D99761A6F - * A88D7431E5BAAD0B6EAE550AC8D61D8BD4FA3C46 - * 8F872885968EB8C589A32E9539ACC012896D450F - * 896B92AF738C974E0065BF42F2576BD366156BB9 - * AA927AFD50AF7C6810E69FE8274F2C605359E31B - * BE2DED372287BC4EB2213E13A0C743848A638955 - * 0F3476E4B2404F95EC41600683D5810F7911B020 - * 4E82C72C6B3E58A7BC4FF8554909F84CA83BB867 - * 5AEB1A2EB0D13F67E306AC59DC0CC81BE006FD85 - -Should we at any point retire a key, we will only replace it with keys signed -by at least one of the above collection. - -We registered project-repo.co and added mail addresses after release `1.3.0`. - -We now have a mail address and its key is signed by signing keys. See [SECURITY.md](SECURITY.md) -for details. - -The full public keys can be found in `keys/` along with any revocation certificates. - -### Versioning & Branching Strategy - -Cagebreak uses [semantic versioning](https://semver.org). - -There are three permanent branches in cagebreak: - - * `master` (for releases) - * `development` (for polishing code between releases) - * `hotfix` (for small emergent releases, usually up-to-date with master) - -Releases are merged to master as per the release procedure, with -reasonable exceptions as the situation requires. - -The release commit is tagged with the release version. - -In the past, our git history did not perfectly reflect this scheme. - -### Release Procedure - -The release procedure outlines the process for a release to occur. - - * [ ] `git checkout development` - * [ ] `git pull origin development` - * [ ] `git push origin development` - * [ ] Arch Build System is up to date - * [ ] `meson test -C build/` just to get an overview - * [ ] Update internal wiki - * [ ] Adjust version number in meson.build - * [ ] `meson compile set-ver -C build` - * [ ] Add new files to meson.build or hardcoded testing variable - * [ ] Commit changes - * [ ] `git push origin development` - * [ ] Complete relevant documentation - * [ ] New features - * [ ] tests added and old test scripts adjusted - * [ ] man pages - * [ ] cagebreak - * [ ] cagebreak-config - * [ ] cagebreak-socket - * [ ] example config - * [ ] FAQ.md - * [ ] Changelog.md for major and minor releases but not patches - * [ ] Check changes for SECURITY.md relevance (changes to socket scope for example) - * [ ] Synchronize any socket changes to cagebreak-socket man page - * [ ] Document fixed bugs in Bugs.md - * [ ] Include issue discussion from github, where applicable - * [ ] `meson compile adjust-epoch -C build` - * [ ] Commit changes - * [ ] `git push origin development` - * [ ] Testing - * [ ] Manual testing - * [ ] `meson compile fuzz -C build` for at least one hour - * [ ] Adjust Hashes.md - Use `meson compile output-hashes -C build` to add Hashes or aid in repro check - * [ ] Commit changes - * [ ] `git push origin development` - * [ ] Complete release-non-auto-checks - * [ ] `meson compile create-sigs -C build` - * [ ] Commit and push signatures, hashes and non-auto-check files - * [ ] `meson test -C build` passes everything except some release tests - * [ ] `git add` relevant files - * [ ] `git commit` - * [ ] `git push origin development` - * [ ] `git checkout master` - * [ ] `git merge --squash development` - * [ ] `git commit` and insert message - * [ ] `meson compile git-tag -C build` - * [ ] `meson compile create-artefacts -C build` - * [ ] `meson test -C build` THIS MUST PASS WITHOUT ANY FAILURES WHATSOEVER - * [ ] `git push --tags origin master` - * [ ] `git checkout development` (merge to development depends on whether release was a hotfix) - * [ ] `git merge master` - * [ ] `git push --tags origin development` - * [ ] `git checkout hotfix` (hotfix is to be kept current with master after releases) - * [ ] `git merge master` - * [ ] `git push --tags origin hotfix` - * [ ] Upload archives and signatures as release assets - * [ ] Delete feature branches if appropriate - * [ ] Manage package release - ## Roadmap Cagebreak plans to do or keep doing the following things @@ -664,20 +185,24 @@ in the future: * React to all issues. * Add or modify features, which the authors find convenient or important. - * Improve the [OpenSSF Best Practices Badge Program](https://bestpractices.coreinfrastructure.org/en) level + * Improve the [OpenSSF Best Practices Badge Program](https://bestpractices.coreinfrastructure.org/en) level. ## Governance Cagebreak is managed by project-repo. +Consider project-repo a single benevolent dictator for life that happens +to occupy at least two brains. + Project-repo is a pseudonym of at least two individuals acting as benevolent dictators for the project by the others mutual consent. The individuals comprising project-repo are not otherwise associated by payment from any organisation or grant. -For all intents and purposes consider project-repo as a single -benevolent dictator for life that happens to occupy at least two brains. +### Governance Issues + +Use [SECURITY.md](SECURITY.md) to contact project-repo. ### Roles @@ -687,37 +212,20 @@ There are no specific roles forced unto anyone. ### Bus Factor +The current bus factor for Cagebreak is: 1 + The Bus Factor is a measure of how many people have to be incapacitated for a project to be unable to continue. -The current bus factor for Cagebreak is: 1 - -Project-repo could still react to issues (even confidential +Project-repo could react to issues (even confidential e-mails) and fix easier issues if any one individual were incapacitated. However, not all aspects of the code or release engineering are fully resilient to the loss of any one individual. -We strive to improve the Bus Factor to at least two in all -aspects of Cagebreak. - -### Governance Issues - -Anyone can use the information in [SECURITY.md](SECURITY.md) to -contact the members of project-repo and bring governance -issues to their attention. - -## Bugs - -For any bug, please [create an issue](https://github.com/project-repo/cagebreak/issues/new) on -[GitHub](https://github.com/project-repo/cagebreak). - -Fixed bugs are to be assigned a number and summarized inside Bugs.md for future reference -independent of github, in case this service is unavailable. - -For other means of contacting the Cagebreak authors and for security issues -see [SECURITY.md](SECURITY.md). +We strive to increase the bus factor to at least 2 in all +aspects. ## Accessibility @@ -730,6 +238,14 @@ see [SECURITY.md](SECURITY.md). would work and cagebreak does not preclude the use of a screen reader for any software run with it. +## Bugs + +[Open an issue](https://github.com/project-repo/cagebreak/issues/new) is you find something. + +See [SECURITY.md](SECURITY.md) for other means of contacting the Cagebreak authors and security issues. + +Fixed bugs are assigned a number and summarized in [Bugs.md](Bugs.md) for future reference. + ## Contributors * Aisha Tammy @@ -742,10 +258,14 @@ see [SECURITY.md](SECURITY.md). released in 2.2.1 with slight modifications * Tom Greig * Fix bug in merge_output_configs in 2.1.2 + * sodface + * Add a screenshot example script in 2.3.0 + * Luca Kennedy (unsigned-enby) + * [Add option to configure the anchor position of messages](https://github.com/project-repo/cagebreak/pull/61) in 2.3.0 ## License -Copyright (c) 2020-2023 The Cagebreak authors +Copyright (c) 2020-2024 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes Copyright (c) 2019 The Sway authors diff --git a/SECURITY.md b/SECURITY.md index a55a2b4..110d48d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,17 +1,33 @@ # Security -The main possibility for security bugs in cagebreak is by privilege -escalation through the socket. Any program with access to the socket -immediately gains arbitrary code execution rights. The socket -is restricted to the user of the cagebreak process (700) and has to -be explicitely enabled using the `-e` flag on invocation. +The main possibility for security bugs in cagebreak is privilege +escalation via the socket. Any program with access to the socket +immediately gains arbitrary code execution rights. The socket has to +be explicitely enabled using the `-e` flag on invocation and +is restricted to the user of the cagebreak process (700). -If you disagree with this threat model, you may contact us via email (See -section Email Contact below.) or [open an issue on github](https://github.com/project-repo/cagebreak/issues/new). +## Email Contact -Should any problem with the github issue system arise or any other reason -for (potentially confidential) contact with the Cagebreak authors appear, -you may contact us via email (See section Email Contact below.). +If you want to get in touch with project-repo via email, contact +`cagebreak @ project-repo . co`. + +We try to respond to everything that is not obvious spam. + +### GPG-Encrypted Emails + +If you can, please encrypt your email with the appropriate GPG key found +in `keys/` and sign your message with your own key. + +* B15B92642760E11FE002DE168708D42451A94AB5 (expired) +* F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C (expired) +* 3ACEA46CCECD59E4C8222F791CBEB493681E8693 (expired) +* 0A268C188D7949FEB39FD1462F2AD980247E4918 (soon to expire) +* [283D10F54201B0C6CCEE2C561DE04E4B056C749D](keys/cagebreak@project-repo.co.pub) + +Note that our keys are signed by cagebreak signing keys. + +If you want us to respond via GPG-encrypted email, please include your own +public key or provide the fingerprint and directions to obtain the key. ## Supported Versions @@ -24,30 +40,7 @@ Builds are reproducible under conditions outlined in [README.md](README.md). For normal bugs you may [open an issue on github](https://github.com/project-repo/cagebreak/issues/new). For everything else, an email contact (with gpg encryption and signature) -is available below. - -## Email Contact - -If you want to get in touch with the developers of cagebreak to report -a security vulnerability or anything else via email, contact -`cagebreak @ project-repo . co`. - -We try to respond to everything that is not obvious spam. - -### GPG-Encrypted Emails - -If you can, please encrypt your email with the appropriate GPG key found -in `keys/` and sign your message with your own key. - -* B15B92642760E11FE002DE168708D42451A94AB5 -* F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C -* 3ACEA46CCECD59E4C8222F791CBEB493681E8693 -* 0A268C188D7949FEB39FD1462F2AD980247E4918 - -Note that our keys are signed by cagebreak signing keys. - -If you want us to respond via GPG-encrypted email, please include your own -public key or provide the fingerprint and directions to obtain the key. +is available above. ## Threat Model @@ -57,7 +50,7 @@ Cagebreak cannot restrict other programs (consider a web browser unable to write a downloaded file for instance). There is no transmission of information by cagebreak other than to the -screens, ipc and potentially other documented local channels. +screens, ipc (if enabled with `-e`) and potentially other documented local channels. ### STRIDE Threat List @@ -76,7 +69,7 @@ Not applicable - Cagebreak allows system manipulation for user software. Not applicable - There are no prohibited operations (See Tampering above.). Cagebreak sends events over documented channels. There is no logging -activated by default - this can be changed by logging the socket (if enabled) for example. +activated by default - this can be changed by logging the socket for example. #### Information Disclosure @@ -86,12 +79,12 @@ Any user software may exfiltrate any data the user has access to. #### Denial of Service Not applicable - Cagebreak offers functionality to terminate itself. This is -available to user software over the socket (if enabled). +available to user software over the socket. #### Elevation of Privilege Software may gain arbitrary code execution if it has access to the -socket (if enabled). Privilege escalation to root is unlikely since privileges +socket. Privilege escalation to root is unlikely since privileges are dropped before any user input is accepted. ## GPG Keys of the Cagebreak Repository diff --git a/cagebreak.c b/cagebreak.c index 66afdf3..9ce99b8 100644 --- a/cagebreak.c +++ b/cagebreak.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _DEFAULT_SOURCE @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -279,7 +280,6 @@ main(int argc, char *argv[]) { struct wlr_viewporter *viewporter = NULL; struct wlr_presentation *presentation = NULL; struct wlr_xdg_output_manager_v1 *output_manager = NULL; - struct wlr_gamma_control_manager_v1 *gamma_control_manager = NULL; struct wlr_xdg_shell *xdg_shell = NULL; wl_list_init(&server.input_config); wl_list_init(&server.output_config); @@ -356,6 +356,7 @@ main(int argc, char *argv[]) { server.message_config.display_time = 2; server.message_config.font = strdup("pango:Monospace 10"); + server.message_config.anchor = CG_MESSAGE_TOP_RIGHT; event_loop = wl_display_get_event_loop(server.wl_display); sigint_source = @@ -369,6 +370,7 @@ main(int argc, char *argv[]) { server.event_loop = event_loop; backend = wlr_backend_autocreate(server.wl_display, &server.session); + server.headless_backend = wlr_headless_backend_create(server.wl_display); if(!backend) { wlr_log(WLR_ERROR, "Unable to create the wlroots backend"); ret = 1; @@ -563,13 +565,17 @@ main(int argc, char *argv[]) { goto end; } - gamma_control_manager = + server.gamma_control = wlr_gamma_control_manager_v1_create(server.wl_display); - if(!gamma_control_manager) { + if(!server.gamma_control) { wlr_log(WLR_ERROR, "Unable to create the gamma control manager"); ret = 1; goto end; } + server.gamma_control_set_gamma.notify = + handle_output_gamma_control_set_gamma; + wl_signal_add(&server.gamma_control->events.set_gamma, + &server.gamma_control_set_gamma); #if CG_HAS_XWAYLAND server.xwayland = wlr_xwayland_create(server.wl_display, compositor, true); @@ -671,6 +677,8 @@ main(int argc, char *argv[]) { wl_list_init(&server.outputs); struct cg_output *output, *output_tmp; wl_list_for_each_safe(output, output_tmp, &tmp_list, link) { + wl_list_remove(&output->link); + output_insert(&server, output); output_configure(&server, output); } server.curr_output = @@ -692,10 +700,6 @@ main(int argc, char *argv[]) { end: if(server.modes != NULL) { -#if CG_HAS_FANALYZE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wanalyzer-double-free" -#endif for(unsigned int i = 0; server.modes[i] != NULL; ++i) { free(server.modes[i]); } @@ -761,6 +765,3 @@ end: return ret; } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic pop -#endif diff --git a/docs/dev-FAQ.md b/docs/dev-FAQ.md new file mode 100644 index 0000000..46c7669 --- /dev/null +++ b/docs/dev-FAQ.md @@ -0,0 +1,67 @@ +# FAQ for Development + +## How is cagebreak adjusted to a new wlroots version? + +There are three steps: + +1. Try to compile Cagebreak with the new wlroots. +2. Fix the compiler errors one-by-one using the wlroots + changelog for reference (https://gitlab.freedesktop.org/wlroots/wlroots/-/releases). +3. Debug until Cagebreak works again. + +## How do I add a new test? + +1. Add a shell script to `test/` +2. Optionally add test configs to `test/testing-configurations/` +3. Make sure the files have shebang, copyright and SPDX License identifiers + (use the other files for reference) +4. Add the test to `meson.build` as in the example below. +5. Add paths and env vars as shown in the other tests +6. Make sure the test is added to the correct suite + (check out CONTRIBUTING.md for details) + +``` +test('Scan-build (static analysis)', find_program('test/scan-build'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel-long') +``` + +## How do I add a new script? + +1. Add a shell script to `scripts/` +2. Make sure the files have shebang, copyright and SPDX License identifiers + (use the other files for reference) +3. Add the script to CONTRIBUTING.md +4. Add the script to meson.build as shown below + +``` +run_target('create-sigs', + command : ['scripts/create-signatures', get_option('gpg_id')]) +``` + +## How do I add an example script? + +Extrapolate from the examples in the `example_scripts` directory. + +The script should be executable standalone. See `test/script-header` for a possible +library. + +License, contributors etc. should be appropriate. + +Shellcheck must pass on any script (use of shellcheck pragmas is allowed but +discouraged). + +## How do I add a new gpg key? + +1. Check which gpg key versions are currently valid. +2. Generate keys with incremented numbers/emails/dates/passphrase. + * Use 4096 Bit RSA Keys +3. Sign the new keys with at least one then-old signing key. +4. Genereate new cagebreak@project-repo.co key +5. Sign the new mail key with the new signing keys. +6. Generate new pkgbuild key. +7. Sign the pkgbuild key with the new signing keys. +8. Add public keys to `keys/`. +9. Update meson_options.txt +10. Update [all man pages](../manuals.md), [CONTRIBUTING](../CONTRIBUTING.md), gpg-validity test & [SECURITY.md](../SECURITY.md) +11. Update the pkgbuild repo with the new key (key and readme). +12. Update git config email. +13. Securely distribute private keys and revocation certificates as per the internal wiki. diff --git a/docs/pull_request_template.md b/docs/pull_request_template.md new file mode 100644 index 0000000..589cd0c --- /dev/null +++ b/docs/pull_request_template.md @@ -0,0 +1,26 @@ +# Description + + + + +## Type of Change + + * [ ] Fix + * [ ] Backwards-compatible Feature + * [ ] Breaking Change + +## Considerations + + + + +## Credit + + * [ ] I want to be credited as YOUR_NAME_OR_PSEUDONYM in your contributor section + * [ ] I don't want to be credited. + + + + +signed-off-by: YOUR_NAME_OR_PSEUDONYM + diff --git a/example_scripts/screenshot_script b/example_scripts/screenshot_script new file mode 100755 index 0000000..59cf524 --- /dev/null +++ b/example_scripts/screenshot_script @@ -0,0 +1,44 @@ +#!/bin/bash +# Copyright 2023 - 2024, project-repo, sodface and the cagebreak contributors +# SPDX-License-Identifier: MIT +# +# Execute this script if you want to take a screenshot. +# Please supply your chosen cropping/editing tool as a +# command-line argument. The filepath to the temporary +# file will be given as an argument to your command. +# +# Example: +# screenshot_script "gwenview" + +named_pipe_send="$(mktemp -u)" +named_pipe_recv="$(mktemp -u)" +mkfifo "${named_pipe_send}" +mkfifo "${named_pipe_recv}" +nc -U "${CAGEBREAK_SOCKET}" < "${named_pipe_send}" > "${named_pipe_recv}"& +# The file descriptor 3 is set up to send commands to cagebreak and file +# descriptor 4 can be used to read events. Notice that events will pile up in +# file descriptor 4, so it is a good idea to continuously read from it or to +# clear it before starting a new transaction. +exec 3>"${named_pipe_send}" +exec 4<"${named_pipe_recv}" +# When the script exits, the os will clean up the pipe +rm "${named_pipe_recv}" +rm "${named_pipe_send}" + +if [[ ${#} -lt 1 ]] +then + echo "Expected a single command line argument specifying the command to edit the screenshot." + exit 1 +fi + +edit_cmd="${1}" + +echo "dump" >&3 +IFS= read -r -d $'\0' event <&4 + +co="$(echo "${event:6}"|jq -r ".curr_output")" +tmpfile="$(mktemp)" +grim -t png -o "${co}" "${tmpfile}" +bash -c "${edit_cmd} \"${tmpfile}\"" +wl-copy < "${tmpfile}" +rm "${tmpfile}" diff --git a/example_scripts/show_workspace_views.sh b/example_scripts/show_workspace_views old mode 100644 new mode 100755 similarity index 54% rename from example_scripts/show_workspace_views.sh rename to example_scripts/show_workspace_views index be6f0f9..33d76bc --- a/example_scripts/show_workspace_views.sh +++ b/example_scripts/show_workspace_views @@ -1,11 +1,23 @@ #!/bin/bash -# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# Copyright 2020 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT - +# # This script displays the process names of the views on the current workspace. -# Start up the ipc link -source "$(dirname "${BASH_SOURCE[0]}")/cb_script_header.sh" +named_pipe_send="$(mktemp -u)" +named_pipe_recv="$(mktemp -u)" +mkfifo "${named_pipe_send}" +mkfifo "${named_pipe_recv}" +nc -U "${CAGEBREAK_SOCKET}" < "${named_pipe_send}" > "${named_pipe_recv}"& +# The file descriptor 3 is set up to send commands to cagebreak and file +# descriptor 4 can be used to read events. Notice that events will pile up in +# file descriptor 4, so it is a good idea to continuously read from it or to +# clear it before starting a new transaction. +exec 3>"${named_pipe_send}" +exec 4<"${named_pipe_recv}" +# When the script exits, the os will clean up the pipe +rm "${named_pipe_recv}" +rm "${named_pipe_send}" echo "dump" >&3 diff --git a/examples/config b/examples/config index 6708e42..b0883cb 100644 --- a/examples/config +++ b/examples/config @@ -1,8 +1,7 @@ -# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# Copyright 2020 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT -###################### -# General settings an key bindings -###################### + +# General settings and key bindings exec xterm @@ -36,19 +35,21 @@ bind k focusup bind l focusright bind t exec xterm bind C-k close -#bind m message Hello World! +# bind m message Hello World! definekey resize h resizeleft definekey resize l resizeright definekey resize j resizedown definekey resize k resizeup definekey resize Escape setmode top -#unhide cursor (default) +# unhide cursor (default) cursor enable -###################### -#Workspaces -###################### +# send a custom event over the socket +# custom_event Hello World! + +## Workspaces + bind 1 screen 1 bind 2 screen 2 bind 3 screen 3 @@ -84,28 +85,33 @@ definekey top XF86_Switch_VT_4 switchvt 4 definekey top XF86_Switch_VT_5 switchvt 5 definekey top XF86_Switch_VT_6 switchvt 6 -###################### -#Bind Function keys -###################### +## Bind Function keys + definekey top XF86AudioMute exec pactl set-sink-mute 0 toggle definekey top XF86AudioLowerVolume exec pactl set-sink-mute 0 off&&amixer set Master 1%- definekey top XF86AudioRaiseVolume exec pactl set-sink-mute 0 off&&amixer set Master 1%+ definekey top XF86MonBrightnessDown exec xbacklight -dec 1 definekey top XF86MonBrightnessUp exec xbacklight -inc 1 -###################### -#Output configuration -###################### -#output eDP-1 pos 0 0 res 1366x768 rate 60 -#output eDP-1 disable -#output eDP-1 enable -#output eDP-1 prio 1 -#output eDP-2 pos 0 0 res 1366x768 rate 60 scale 2.0 +## Output configuration -##################### -#Input configuration -##################### +# output eDP-1 pos 0 0 res 1366x768 rate 60 +output eDP-1 disable +output eDP-1 enable +output eDP-1 permanent -#input 1234:0:Device_Ident click_method clickfinger -#input type:pointer scroll_method two_finger -#input * calibration_matrix 1 2 3 4 5 6 +output eDP-1 peripheral +# output eDP-1 prio 1 +# output eDP-2 pos 0 0 res 1366x768 rate 60 scale 2.0 + + +## Input configuration + +# input 1234:0:Device_Ident click_method clickfinger +# input type:pointer scroll_method two_finger +# input * calibration_matrix 1 2 3 4 5 6 + +## Message configuration + +# configure_message display_time 1 +# configure_message anchor top_center diff --git a/fuzz/execl_override.c b/fuzz/execl_override.c index 275d4f0..0f9a19f 100644 --- a/fuzz/execl_override.c +++ b/fuzz/execl_override.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT // This file is used by the fuzzer in order to prevent executing shell commands. diff --git a/fuzz/fuzz-lib.c b/fuzz/fuzz-lib.c index 650d8a8..2d46e50 100644 --- a/fuzz/fuzz-lib.c +++ b/fuzz/fuzz-lib.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -273,7 +273,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) { server.scene_output_layout = wlr_scene_attach_output_layout(server.scene, server.output_layout); - compositor = wlr_compositor_create(server.wl_display, 5, server.renderer); + compositor = wlr_compositor_create(server.wl_display, 6, server.renderer); if(!compositor) { wlr_log(WLR_ERROR, "Unable to create the wlroots compositor"); ret = 1; diff --git a/fuzz/fuzz-lib.h b/fuzz/fuzz-lib.h index 46aefd2..2715978 100644 --- a/fuzz/fuzz-lib.h +++ b/fuzz/fuzz-lib.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_FUZZ_LIB_H diff --git a/fuzz/fuzz-parse.c b/fuzz/fuzz-parse.c index d0bd5ab..9c35010 100644 --- a/fuzz/fuzz-parse.c +++ b/fuzz/fuzz-parse.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L diff --git a/idle_inhibit_v1.c b/idle_inhibit_v1.c index 019d47b..bc76ff7 100644 --- a/idle_inhibit_v1.c +++ b/idle_inhibit_v1.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #include @@ -15,10 +15,6 @@ struct cg_idle_inhibitor_v1 { struct wl_listener destroy; }; -#if CG_HAS_FANALYZE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" -#endif static void idle_inhibit_v1_check_active(struct cg_server *server) { /* As of right now, this does not check whether the inhibitor @@ -26,9 +22,6 @@ idle_inhibit_v1_check_active(struct cg_server *server) { bool inhibited = !wl_list_empty(&server->inhibitors); wlr_idle_notifier_v1_set_inhibited(server->idle, inhibited); } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic pop -#endif static void handle_destroy(struct wl_listener *listener, void *data) { diff --git a/idle_inhibit_v1.h b/idle_inhibit_v1.h index 74ae956..dc712bf 100644 --- a/idle_inhibit_v1.h +++ b/idle_inhibit_v1.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_IDLE_INHIBIT_H #define CG_IDLE_INHIBIT_H diff --git a/img/archwiki.svg b/img/archwiki.svg new file mode 100644 index 0000000..635b400 --- /dev/null +++ b/img/archwiki.svg @@ -0,0 +1 @@ + : Wiki \ No newline at end of file diff --git a/img/aur.svg b/img/aur.svg new file mode 100644 index 0000000..c8af6f3 --- /dev/null +++ b/img/aur.svg @@ -0,0 +1 @@ + : AUR \ No newline at end of file diff --git a/img/contributing.svg b/img/contributing.svg new file mode 100644 index 0000000..6d58a85 --- /dev/null +++ b/img/contributing.svg @@ -0,0 +1 @@ + : Contrib \ No newline at end of file diff --git a/img/faq.svg b/img/faq.svg new file mode 100644 index 0000000..41bfdfe --- /dev/null +++ b/img/faq.svg @@ -0,0 +1 @@ + : FAQ \ No newline at end of file diff --git a/img/mail.svg b/img/mail.svg new file mode 100644 index 0000000..78cfd12 --- /dev/null +++ b/img/mail.svg @@ -0,0 +1 @@ + : Mail \ No newline at end of file diff --git a/img/manuals.svg b/img/manuals.svg new file mode 100644 index 0000000..8aebe59 --- /dev/null +++ b/img/manuals.svg @@ -0,0 +1 @@ + : Manuals \ No newline at end of file diff --git a/img/web-artefacts.svg b/img/web-artefacts.svg new file mode 100644 index 0000000..00072e8 --- /dev/null +++ b/img/web-artefacts.svg @@ -0,0 +1 @@ + : Mirror \ No newline at end of file diff --git a/img/web-open-issue.svg b/img/web-open-issue.svg new file mode 100644 index 0000000..8c2de01 --- /dev/null +++ b/img/web-open-issue.svg @@ -0,0 +1 @@ + : + Issue \ No newline at end of file diff --git a/input.h b/input.h index f45e735..358c385 100644 --- a/input.h +++ b/input.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef _CG_INPUT_H diff --git a/input_manager.c b/input_manager.c index fcdd684..47ce206 100644 --- a/input_manager.c +++ b/input_manager.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L diff --git a/input_manager.h b/input_manager.h index b3eb006..eb6f019 100644 --- a/input_manager.h +++ b/input_manager.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_INPUT_MANAGER_H diff --git a/ipc_server.c b/ipc_server.c index 05614b3..37e59ad 100644 --- a/ipc_server.c +++ b/ipc_server.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _DEFAULT_SOURCE diff --git a/ipc_server.h b/ipc_server.h index 41d7b88..a8ae3ef 100644 --- a/ipc_server.h +++ b/ipc_server.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_IPC_SERVER_H diff --git a/keybinding.c b/keybinding.c index 6da0cc6..2432e59 100644 --- a/keybinding.c +++ b/keybinding.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -90,6 +90,7 @@ keybinding_free(struct keybinding *keybinding, bool recursive) { if(keybinding->data.m_cfg->font != NULL) { free(keybinding->data.m_cfg->font); } + free(keybinding->data.m_cfg); break; case KEYBINDING_DISPLAY_MESSAGE: if(keybinding->data.c != NULL) { @@ -248,8 +249,7 @@ swap_tile(struct cg_tile *tile, "{\"event_name\":\"swap_tile\",\"tile_id\":%d,\"swap_" "tile_id\":%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", tile->id, swap_tile->id, tile->workspace->num + 1, - tile->workspace->output->wlr_output->name, - output_get_num(tile->workspace->output)); + tile->workspace->output->name, output_get_num(tile->workspace->output)); } void @@ -399,8 +399,7 @@ resize(struct cg_tile *tile, const struct cg_tile *parent, int coord_offset, "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", tile->id, old_x, old_y, old_height, old_width, tile->tile.x, tile->tile.y, tile->tile.height, tile->tile.width, - tile->workspace->num + 1, - tile->workspace->output->wlr_output->name, + tile->workspace->num + 1, tile->workspace->output->name, output_get_num(tile->workspace->output)); } @@ -455,18 +454,18 @@ resize_vertical(struct cg_tile *tile, struct cg_tile *parent, int y_offset, void resize_tile(struct cg_server *server, int hpixs, int vpixs) { struct cg_output *output = server->curr_output; - struct wlr_box output_box; - wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, - &output_box); struct cg_tile *focused = output->workspaces[output->curr_workspace]->focused_tile; /* First do the horizontal adjustment */ - if(hpixs != 0 && focused->tile.width < output_box.width && - is_between_strict(0, output_box.width, focused->tile.width + hpixs)) { + if(hpixs != 0 && + focused->tile.width < output_get_layout_box(output).width && + is_between_strict(0, output_get_layout_box(output).width, + focused->tile.width + hpixs)) { int x_offset = 0; /* In case we are on the total right, move the left edge of the tile */ - if(focused->tile.x + focused->tile.width == output_box.width) { + if(focused->tile.x + focused->tile.width == + output_get_layout_box(output).width) { x_offset = -hpixs; } bool resize_allowed = @@ -476,10 +475,13 @@ resize_tile(struct cg_server *server, int hpixs, int vpixs) { } } /* Repeat for vertical */ - if(vpixs != 0 && focused->tile.height < output_box.height && - is_between_strict(0, output_box.height, focused->tile.height + vpixs)) { + if(vpixs != 0 && + focused->tile.height < output_get_layout_box(output).height && + is_between_strict(0, output_get_layout_box(output).height, + focused->tile.height + vpixs)) { int y_offset = 0; - if(focused->tile.y + focused->tile.height == output_box.height) { + if(focused->tile.y + focused->tile.height == + output_get_layout_box(output).height) { y_offset = -vpixs; } bool resize_allowed = @@ -500,7 +502,7 @@ keybinding_workspace_fullscreen(struct cg_server *server) { "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", output->workspaces[output->curr_workspace]->focused_tile->id, output->workspaces[output->curr_workspace]->num + 1, - output->wlr_output->name, output_get_num(output)); + output->name, output_get_num(output)); } // Switch to a differerent virtual terminal @@ -593,8 +595,8 @@ keybinding_split_output(struct cg_output *output, bool vertical) { "{\"event_name\":\"split\",\"tile_id\":%d,\"new_tile_id\":%d," "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d,\"vertical\":%d}", curr_workspace->focused_tile->id, new_tile->id, curr_workspace->num + 1, - curr_workspace->output->wlr_output->name, - output_get_num(curr_workspace->output), vertical); + curr_workspace->output->name, output_get_num(curr_workspace->output), + vertical); } static void @@ -612,8 +614,7 @@ keybinding_close_view(struct cg_view *view) { outp->server, "{\"event_name\":\"close\",\"view_id\":%d,\"view_pid\":%d,\"tile_id\":" "%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", - view_id, view_pid, tile_id, ws + 1, outp->wlr_output->name, - output_get_num(outp)); + view_id, view_pid, tile_id, ws + 1, outp->name, output_get_num(outp)); } static void @@ -628,7 +629,7 @@ keybinding_split_horizontal(struct cg_server *server) { static void into_process(const char *command) { - execl("/bin/sh", "sh", "-c", command, (char *)NULL); + execlp("sh", "sh", "-c", command, (char *)NULL); _exit(1); } @@ -668,8 +669,8 @@ keybinding_cycle_outputs(struct cg_server *server, bool reverse, "{\"event_name\":\"cycle_outputs\",\"old_output\":\"%s\",\"old_" "output_id\":%d," "\"new_output\":\"%s\",\"new_output_id\":%d,\"reverse\":%d}", - old_output->wlr_output->name, output_get_num(old_output), - output->wlr_output->name, output_get_num(output), reverse); + old_output->name, output_get_num(old_output), output->name, + output_get_num(output), reverse); } } @@ -719,7 +720,7 @@ keybinding_cycle_views(struct cg_server *server, bool reverse, bool ipc) { curr_id, curr_pid, next_view == NULL ? -1 : (int)next_view->id, next_view == NULL ? -1 : (int)next_view->impl->get_pid(next_view), next_view->tile->id, curr_workspace->num + 1, - curr_workspace->output->wlr_output->name, + curr_workspace->output->name, output_get_num(curr_workspace->output)); } } @@ -742,7 +743,7 @@ keybinding_focus_tile(struct cg_server *server, uint32_t tile_id) { "{\"event_name\":\"focus_tile\",\"old_tile_id\":%d,\"new_tile_" "id\":%d,\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", old_tile->id, workspace->focused_tile->id, workspace->num + 1, - output->wlr_output->name, output_get_num(output)); + output->name, output_get_num(output)); break; } } @@ -776,8 +777,7 @@ keybinding_switch_ws(struct cg_server *server, uint32_t ws) { ipc_send_event(output->server, "{\"event_name\":\"switch_ws\",\"old_workspace\":%d," "\"new_workspace\":%d,\"output\":\"%s\",\"output_id\":%d}", - old_ws + 1, ws + 1, output->wlr_output->name, - output_get_num(output)); + old_ws + 1, ws + 1, output->name, output_get_num(output)); return 0; } @@ -834,6 +834,50 @@ print_str(struct dyn_str *outp, const char *fmt, ...) { return 0; } +char * +print_message_conf(struct cg_message_config *config) { + struct dyn_str outp_str; + outp_str.len = 0; + outp_str.cur_pos = 0; + uint32_t nmemb = 7; + outp_str.str_arr = calloc(nmemb, sizeof(char *)); + print_str(&outp_str, "\"message_config\": {"); + print_str(&outp_str, "\"font\": \"%s\",\n", config->font); + print_str(&outp_str, "\"display_time\": %d,\n", config->display_time); + print_str(&outp_str, "\"bg_color\": [%f,%f,%f,%f],\n", config->bg_color[0], + config->bg_color[1], config->bg_color[2], config->bg_color[3]); + print_str(&outp_str, "\"fg_color\": [%f,%f,%f,%f],\n", config->fg_color[0], + config->fg_color[1], config->fg_color[2], config->fg_color[3]); + switch(config->anchor) { + case CG_MESSAGE_TOP_LEFT: + print_str(&outp_str, "\"anchor\": \"top_left\"\n", config->font); + break; + case CG_MESSAGE_TOP_CENTER: + print_str(&outp_str, "\"anchor\": \"top_center\"\n", config->font); + break; + case CG_MESSAGE_TOP_RIGHT: + print_str(&outp_str, "\"anchor\": \"top_right\"\n", config->font); + break; + case CG_MESSAGE_BOTTOM_LEFT: + print_str(&outp_str, "\"anchor\": \"bottom_left\"\n", config->font); + break; + case CG_MESSAGE_BOTTOM_CENTER: + print_str(&outp_str, "\"anchor\": \"bottom_center\"\n", config->font); + break; + case CG_MESSAGE_BOTTOM_RIGHT: + print_str(&outp_str, "\"anchor\": \"bottom_right\"\n", config->font); + break; + case CG_MESSAGE_CENTER: + print_str(&outp_str, "\"anchor\": \"center\"\n", config->font); + break; + case CG_MESSAGE_NOPT: // This should actually never occur + print_str(&outp_str, "\"anchor\": \"no_op\"\n", config->font); + break; + } + print_str(&outp_str, "}"); + return dyn_str_to_str(&outp_str); +} + void print_modes(struct dyn_str *str, char **modes) { uint32_t len = 0; @@ -1017,19 +1061,19 @@ print_output(struct cg_output *outp) { struct dyn_str outp_str; outp_str.len = 0; outp_str.cur_pos = 0; - uint32_t nmemb = 8; - struct wlr_box outp_box; - wlr_output_layout_get_box(outp->server->output_layout, outp->wlr_output, - &outp_box); + uint32_t nmemb = 10; outp_str.str_arr = calloc(nmemb, sizeof(char *)); - print_str(&outp_str, "\"%s\": {\n", outp->wlr_output->name); + print_str(&outp_str, "\"%s\": {\n", outp->name); print_str(&outp_str, "\"priority\": %d,\n", outp->priority); - print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n", outp_box.x, - outp_box.y); + print_str(&outp_str, "\"coords\": {\"x\":%d,\"y\":%d},\n", + output_get_layout_box(outp).x, output_get_layout_box(outp).y); print_str(&outp_str, "\"size\": {\"width\":%d,\"height\":%d},\n", outp->wlr_output->width, outp->wlr_output->height); print_str(&outp_str, "\"refresh_rate\": %f,\n", (float)outp->wlr_output->refresh / 1000.0); + print_str(&outp_str, "\"permanent\": %d,\n", + outp->role == OUTPUT_ROLE_PERMANENT); + print_str(&outp_str, "\"active\": %d,\n", !outp->destroyed); print_str(&outp_str, "\"curr_workspace\": %d,\n", outp->curr_workspace + 1); char *workspaces_str = print_workspaces(outp); if(workspaces_str != NULL) { @@ -1183,7 +1227,7 @@ keybinding_dump(struct cg_server *server) { struct dyn_str str; str.len = 0; str.cur_pos = 0; - uint32_t nmemb = 13; + uint32_t nmemb = 14; str.str_arr = calloc(nmemb, sizeof(char *)); print_str(&str, "{\"event_name\":\"dump\","); @@ -1200,11 +1244,15 @@ keybinding_dump(struct cg_server *server) { } print_str(&str, "\"views_curr_id\":%d,\n", curr_view_id); print_str(&str, "\"tiles_curr_id\":%d,\n", curr_tile_id); - print_str(&str, "\"curr_output\":\"%s\",\n", - server->curr_output->wlr_output->name); + print_str(&str, "\"curr_output\":\"%s\",\n", server->curr_output->name); print_str(&str, "\"default_mode\":\"%s\",\n", get_mode_name(server->modes, server->seat->default_mode)); print_modes(&str, server->modes); + char *message_string = print_message_conf(&server->message_config); + if(message_string != NULL) { + print_str(&str, "%s,", message_string); + free(message_string); + } char *outps_str = print_outputs(server); if(outps_str != NULL) { print_str(&str, "%s,", outps_str); @@ -1296,9 +1344,8 @@ keybinding_move_view_to_cycle_output(struct cg_server *server, bool reverse) { "{\"event_name\":\"move_view_to_cycle_output\",\"view_id\":%d,\"view_" "pid\":%d,\"old_output\":\"%s\",\"old_output_id\":%d,\"new_output\":\"%" "s\",\"new_output_id\":%d,\"old_tile_id\":%d,\"new_tile_id\":%d}", - id, pid, old_outp->wlr_output->name, output_get_num(old_outp), - server->curr_output->wlr_output->name, - output_get_num(server->curr_output), + id, pid, old_outp->name, output_get_num(old_outp), + server->curr_output->name, output_get_num(server->curr_output), old_outp->workspaces[old_outp->curr_workspace]->focused_tile->id, server->curr_output->workspaces[server->curr_output->curr_workspace] ->focused_tile->id); @@ -1420,8 +1467,8 @@ keybinding_switch_output(struct cg_server *server, int output) { "{\"event_name\":\"switch_output\",\"old_output\":" "\"%s\",\"old_output_id\":%d,\"new_output\":\"%s\"," "\"new_output_id\":%d}", - old_outp->wlr_output->name, output_get_num(old_outp), - it->wlr_output->name, output_get_num(it)); + old_outp->name, output_get_num(old_outp), it->name, + output_get_num(it)); return; } ++count; @@ -1467,8 +1514,7 @@ keybinding_move_view_to_output(struct cg_server *server, int output_num) { server, "{\"event_name\":\"move_view_to_output\",\"view_id\":%d,\"old_" "output\":\"%s\",\"new_output\":\"%s\"}", - view_id, old_outp->wlr_output->name, - server->curr_output->wlr_output->name); + view_id, old_outp->name, server->curr_output->name); } void @@ -1503,7 +1549,7 @@ keybinding_move_view_to_workspace(struct cg_server *server, uint32_t ws) { "\"old_workspace\":%d,\"new_workspace\":%d," "\"output\":\"%s\",\"output_id\":%d,\"view_pid\":%d}", view == NULL ? -1 : (int)view->id, old_ws + 1, ws + 1, - server->curr_output->wlr_output->name, + server->curr_output->name, output_get_num(server->curr_output), view == NULL ? 0 : view->impl->get_pid(view)); } @@ -1552,17 +1598,18 @@ keybinding_configure_output(struct cg_server *server, struct cg_output *output, *tmp_output; wl_list_for_each_safe(output, tmp_output, &server->outputs, link) { - if(strcmp(config->output_name, output->wlr_output->name) == 0) { + if(strcmp(config->output_name, output->name) == 0) { + int output_num = output_get_num(output); output_configure(server, output); - ipc_send_event(output->server, + ipc_send_event(server, "{\"event_name\":\"configure_output\",\"output\":\"%" "s\",\"output_id\":%d}", - cfg->output_name, output_get_num(output)); + cfg->output_name, output_num); return; } } wl_list_for_each_safe(output, tmp_output, &server->disabled_outputs, link) { - if(strcmp(config->output_name, output->wlr_output->name) == 0) { + if(strcmp(config->output_name, output->name) == 0) { output_configure(server, output); ipc_send_event( output->server, @@ -1618,6 +1665,9 @@ keybinding_configure_message(struct cg_server *server, server->message_config.fg_color[2] = config->fg_color[2]; server->message_config.fg_color[3] = config->fg_color[3]; } + if(config->anchor != CG_MESSAGE_NOPT) { + server->message_config.anchor = config->anchor; + } ipc_send_event(server, "{\"event_name\":\"configure_message\"}"); } @@ -1659,6 +1709,10 @@ run_action(enum keybinding_action action, struct cg_server *server, case KEYBINDING_RUN_COMMAND: { int pid; if((pid = fork()) == 0) { + setsid(); + sigset_t set; + sigemptyset(&set); + sigprocmask(SIG_SETMASK, &set, NULL); if(fork() == 0) { into_process(data.c); } diff --git a/keybinding.h b/keybinding.h index a5958f0..fca1271 100644 --- a/keybinding.h +++ b/keybinding.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef KEYBINDING_H diff --git a/keys/cagebreak@project-repo.co.pub b/keys/cagebreak@project-repo.co.pub index 648618b..4ef3235 100644 --- a/keys/cagebreak@project-repo.co.pub +++ b/keys/cagebreak@project-repo.co.pub @@ -1,87 +1,76 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -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 -=bl5A +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 +6arp +=AorA -----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak@project-repo.co.pub-legacy-4 b/keys/cagebreak@project-repo.co.pub-legacy-4 new file mode 100644 index 0000000..648618b --- /dev/null +++ b/keys/cagebreak@project-repo.co.pub-legacy-4 @@ -0,0 +1,87 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=bl5A +-----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak_signing_key_13@project-repo.co.pub b/keys/cagebreak_signing_key_13@project-repo.co.pub new file mode 100644 index 0000000..7c8a376 --- /dev/null +++ b/keys/cagebreak_signing_key_13@project-repo.co.pub @@ -0,0 +1,76 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +XPUssBeVi6uNhWON/EjKc0cLAfNwuBrjj6I= +=5Ie4 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/keys/cagebreak_signing_key_14@project-repo.co.pub b/keys/cagebreak_signing_key_14@project-repo.co.pub new file mode 100644 index 0000000..974001d --- /dev/null +++ b/keys/cagebreak_signing_key_14@project-repo.co.pub @@ -0,0 +1,76 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGWUZeUBEAC3tS/7YZznD2QlyIPUqMMxT7475FQqxPCd11OM2I6tc9wjtKqt +m4l2HvMZ8tiykHNfts/3sgbBW9nsev4NwKV60GFOyFUT+W9IpxuO6ghzbsu+vO1f +8768GHa8376Ls1y3ujxfOoP7zQsvfs6JJYeFgzPLTLbA/hPciby9hnQcBrBq0vL9 +iSNdMNvvkgQVlhXMnFSR9YapK0KxV6uVPQCKbyD6vuboVQrmn0+RHgX6adMZd9R/ +SO4xIoBvFFdaZb4IH12rtg7MhP+xonDpewP8fVFSLThMB64AfVPv3zJhgGRYhENd +Yg9+68h98l1BvVHOhuq68/PGeYnWbiNXOwKonBuSDGgekSu3EaixhxWGQd3Irgui +7a4Dij/Mefu6L+ETK+5AByN57nEaeSMJTVtRUQiB9xPVoptWZAi9WJhuEGpzTbK1 +7bYCGItqixQ0aveVJbUMZ8pD2+TNPQltbKWR9rZc5re+Irt/eWIqgxLjHXA3s/5f +DOdz6z0JQ/vjvOOg/q7uxRMG/sbNJrWPTuOh2sncrk+bj9d2V9722PVc9TFMhUfw +UkrqOK1G2fnzanwt/q5uqkeKi1gv1eSFrkJ8d1zcI+fKgbA8LXTNjkW+MliMMxSa +5Gb2wM/c6vFol6tVve4wObac56uOA+uiiOwQLhOz7yjtMS0D1Lwi+GidXwARAQAB +tENDYWdlYnJlYWsgU2lnbmluZyBLZXkgMTQgPGNhZ2VicmVha19zaWduaW5nX2tl +eV8xNEBwcm9qZWN0LXJlcG8uY28+iQJXBBMBCABBFiEEgTct24EkNJ8DA7d0SNfi +7jND46oFAmWUZeUCGwMFCQHhM4AFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AA +CgkQSNfi7jND46qcWBAAoh34oV5jcPyGy/6eMfnptIOY4aYbFTO/oS36fBUwXVUS +TFJfNYuEJU/z5DBU7Lm3DaAnXHQj9lz0Tuh82b27Gk9ALxZtZTQDlyj1tIg+BlZP +uSN+mPlvsg8ZVISYnB/vzs/2svL8R0DZcACWrPkDV2U1zPhPbMe2MURv1Zhqpjqn +j/uGz7jtSFFbs2QqEqW7KG3DDeAbdK6PnVVEsbnDI203ECBwpR+JidI8l5NY+tcF +ENqIoqZa03FasJWeO1AgcmMwfvZfAro/arUVnxeo85WLeF5uF/IdJo1jRTAucac0 +WME0wB4pqMQ0Q8Snb80oD749g2iwtw8gKhmGhBrT0CtrTQqcsA4r1ITBtF+0vi9j +FCzgwLM15GYGGetDEql9IL7RSpZJKKqvm7o3qxOBFIMsOmVaQl1VmuwB9GDGERad +cuPQlVYodPkB816h98Xmv2OgTAoaczKRESQy+qgY6uwvjESX9ltl0mBvruGxMe6E +SiW52TPjGPaKP8WLXb2OznIiLQnofVPR0KBPNNOfIWPz16E3Due3SYPQwbPwglYR +AI65v1fHK3WCeBR6mi/bwyajDyn0PQYQvUGyxGRSGu6ljuI0CkElHtX625zIHPkL +Zjnb/uKW8HXlgLF8fk8g41SCdfYEfhOxxm/165PVSuoN5W7JjZqheS5t7bCzzEeJ +AjMEEAEIAB0WIQROgscsaz5Yp7xP+FVJCfhMqDu4ZwUCZZV7HgAKCRBJCfhMqDu4 +ZworD/9FOYMpaSkU9qAJQCvsLIcAO68FDOphmnDvJBN7P3aAT9iKsKLlgzXb/RSN +gC0kQ/dh7CvhXNsGHbtb9A7bngKgb4SaIw9Rot/m/z4AJ7Ihj8llJBz0T5a79njQ +VQjm3RDOfPHB59mhG7OS3kJJCIZzN+PWJIDrajb0XMaJLifYDMXqKsw5ma+xpU4b +Ox2PC6rOmi05x35Y+SyXMrUeqia5sHeVby33ropk4BIGq7KIf5kwzVXC9/4aPZlb +aBBDhoDYHjoUBvt9GS1CzImutq0q9Ofkwx6msqbz5HSLoK58J7IktrgwVxLK1XHr +wx860zPPef6gk9YgJYUJ6QjzigMV8gB5X3sExB4GF7Xtg92dtGKFsZeqG+NflVhe ++9zjrDFTCPYOoPEIZUg9JBFkRongJ5xzK/wx0GXMqfrMJACSSxuWKz+iIA6bYIhW +ayg0cX5uaLdKhZvpK8DcmpAwHMWe8tiRP6BgK6x90aVFXOBhZF4jVW/sZgPEUQUx +YZfKrm3Ezn9cbBNlg7VQ1rUd3pCvDe0lz+TzsjgMDrLQtTe/FHLFshm+XD/TliZ/ +sQzz+IGsTu0UAdZFhWn1wq0SaNh3hxpm1GOa51KXWxoiF1ym/nFySvN3zj471WBB +IEAl451qfJRzIiaeRGU26JqY5LGzMaMDGXgDAKgt1w2v4Fa5lYkCMwQQAQgAHRYh +BFrrGi6w0T9n4wasWdwMyBvgBv2FBQJllXtOAAoJENwMyBvgBv2FZ70QAI184liO +BT1ZQ3ZsFRD0+kxptxZ4KKPstSiNYCwYSuQNL37HCFa5kDmdyoQr0Mvtj0ohjbNw +ZQ00cb/nDwXwjk6dhVkuv7ijbh6akKOs7yjzHTxdKUCh+ESZD3kwzSzjO2ccsTn/ +nQqt9rmjxpJSvim6Qc5jlT4WbFNseTYFmyeNYnRtbuJKgXyT3FNfJ2XqkP/Kzvv/ +32uKcVn9Sw4Ab4gpEo5f/ti0iYQBhC5w7T8AGQ+WkaqVg3bWdrJt5qUhRdLqDdON +OoTGQ9JDfUFk9JPrDdIeZfHYK2cOmn48gIj26zDgEarDgJSGhIHoniP4HvGCpu42 +fUmgBAzTutD29p56umVVX7qt8eZmmf7Vwcu3vYHlxrXDcPaOd7PCHmI4OvXXAc3X +SKPlCXWf1Amklj2kkPFJplt8SECI+7j0gaSSWriH50y5pOlFmTWpxFlr3ratYsn9 +ZRJ4TA+/xVJTyrcbCfsdsxHc3vIYCC1vz7OuKKn8YqobSHdkmfUPZqw5ZCS3BBfC +zQMoX8qLUwSonGFLMkZZa17n8VV6GaykSRfyJMjEkcDLGhDqsK/izcR9fLvNYmt9 +lyjjCdrfWLyTvKC8lCCvuY0G2Woeh+Q+R3TTfA09hbBiFTOuHTgSzx4ek8Xq4SFg +O1ifhT8ao4V0tA2HyEJtjR+M9YZvU2LJvRniuQINBGWUZeUBEADjNBP2cMphSo5i +Zu2Iad978vaciU1Dpw4BPixLLbN7B9v2wH+2mLXNQ5tyKTuLrEvGl4R6exNIcDTv +wWKwM8tF+CSQGZ/mP359bwz+ZUGSpOfuu/l3jF2Ka0mspJQbc2s75fGfv6LkCRDO +qUya53MIZN6o0kIJr60tS5C/qpzv35qke7g5uvxgYhut4MPZj1hOxYJRKO3hm3tN +Uo6swVHaJG05Hy9U1tJ1BQGDH0xpR0H6GIdQAHoF5X4owfxwEKfv/SKy/8/XnPng +AFkR4YY1/cwSHdX8xu/86bgFPy+eUU0w0PKs93/Qgn0FQzQ+KU1GZyG4oWGuA6RM +2CwzMFoxdn1Omj9raYQwlK4MZJFXDYtiSUYXAPO271nCbg09T2uTmuYTYvusJEj/ +aifFKWPrJz1VanOA7dIgUMUQmAVaxZlfDxTN9+qmnNbTUBM9yEp63nmBxyht9EGq +RSxNBrBhO2MNpNjTm2tzrGbT7UU7cJsDalvVT+4s+Q0bU9caUnaDTNAK31cRMFK5 +zNhB2GPADdLGDYWk9YeEKIlAOPTZghDG3rMs+lb4Itv6TRfv8ymj7AtGWMpOghdN +hIuaE0PX6XIYyu8JXoxPu9jGN6dXOEsxwDrBfSVgdeoV4B2KMf24P/p/XBOBSSqu +q5ZhyBVfhfdX6n8zMoXKCiF/LY20RQARAQABiQI8BBgBCAAmFiEEgTct24EkNJ8D +A7d0SNfi7jND46oFAmWUZeUCGwwFCQHhM4AACgkQSNfi7jND46rMIA//QS+1v6bw +C0CZa1284hBxqfsU6hQnIV45CQ2S3tUtyfKf6QchKSLPSKSN7A3ywuKyGQwmWTzW +L2JQY9G9DzlrgaiRMC13594VtDka0sLXq9aZEKTkcO5MXtjDKVsXjlJ5Z5NhYrjl +C+UFU/GxQk7h8+DW9xSrm9HpVrwF5XWAs7cHrCmFnp90cNJysMzP6WjBaSRksPF1 +Ji1a281luUYwX6mxlKumAEPBj+TyRJVyYaAY2lpJjG78NNyFnLRFCjCBNj784r9C +5VEHG4w3lzzMfBXLRBU3+YWFsG9XBB5f6ThTr4+iCmupxY1RdWl0kMS0J818lVdd +G4ZibmEmOdAXs0dQdZZD1LGrzlgH4+xkCT7D65Pd6YFrhdVsRleYdCGNbP1NSaZy +hYP2rzDt+VV8AUgstscDkvoHWDM0WgueIKQaBVaqp3HOlQ/av9RWglxGlfJlBaWd +1AU9vOj7W48IKfoxIqByxeUWpTV2C+pMkToDLDd3giWtlu6fhUwn/bwvl4QVnJ+S +ICUtM1K2xPymTSrajBnkqTin8HOIigAiFo6RyvSv0XD6IQc43y0UnaYDZH7GpF1Z +6M9mgn15INWAc8kzI/NV1MsRAiRDCixL7gO0dAGZueCO7MgLiGpQB/6dLK8ETfHm +2rpj+N0DJVi3/r0GWYgBEzvO+yV1ly011sk= +=AVO4 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/libinput.c b/libinput.c index e980060..b6244aa 100644 --- a/libinput.c +++ b/libinput.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #include "input.h" @@ -219,7 +219,7 @@ output_by_name_or_id(const char *name_or_id, struct cg_server *server) { char identifier[128]; output_get_identifier(identifier, sizeof(identifier), output); if(strcasecmp(identifier, name_or_id) == 0 || - strcasecmp(output->wlr_output->name, name_or_id) == 0) { + strcasecmp(output->name, name_or_id) == 0) { return output; } } diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index d5b4969..ee68d72 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,8 +1,8 @@ -cagebreak-config(5) "Version 2.2.3" "Cagebreak Manual" +cagebreak-config(5) "Version 2.3.0" "Cagebreak Manual" # NAME -*cagebreak-config* — Cagebreak configuration file +*cagebreak-config* Cagebreak configuration file # SYNOPSIS @@ -17,9 +17,8 @@ are parsed sequentially but independently from the rest of the file. Each line starting with a "#" is a comment. -Note that nesting of commands is limited to 50 times, though lines -are arbitrarily long in practice, though a reasonable limit of 4Mb has -been set. +Note that nesting of commands is limited to 50 times. +Lines are arbitrarily long in practice, though a reasonable limit of 4Mb has been set. See *KEY DEFINITIONS* for details on modifier keys and *MODES* for details on modes. @@ -29,8 +28,8 @@ on modes. *abort* Return to default mode -*background * - Set RGB of background - <[r|g|b]> are floating point numbers +*background * + Set RGB of background - <[r|g|b]\> are floating point numbers between 0 and 1. There is no support for background images. @@ -39,8 +38,8 @@ on modes. background 1.0 0.0 0.0 ``` -*bind * - Bind to execute if pressed in root mode +*bind * + Bind to execute if pressed in root mode ``` bind @@ -52,15 +51,17 @@ definekey root Close current window - This may be useful for windows of applications which do not offer any method of closing them. -*configure_message [font |[f|b]g_color b> |display_time ]* +*configure_message [font |[f|b]g_color |display_time |anchor ]* Configure message characteristics - - - font sets - - is - - X core font description or - - FreeType font description via pango - - fg_color sets RGBA of foreground - - bg_color sets RGBA of background - - display_time sets display time in seconds + - font sets the font of the message. + Here, is either + - an X core font description or + - a FreeType font description via pango + - fg_color sets the RGBA of the foreground + - bg_color sets the RGBA of the background + - display_time sets the display time in seconds + - anchor sets the position of the message. + may be one of {top,bottom}\_{left,center,right} or center. ``` # Set font @@ -85,20 +86,20 @@ configure_message display_time 4 This simply hides the cursor. Pointing and clicking is still possible. -*custom_event * +*custom_event * Send a custom event to the IPC socket This sends an event of type "custom_event" to all programs - listening to the IPC socket along with the string . + listening to the IPC socket along with the string . See *cagebreak-socket(7)* for more details. -*definekey * - Bind to execute if pressed in - +*definekey * + Bind to execute if pressed in - *definekey* is a more general version of *bind*. -*definemode * - Define new mode - After a call to *definemode*, - can be used with *definekey* to create a custom key mapping. +*definemode * + Define new mode - After a call to *definemode*, + can be used with *definekey* to create a custom key mapping. ``` # define new mode and create a mapping for it @@ -109,8 +110,8 @@ definekey foo C-t abort *dump* Triggers the *dump* event, see *cagebreak-socket(7)* for details -*escape * - Set to switch to root mode to execute one command +*escape * + Set to switch to root mode to execute one command ``` escape @@ -130,8 +131,8 @@ definekey top mode root *exchangeup* Exchange current window with window in the tile to the top -*exec * - Execute using *sh -c* +*exec * + Execute using *sh -c* *focus* Focus next tile @@ -154,10 +155,10 @@ definekey top mode root *hsplit* Split current tile horizontally -*input * - Set to for device - - can be "\*" (wildcard), of the form - "type:" or the identifier of the device as printed +*input * + Set to for device - + can be "\*" (wildcard), of the form + "type:" or the identifier of the device as printed for example by *cagebreak -s*. The supported input types are - touchpad - pointer @@ -174,7 +175,7 @@ definekey top mode root *accel_profile adaptive|flat* Set pointer acceleration profile for specified input device - *calibration_matrix <6 space-separated floating point values>* + *calibration_matrix <6 space-separated floating point values\>* Set calibration matrix *click_method none|button_areas|clickfinger* @@ -207,26 +208,26 @@ definekey top mode root Enable or disable natural (inverted) scrolling for specified input device - *pointer_accel [<-1|1>]* + *pointer_accel [<-1|1\>]* Change the pointer acceleration for specified input device - *scroll_button disable|* + *scroll_button disable|* Set button used for scroll_method on_button_down - The button can be given as an event name or code, which can be obtained from *libinput debug-events*. If set to _disable_, it disables the scroll_method on_button_down. - *scroll_factor * + *scroll_factor * Change the scroll factor for the specified input device - Scroll speed will be scaled by the given value, which must be non-negative. *scroll_method none|two_finger|edge|on_button_down* Change scroll method for specified input device - *repeat_delay * + *repeat_delay * Repeat delay in ms for keyboards only - *repeat_rate * + *repeat_rate * Repeat rate in 1/s for keyboards only *tap enabled|disabled* @@ -238,11 +239,11 @@ definekey top mode root middle click. _lmr_ treats 1 finger as left click, 2 fingers as middle click, and 3 fingers as right click. -message +message Display a line of arbitrary text. -*mode * - Enter mode "" - Returns to default mode, after a command is +*mode * + Enter mode "" - Returns to default mode, after a command is executed. *movetonextscreen* @@ -253,12 +254,12 @@ message Move currently focused window to previous screen See *output* for differences between screen and output. -*movetoscreen * - Move currently focused window to -th screen +*movetoscreen * + Move currently focused window to -th screen See *output* for differences between screen and output. -*movetoworkspace * - Move currently focused window to -th workspace +*movetoworkspace * + Move currently focused window to -th workspace See *output* for differences between screen and output. *next* @@ -271,23 +272,32 @@ message *only* Remove all splits and make current window fill the entire screen -*output [[pos res x rate [scale ]] | enable | disable | prio | rotate ]* - Configure output "" - - - and are the position of the +*output [[pos res x rate [scale ]] | enable | disable | [permanent|peripheral] | prio | rotate ]* + Configure output "" - + - and are the position of the monitor in pixels. The top-left monitor should have the coordinates 0 0. - - and specify the resolution in pixels. - - sets the refresh rate of the monitor (often this is 50 or 60). - - sets the output scale (default is 1.0) - - enable and disable enable or disable . Note that if - is the only enabled output, *output disable* has + - and specify the resolution in pixels. + - sets the refresh rate of the monitor (often this is 50 or 60). + - sets the output scale (default is 1.0) + - enable and disable enable or disable . Note that if + is the only enabled output, *output disable* has no effect. - - prio is used to set the priority of an output. If + - permanent sets to persist even on disconnect. When + the physical monitor is disconnected, the output is + maintained and operates identically to the attached monitor. On reconnect, + the monitor operates as though it was never disconnected. Setting the + output role to peripheral when the monitor is disconnected, + destroys the output, as if the monitor were disconnected. + - peripheral sets the role of to peripheral, meaning that on + disconnecting the respective monitor, all views will be moved to another + available output. The default role is peripheral. + - prio is used to set the priority of an output. If nothing else is set, outputs are added as they request to be added - and have a numerical priority of -1. Using prio it is possible - to set priorities for outputs, where >= 1. The larger is, + and have a numerical priority of -1. Using prio it is possible + to set priorities for outputs, where >= 1. The larger is, the higher the priority is, that is to say, the earlier the output will appear in the list of outputs. - - rotate is used to rotate the output by ` mod 4 x 90` degrees + - rotate is used to rotate the output by ` mod 4 x 90` degrees counter-clockwise. ``` @@ -333,19 +343,19 @@ output DP-1 rotate 3 *resizeup* Resize current tile towards the top -*screen * - Change to -th screen +*screen * + Change to -th screen See *output* for differences between screen and output. *show_info* Display information about the current setup - In particular, print the identifiers of the available inputs and outputs. -*setmode * - Set default mode to +*setmode * + Set default mode to -*switchvt * - Switch to tty +*switchvt * + Switch to tty *time* Display time @@ -353,11 +363,11 @@ output DP-1 rotate 3 *vsplit* Split current tile vertically -*workspace * - Change to -th workspace +*workspace * + Change to -th workspace -*workspaces * - Set number of workspaces to - is a single integer larger than 1 +*workspaces * + Set number of workspaces to - is a single integer larger than 1 and less than 30. # MODES @@ -386,7 +396,7 @@ Keys are specified by their names as displayed for example by *xev*. Modifiers can be specified using the following syntax: - - + - The supported modifiers are: @@ -398,7 +408,7 @@ The supported modifiers are: *S - Shift* -*2 - Mod2* +*2 - Mod 2* *3 - Mod 3* @@ -425,14 +435,12 @@ Mail contact: `cagebreak @ project-repo . co` GPG Fingerprints: -- B15B92642760E11FE002DE168708D42451A94AB5 -- F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C -- 3ACEA46CCECD59E4C8222F791CBEB493681E8693 - 0A268C188D7949FEB39FD1462F2AD980247E4918 +- 283D10F54201B0C6CCEE2C561DE04E4B056C749D # LICENSE -Copyright (c) 2020-2023 The Cagebreak authors +Copyright (c) 2020-2024 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index 19365d6..ed47f05 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,8 +1,8 @@ -cagebreak-socket(7) "Version 2.2.3" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.3.0" "Cagebreak Manual" # NAME -*cagebreak-socket* — Cagebreak socket +*cagebreak-socket* Cagebreak socket # SYNOPSIS @@ -30,7 +30,10 @@ Here is an example of how this works using *only* as a command sent over the soc ``` only -cg-ipc{"event_name":"fullscreen","tile_id":2,"workspace":1,"output":"eDP-1"} +cg-ipc{"event_name":"fullscreen", +"tile_id":2, +"workspace":1, +"output":"eDP-1"} ``` This documentation describes the trigger for the events, the keys and the data @@ -45,7 +48,9 @@ type of the values of each event. ``` background 0 1.0 0 -cg-ipc{"event_name":"background","old_bg":[0.000000,1.000000,1.000000],"new_bg":[0.000000,1.000000,0.000000]} +cg-ipc{"event_name":"background", +"old_bg":[0.000000,1.000000,1.000000], +"new_bg":[0.000000,1.000000,0.000000]} ``` *close* @@ -61,7 +66,13 @@ cg-ipc{"event_name":"background","old_bg":[0.000000,1.000000,1.000000],"new_bg": ``` close -cg-ipc{"event_name":"close","view_id":47,"view_pid":30456,"tile_id":47,"workspace":1,"output":"eDP-1","output_id":1} +cg-ipc{"event_name":"close", +"view_id":47, +"view_pid":30456, +"tile_id":47, +"workspace":1, +"output":"eDP-1", +"output_id":1} ``` *configure_input* @@ -110,7 +121,13 @@ cg-ipc{"event_name":"configure_output","output":"eDP-1","output_id":1} ``` # Cursor switches tile -cg-ipc{"event_name":"cursor_switch_tile","old_output":"eDP-1","old_output_id":1,"old_tile":2,"new_output":"eDP-1","new_output_id":1,"new_tile":3} +cg-ipc{"event_name":"cursor_switch_tile", +"old_output":"eDP-1", +"old_output_id":1, +"old_tile":2, +"new_output":"eDP-1", +"new_output_id":1, +"new_tile":3} ``` *custom_event* @@ -136,7 +153,12 @@ cg-ipc{"event_name":"custom_event","message":"Hello World!"} ``` nextscreen -cg-ipc{"event_name":"cycle_outputs","old_output":"eDP-1","old_output_id":1,"new_output":"HDMI-A-1","new_output_id":2,"reverse":0} +cg-ipc{"event_name":"cycle_outputs", +"old_output":"eDP-1", +"old_output_id":1, +"new_output":"HDMI-A-1", +"new_output_id":2, +"reverse":0} ``` *cycle_views* @@ -154,7 +176,15 @@ cg-ipc{"event_name":"cycle_outputs","old_output":"eDP-1","old_output_id":1,"new_ ``` next -cg-ipc{"event_name":"cycle_views","old_view_id":11,"old_view_pid":32223,"new_view_id":4,"old_view_pid";53221,"tile_id":13,"workspace":1,"output":"eDP-1","output_id":1} +cg-ipc{"event_name":"cycle_views", +"old_view_id":11, +"old_view_pid":32223, +"new_view_id":4, +"old_view_pid";53221, +"tile_id":13, +"workspace":1, +"output":"eDP-1", +"output_id":1} ``` *definekey* @@ -220,12 +250,20 @@ cg-ipc{"event_name":"destroy_output","output":"HDMI-A-1","output_id":2} - curr_output: current output as a string - default_mode: name of the default mode as a string - modes: list of names of modes as strings + - message_config: the current configuration of the cagebreak messages + - font: the font used to display the messages + - display_time: the duration in seconds that the cagebreak messages are displayed + - bg_color: list of four floating point numbers denoting the background color in rgba + - fg_color: list of four floating point numbers denoting the foreground color in rgba + - anchor: the positioning of the messages on the screen (see *cagebreak-config(5)* for more information) - outputs: object of objects for each output - output name as string - priority: priority as per *output* prio in *cagebreak-config(5)* or default - coords: object of x and y coordinates of output - size: object of width and height as integers - refresh_rate: refresh rate as float + - permanent: 0 if peripheral, 1 if permanent + - active: 1 if the output is active, 0 if not - curr_workspace: current workspace as an integer - workspaces: list of objects for each workspace - views: list of objects for each view @@ -258,11 +296,18 @@ cg-ipc{"event_name":"dump","nws":1, "curr_output":"eDP-1", "default_mode":"top", "modes":["top","root","resize"], -"outputs": {"eDP-1": { +"message_config": {"font": "pango:Monospace 10", +"display_time": 2, +"bg_color": [0.900000,0.850000,0.850000,1.000000], +"fg_color": [0.000000,0.000000,0.000000,1.000000], +"anchor": "top_right" +},"outputs": {"eDP-1": { "priority": -1, "coords": {"x":0,"y":0}, "size": {"width":2560,"height":1440}, "refresh_rate": 60.012000, +"permanent": 0, +"active": 1, "curr_workspace": 0, "workspaces": [{"views": [{ "id": 16, @@ -351,7 +396,12 @@ cg-ipc{"event_name":"dump","nws":1, ``` focus -cg-ipc{"event_name":"focus_tile","old_tile_id":14,"new_tile_id":13,"workspace":1,"output":"eDP-1","output_id":1} +cg-ipc{"event_name":"focus_tile", +"old_tile_id":14, +"new_tile_id":13, +"workspace":1, +"output":"eDP-1", +"output_id":1} ``` *fullscreen* @@ -365,7 +415,11 @@ cg-ipc{"event_name":"focus_tile","old_tile_id":14,"new_tile_id":13,"workspace":1 ``` only -cg-ipc{"event_name":"fullscreen","tile_id":3,"workspace":1,"output":"eDP-1","output_id":1} +cg-ipc{"event_name":"fullscreen", +"tile_id":3, +"workspace":1, +"output":"eDP-1", +"output_id":1} ``` *move_view_to_cycle_output* @@ -381,8 +435,17 @@ cg-ipc{"event_name":"fullscreen","tile_id":3,"workspace":1,"output":"eDP-1","out ``` movetonextscreen -cg-ipc{"event_name":"cycle_outputs","old_output":"eDP-1","new_output":"HDMI-A-1","reverse":0} -cg-ipc{"event_name":"move_view_to_cycle_output","view_id":11,"view_pid":43123,"old_output":"eDP-1","old_output_id":1,"new_output":"HDMI-A-1","new_output_id":2} +cg-ipc{"event_name":"cycle_outputs", +"old_output":"eDP-1", +"new_output":"HDMI-A-1", +"reverse":0} +cg-ipc{"event_name":"move_view_to_cycle_output", +"view_id":11, +"view_pid":43123, +"old_output":"eDP-1", +"old_output_id":1, +"new_output":"HDMI-A-1", +"new_output_id":2} ``` *move_view_to_output* @@ -395,8 +458,13 @@ cg-ipc{"event_name":"move_view_to_cycle_output","view_id":11,"view_pid":43123,"o ``` movetoscreen 2 -cg-ipc{"event_name":"switch_output","old_output":"eDP-1","new_output":"HDMI-A-1"} -cg-ipc{"event_name":"move_view_to_output","view_id":78,"old_output":"eDP-1","new_output":"HDMI-A-1"} +cg-ipc{"event_name":"switch_output", +"old_output":"eDP-1", +"new_output":"HDMI-A-1"} +cg-ipc{"event_name":"move_view_to_output", +"view_id":78, +"old_output":"eDP-1", +"new_output":"HDMI-A-1"} ``` *move_view_to_ws* @@ -412,8 +480,17 @@ cg-ipc{"event_name":"move_view_to_output","view_id":78,"old_output":"eDP-1","new ``` movetoworkspace 1 -cg-ipc{"event_name":"switch_ws","old_workspace":1,"new_workspace":1,"output":"eDP-1"} -cg-ipc{"event_name":"move_view_to_ws","view_id":43,"old_workspace":0,"new_workspace":0,"output":"eDP-1","output_id":1,"view_pid":64908} +cg-ipc{"event_name":"switch_ws", +"old_workspace":1, +"new_workspace":1, +"output":"eDP-1"} +cg-ipc{"event_name":"move_view_to_ws", +"view_id":43, +"old_workspace":0, +"new_workspace":0, +"output":"eDP-1", +"output_id":1, +"view_pid":64908} ``` *new_output* @@ -442,8 +519,19 @@ cg-ipc{"event_name":"new_output","output":"HDMI-A-1","output_id":2,"priority":-1 ``` resizeleft -cg-ipc{"event_name":"resize_tile","tile_id":14,"old_dims":"[1280,0,1440,1280]","new_dims":"[1270,0,1440,1290]","workspace":1,"output":"eDP-1","output_id":1} -cg-ipc{"event_name":"resize_tile","tile_id":13,"old_dims":"[0,0,1440,1280]","new_dims":"[0,0,1440,1270]","workspace":1,"output":"eDP-1","output_id":1} +cg-ipc{"event_name":"resize_tile", +"tile_id":14, +"old_dims":"[1280,0,1440,1280]", +"new_dims":"[1270,0,1440,1290]", +"workspace":1,"output":"eDP-1", +"output_id":1} +cg-ipc{"event_name":"resize_tile", +"tile_id":13, +"old_dims":"[0,0,1440,1280]", +"new_dims":"[0,0,1440,1270]", +"workspace":1, +"output":"eDP-1", +"output_id":1} ``` *set_nws* @@ -471,7 +559,13 @@ cg-ipc{"event_name":"set_nws","old_nws":1,"new_nws":2} ``` hsplit -cg-ipc{"event_name":"split","tile_id":11,"new_tile_id":12,"workspace":1,"output":"eDP-1","output_id":1,"vertical":0} +cg-ipc{"event_name":"split", +"tile_id":11, +"new_tile_id":12, +"workspace":1, +"output":"eDP-1", +"output_id":1, +"vertical":0} ``` *swap_tile* @@ -488,7 +582,13 @@ cg-ipc{"event_name":"split","tile_id":11,"new_tile_id":12,"workspace":1,"output" ``` exchangeright -cg-ipc{"event_name":"swap_tile","tile_id":1,"tile_pid":53478,"swap_tile_id":3,"swap_tile_pid":98234,"workspace":1,"output":"eDP-1"} +cg-ipc{"event_name":"swap_tile", +"tile_id":1, +"tile_pid":53478, +"swap_tile_id":3, +"swap_tile_pid":98234, +"workspace":1, +"output":"eDP-1"} ``` *switch_default_mode* @@ -514,7 +614,11 @@ switch_output ``` screen 2 -cg-ipc{"event_name":"switch_output","old_output":"eDP-1","old_output_id":1,"new_output":"HDMI-A-1","new_output_id":2} +cg-ipc{"event_name":"switch_output", +"old_output":"eDP-1", +"old_output_id":1, +"new_output":"HDMI-A-1", +"new_output_id":2} ``` switch_ws @@ -528,7 +632,11 @@ switch_ws ``` workspace 2 -cg-ipc{"event_name":"switch_ws","old_workspace":1,"new_workspace":2,"output":"eDP-1","output_id":1} +cg-ipc{"event_name":"switch_ws", +"old_workspace":1, +"new_workspace":2, +"output":"eDP-1", +"output_id":1} ``` *view_map* @@ -544,7 +652,13 @@ cg-ipc{"event_name":"switch_ws","old_workspace":1,"new_workspace":2,"output":"eD ``` # process opens a view -cg-ipc{"event_name":"view_map","view_id":28,"tile_id":14,"workspace":1,"output":"eDP-1","output_id":1,"view_pid":39827} +cg-ipc{"event_name":"view_map", +"view_id":28, +"tile_id":14, +"workspace":1, +"output":"eDP-1", +"output_id":1, +"view_pid":39827} ``` *view_unmap* @@ -560,7 +674,13 @@ cg-ipc{"event_name":"view_map","view_id":28,"tile_id":14,"workspace":1,"output": ``` # view is closed by the process -cg-ipc{"event_name":"view_unmap","view_id":24,"tile_id":13,"workspace":1,"output":"eDP-1","output_id":1,"view_pid":39544} +cg-ipc{"event_name":"view_unmap", +"view_id":24, +"tile_id":13, +"workspace":1, +"output":"eDP-1", +"output_id":1, +"view_pid":39544} ``` ## SECURITY @@ -590,14 +710,12 @@ Mail contact: `cagebreak @ project-repo . co` GPG Fingerprints: -- B15B92642760E11FE002DE168708D42451A94AB5 -- F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C -- 3ACEA46CCECD59E4C8222F791CBEB493681E8693 - 0A268C188D7949FEB39FD1462F2AD980247E4918 +- 283D10F54201B0C6CCEE2C561DE04E4B056C749D # LICENSE -Copyright (c) 2022 - 2023 The Cagebreak authors +Copyright (c) 2022 - 2024 The Cagebreak authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index bdd469f..4dfd854 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.2.3" "Cagebreak Manual" +cagebreak(1) "Version 2.3.0" "Cagebreak Manual" # NAME @@ -28,7 +28,7 @@ socket specified in the environment variable *\$CAGEBREAK_SOCKET*. The syntax accepted through this socket is identical to that of the configuration file (see *cagebreak-config(5)*). Errors which occur during interaction over IPC channel -are displayed in a message box at the top right of the screen. +are displayed in a message box on the screen. # OPTIONS @@ -87,14 +87,12 @@ Mail contact: `cagebreak @ project-repo . co` GPG Fingerprints: -- B15B92642760E11FE002DE168708D42451A94AB5 -- F8DD9F8DD12B85A28F5827C4678E34D2E753AA3C -- 3ACEA46CCECD59E4C8222F791CBEB493681E8693 - 0A268C188D7949FEB39FD1462F2AD980247E4918 +- 283D10F54201B0C6CCEE2C561DE04E4B056C749D # LICENSE -Copyright (c) 2020-2023 The Cagebreak authors +Copyright (c) 2020-2024 The Cagebreak authors Copyright (c) 2018-2020 Jente Hidskes diff --git a/manuals.md b/manuals.md new file mode 100644 index 0000000..dd5f84b --- /dev/null +++ b/manuals.md @@ -0,0 +1,5 @@ +# Cagebreak Manuals + + * [cagebreak-config (5)](man/cagebreak-config.5.md) (probably, what you are looking for, commands etc.) + * [cagebreak (1)](man/cagebreak.1.md) (command line arguments, environment variables etc.) + * [cagebreak-socket (7)](man/cagebreak-socket.7.md) (mostly useful for scripting, socket information) diff --git a/meson.build b/meson.build index aeb3346..b0b458d 100644 --- a/meson.build +++ b/meson.build @@ -1,9 +1,9 @@ -# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# Copyright 2020 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT project( 'cagebreak', 'c', -version : '2.2.3', +version : '2.3.0', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -204,12 +204,12 @@ reproducible_build_versions = { 'wayland_server': '1.19.0', 'wayland_client': '1.22.0', 'wayland_cursor': '1.22.0', - 'wlroots': '0.17.0', + 'wlroots': '0.17.1', 'xkbcommon': '1.6.0', - 'fontconfig': '2.14.2', - 'libinput': '1.24.0', + 'fontconfig': '2.15.0', + 'libinput': '1.25.0', 'libevdev': '1.13.1', - 'libudev': '254', + 'libudev': '255', 'pango': '1.51.0', 'cairo': '1.18.0', 'pangocairo': '1.51.0', @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1701768836 + secssinceepoch = 1706213605 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') @@ -371,12 +371,16 @@ run_target('create-artefacts', # Test Suite test('Build without warnings', find_program('test/build-w-o-warnings'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Example script header is consistent', find_program('test/script-header'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Script executability is consistent', find_program('test/script-header'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Man page consistency', find_program('test/man-pages'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') test('Build without xwayland', find_program('test/build-w-o-xwayland'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') test('Copyright and LICENSE', find_program('test/copyright-license'), args : [ cagebreak_main_file + cagebreak_source_strings + cagebreak_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()), ''.join('MESONLICENSE=', meson.project_license())], suite: 'devel' ) -test('Clang-format (formatting check)', find_program('test/clang-format'), args : [ cagebreak_main_file + cagebreak_source_strings + cagebreak_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') -test('Shellcheck (script linting)', find_program('test/shellcheck'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Formatting check (clang-format)', find_program('test/clang-format'), args : [ cagebreak_main_file + cagebreak_source_strings + cagebreak_header_strings + fuzz_sources + fuzz_headers + fuzz_override_lib ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Script linting (shellcheck)', find_program('test/shellcheck'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') test('GPG key validity', find_program('test/gpg-validity'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') -test('Scan-build (static analysis)', find_program('test/scan-build'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel-long') +test('Illegal Strings', find_program('test/illegal-strings'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel') +test('Static analysis (scan-build)', find_program('test/scan-build'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'devel-long') test('Arguments', find_program('test/arguments'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic') test('Environment Variables', find_program('test/environment-variables'), env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'basic') test('Semantic versioning', find_program('test/versions'), args : [ meson.project_version() ], env : [ ''.join('MESONCURRENTCONFIGDIR=', meson.current_source_dir()) ], suite: 'release') diff --git a/meson_options.txt b/meson_options.txt index eba2f60..a4377b9 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,8 +1,8 @@ -# Copyright 2020 - 2023, project-repo and the cagebreak contributors +# Copyright 2020 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT option('xwayland', type: 'boolean', value: 'false', description: 'Enable support for X11 applications') option('man-pages', type: 'boolean', value: 'false', description: 'Build man pages (requires pandoc)') option('fuzz', type: 'boolean', value: 'false', description: 'Enable building fuzzer targets') option('version_override', type: 'string', description: 'Set the project version to the string specified. Used for creating hashes for reproducible builds.') option('corpus', type: 'string', value: 'fuzz_corpus', description: 'Set fuzzing corpus directory') -option('gpg_id', type: 'string', value: '4E82C72C6B3E58A7BC4FF8554909F84CA83BB867', description: 'Set gpg signing key for cagebreak') +option('gpg_id', type: 'string', value: '438C27DDB5D174673DF4D67B451205B3528C7C63', description: 'Set gpg signing key for cagebreak') diff --git a/message.c b/message.c index d74b8cf..4b99aaf 100644 --- a/message.c +++ b/message.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #include @@ -174,13 +174,9 @@ create_message_texture(const char *string, const struct cg_output *output) { return buf; } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" -#endif void message_set_output(struct cg_output *output, const char *string, - struct wlr_box *box, enum cg_message_align align) { + struct wlr_box *box, enum cg_message_anchor anchor) { struct cg_message *message = malloc(sizeof(struct cg_message)); if(!message) { wlr_log(WLR_ERROR, "Error allocating message structure"); @@ -202,26 +198,35 @@ message_set_output(struct cg_output *output, const char *string, int height = buf->base.height / scale; message->position->width = width; message->position->height = height; - switch(align) { - case CG_MESSAGE_TOP_RIGHT: { - message->position->x -= width; + switch(anchor) { + case CG_MESSAGE_TOP_LEFT: + message->position->x = 0; + message->position->y = 0; break; - } - case CG_MESSAGE_BOTTOM_LEFT: { + case CG_MESSAGE_TOP_CENTER: + message->position->x -= width / 2; + message->position->y = 0; + break; + case CG_MESSAGE_TOP_RIGHT: + message->position->x -= width; + message->position->y = 0; + break; + case CG_MESSAGE_BOTTOM_LEFT: + message->position->x = 0; message->position->y -= height; break; - } - case CG_MESSAGE_BOTTOM_RIGHT: { + case CG_MESSAGE_BOTTOM_CENTER: + message->position->x -= width / 2; + message->position->y -= height; + break; + case CG_MESSAGE_BOTTOM_RIGHT: message->position->x -= width; message->position->y -= height; break; - } - case CG_MESSAGE_CENTER: { + case CG_MESSAGE_CENTER: message->position->x -= width / 2; message->position->y -= height / 2; break; - } - case CG_MESSAGE_TOP_LEFT: default: break; } @@ -235,17 +240,18 @@ message_set_output(struct cg_output *output, const char *string, wlr_scene_buffer_create(&scene_output->scene->tree, &buf->base); wlr_scene_node_raise_to_top(&message->message->node); wlr_scene_node_set_enabled(&message->message->node, true); - struct wlr_box outp_box; - wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, - &outp_box); wlr_scene_buffer_set_dest_size(message->message, width, height); - wlr_scene_node_set_position(&message->message->node, - message->position->x + outp_box.x, - message->position->y + outp_box.y); + wlr_scene_node_set_position( + &message->message->node, + message->position->x + output_get_layout_box(output).x, + message->position->y + output_get_layout_box(output).y); } void message_printf(struct cg_output *output, const char *fmt, ...) { + if(output->destroyed) { + return; + } va_list ap; va_start(ap, fmt); char *buffer = malloc_vsprintf_va_list(fmt, ap); @@ -261,26 +267,55 @@ message_printf(struct cg_output *output, const char *fmt, ...) { free(buffer); return; } - struct wlr_box output_box; - wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, - &output_box); - - box->x = output_box.width; - box->y = 0; + struct wlr_box output_box = output_get_layout_box(output); box->width = 0; box->height = 0; + switch(output->server->message_config.anchor) { + case CG_MESSAGE_TOP_LEFT: + box->x = 0; + box->y = 0; + break; + case CG_MESSAGE_TOP_CENTER: + box->x = output_box.width / 2; + box->y = 0; + break; + case CG_MESSAGE_TOP_RIGHT: + box->x = output_box.width; + box->y = 0; + break; + case CG_MESSAGE_BOTTOM_LEFT: + box->x = 0; + box->y = output_box.height; + break; + case CG_MESSAGE_BOTTOM_CENTER: + box->x = output_box.width / 2; + box->y = output_box.height; + break; + case CG_MESSAGE_BOTTOM_RIGHT: + box->x = output_box.width; + box->y = output_box.height; + break; + case CG_MESSAGE_CENTER: + box->x = output_box.width / 2; + box->y = output_box.height / 2; + break; + default: + break; + } - message_set_output(output, buffer, box, CG_MESSAGE_TOP_RIGHT); + message_set_output(output, buffer, box, + output->server->message_config.anchor); free(buffer); alarm(output->server->message_config.display_time); } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic pop -#endif void message_printf_pos(struct cg_output *output, struct wlr_box *position, - const enum cg_message_align align, const char *fmt, ...) { + const enum cg_message_anchor anchor, const char *fmt, ...) { + if(output->destroyed) { + free(position); + return; + } uint16_t buf_len = 256; char *buffer = (char *)malloc(buf_len * sizeof(char)); va_list ap; @@ -289,7 +324,7 @@ message_printf_pos(struct cg_output *output, struct wlr_box *position, vsnprintf(buffer, buf_len, fmt, ap); va_end(ap); - message_set_output(output, buffer, position, align); + message_set_output(output, buffer, position, anchor); free(buffer); alarm(output->server->message_config.display_time); } diff --git a/message.h b/message.h index 806307c..a1b8f13 100644 --- a/message.h +++ b/message.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef MESSAGE_H @@ -11,12 +11,15 @@ struct cg_output; struct wlr_box; struct wlr_buffer; -enum cg_message_align { +enum cg_message_anchor { CG_MESSAGE_TOP_LEFT, + CG_MESSAGE_TOP_CENTER, CG_MESSAGE_TOP_RIGHT, CG_MESSAGE_BOTTOM_LEFT, + CG_MESSAGE_BOTTOM_CENTER, CG_MESSAGE_BOTTOM_RIGHT, CG_MESSAGE_CENTER, + CG_MESSAGE_NOPT }; struct cg_message_config { @@ -24,6 +27,7 @@ struct cg_message_config { int display_time; float bg_color[4]; float fg_color[4]; + enum cg_message_anchor anchor; }; struct cg_message { @@ -37,7 +41,7 @@ void message_printf(struct cg_output *output, const char *fmt, ...); void message_printf_pos(struct cg_output *output, struct wlr_box *position, - enum cg_message_align, const char *fmt, ...); + enum cg_message_anchor, const char *fmt, ...); void message_clear(struct cg_output *output); diff --git a/output.c b/output.c index 0a482f0..c048b9b 100644 --- a/output.c +++ b/output.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -14,13 +14,16 @@ #if WLR_HAS_X11_BACKEND #include #endif +#include #include #include #include +#include #include #include #include #include +#include #include #include #if CG_HAS_XWAYLAND @@ -103,7 +106,7 @@ output_get_num(const struct cg_output *output) { struct cg_output *it; int count = 1; wl_list_for_each(it, &output->server->outputs, link) { - if(strcmp(output->wlr_output->name, it->wlr_output->name) == 0) { + if(strcmp(output->name, it->name) == 0) { return count; } ++count; @@ -111,33 +114,64 @@ output_get_num(const struct cg_output *output) { return -1; } +struct wlr_box +output_get_layout_box(struct cg_output *output) { + struct wlr_box box; + wlr_output_layout_get_box(output->server->output_layout, output->wlr_output, + &box); + if(!output->destroyed && !wlr_box_empty(&box)) { + output->layout_box.x = box.x; + output->layout_box.y = box.y; + output->layout_box.width = box.width; + output->layout_box.height = box.height; + } + return output->layout_box; +} + static void output_destroy(struct cg_output *output) { struct cg_server *server = output->server; - char *outp_name = strdup(output->wlr_output->name); + char *outp_name = strdup(output->name); int outp_num = output_get_num(output); - wl_list_remove(&output->destroy.link); - wl_list_remove(&output->commit.link); - wl_list_remove(&output->frame.link); - - output_clear(output); - - /*Important: due to unfortunate events, "workspace" and "output->workspace" - * have nothing in common. The former is the workspace of a single output, - * whereas the latter is the workspace of the outputs.*/ - for(unsigned int i = 0; i < server->nws; ++i) { - workspace_free(output->workspaces[i]); + if(output->destroyed == false) { + wl_list_remove(&output->destroy.link); + wl_list_remove(&output->commit.link); + wl_list_remove(&output->frame.link); + wlr_scene_output_destroy(output->scene_output); + output->scene_output = NULL; } - free(output->workspaces); + output->destroyed = true; + enum output_role role = output->role; + if(role == OUTPUT_ROLE_PERMANENT) { + output->wlr_output = wlr_headless_add_output(server->headless_backend, + output->layout_box.width, + output->layout_box.height); + output->scene_output = + wlr_scene_output_create(server->scene, output->wlr_output); + struct wlr_output_layout_output *lo = + wlr_output_layout_add(server->output_layout, output->wlr_output, + output->layout_box.x, output->layout_box.y); + wlr_scene_output_layout_add_output(server->scene_output_layout, lo, + output->scene_output); - free(output); + } else { + output_clear(output); + + for(unsigned int i = 0; i < server->nws; ++i) { + workspace_free(output->workspaces[i]); + } + free(output->workspaces); + free(output->name); + + free(output); + } if(outp_name != NULL) { ipc_send_event(server, "{\"event_name\":\"destroy_output\",\"output\":\"%s\"," - "\"output_id\":%d}", - outp_name, outp_num); + "\"output_id\":%d,\"permanent\":%d}", + outp_name, outp_num, role == OUTPUT_ROLE_PERMANENT); free(outp_name); } else { wlr_log(WLR_ERROR, @@ -154,6 +188,27 @@ handle_output_destroy(struct wl_listener *listener, void *data) { output_destroy(output); } +void +handle_output_gamma_control_set_gamma(struct wl_listener *listener, + void *data) { + struct cg_server *server = + wl_container_of(listener, server, gamma_control_set_gamma); + const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; + + struct wlr_gamma_control_v1 *gamma_control = + wlr_gamma_control_manager_v1_get_control(server->gamma_control, + event->output); + + struct wlr_output_state pending = {0}; + wlr_gamma_control_v1_apply(gamma_control, &pending); + if(!wlr_output_test_state(event->output, &pending)) { + wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); + } else { + wlr_output_commit_state(event->output, &pending); + wlr_output_schedule_frame(event->output); + } +} + static void handle_output_frame(struct wl_listener *listener, void *data) { struct cg_output *output = wl_container_of(listener, output, frame); @@ -257,11 +312,24 @@ output_apply_config(struct cg_server *server, struct cg_output *output, struct cg_output_config *config) { struct wlr_output *wlr_output = output->wlr_output; - if(output->wlr_output->enabled) { - wlr_output_layout_remove(server->output_layout, wlr_output); + struct wlr_box prev_box; + prev_box.x = output->layout_box.x; + prev_box.y = output->layout_box.y; + prev_box.width = output->layout_box.width; + prev_box.height = output->layout_box.height; + bool prio_changed = false; + if(config->role != OUTPUT_ROLE_DEFAULT) { + output->role = config->role; + if((output->role == OUTPUT_ROLE_PERIPHERAL) && + (output->destroyed == true)) { + output_destroy(output); + wlr_output_destroy(wlr_output); + return; + } } if(config->priority != -1) { + prio_changed = (output->priority != config->priority); output->priority = config->priority; } @@ -282,18 +350,57 @@ output_apply_config(struct cg_server *server, struct cg_output *output, wlr_output_commit(wlr_output); return; } - struct wlr_output_layout_output *lo = wlr_output_layout_add( - server->output_layout, wlr_output, config->pos.x, config->pos.y); - wlr_scene_output_layout_add_output(server->scene_output_layout, lo, - output->scene_output); - /* Since the size of the output may have changed, we - * reinitialize all workspaces with a fullscreen layout */ - for(unsigned int i = 0; i < output->server->nws; ++i) { - output_make_workspace_fullscreen(output, i); + if(wlr_box_empty(&output->layout_box)) { + struct wlr_output_layout_output *lo = + wlr_output_layout_add(server->output_layout, wlr_output, + config->pos.x, config->pos.y); + wlr_scene_output_layout_add_output(server->scene_output_layout, lo, + output->scene_output); + } else { + wlr_scene_output_set_position(output->scene_output, config->pos.x, + config->pos.y); } - } else { + if(output->workspaces != NULL) { + wlr_output_layout_get_box(server->output_layout, output->wlr_output, + &output->layout_box); + /* Since the size of the output may have changed, we + * reinitialize all workspaces with a fullscreen layout */ + if(output->layout_box.width != prev_box.width || + output->layout_box.height != prev_box.height) { + for(unsigned int i = 0; i < output->server->nws; ++i) { + output_make_workspace_fullscreen(output, i); + } + } + if(prev_box.x != output->layout_box.x || + prev_box.y != output->layout_box.y) { + for(unsigned int i = 0; i < server->nws; ++i) { + struct cg_workspace *ws = output->workspaces[i]; + bool first = true; + for(struct cg_tile *tile = ws->focused_tile; + first || output->workspaces[i]->focused_tile != tile; + tile = tile->next) { + first = false; + if(tile->view != NULL) { + wlr_scene_node_set_position( + &tile->view->scene_tree->node, + tile->view->ox + output->layout_box.x, + tile->view->oy + output->layout_box.y); + } + } + } + } + } + } else if(wlr_box_empty(&output->layout_box)) { + wlr_output_layout_add_auto(server->output_layout, wlr_output); + // The following two lines make sure that the output is "manually" + // managed, so that its position doesn't change anymore in the + // future. + wlr_output_layout_get_box(server->output_layout, output->wlr_output, + &output->layout_box); + wlr_output_layout_remove(server->output_layout, output->wlr_output); struct wlr_output_layout_output *lo = - wlr_output_layout_add_auto(server->output_layout, wlr_output); + wlr_output_layout_add(server->output_layout, output->wlr_output, + output->layout_box.x, output->layout_box.y); wlr_scene_output_layout_add_output(server->scene_output_layout, lo, output->scene_output); @@ -311,8 +418,10 @@ output_apply_config(struct cg_server *server, struct cg_output *output, wlr_output_enable(wlr_output, false); wlr_output_commit(wlr_output); } else { - wl_list_remove(&output->link); - output_insert(server, output); + if(prio_changed) { + wl_list_remove(&output->link); + output_insert(server, output); + } wlr_output_enable(wlr_output, true); wlr_output_commit(wlr_output); } @@ -329,9 +438,8 @@ output_apply_config(struct cg_server *server, struct cg_output *output, output->bg = wlr_scene_rect_create( &scene_output->scene->tree, output->wlr_output->width, output->wlr_output->height, server->bg_color); - struct wlr_box box; - wlr_output_layout_get_box(server->output_layout, output->wlr_output, &box); - wlr_scene_node_set_position(&output->bg->node, box.x, box.y); + wlr_scene_node_set_position(&output->bg->node, scene_output->x, + scene_output->y); wlr_scene_node_lower_to_bottom(&output->bg->node); } @@ -344,6 +452,7 @@ empty_output_config(void) { } cfg->status = OUTPUT_DEFAULT; + cfg->role = OUTPUT_ROLE_DEFAULT; cfg->pos.x = -1; cfg->pos.y = -1; cfg->pos.width = -1; @@ -367,6 +476,11 @@ merge_output_configs(struct cg_output_config *cfg1, } else { out_cfg->status = cfg1->status; } + if(cfg1->role == out_cfg->role) { + out_cfg->role = cfg2->role; + } else { + out_cfg->role = cfg1->role; + } if(cfg1->pos.x == out_cfg->pos.x) { out_cfg->pos.x = cfg2->pos.x; out_cfg->pos.y = cfg2->pos.y; @@ -415,7 +529,7 @@ output_configure(struct cg_server *server, struct cg_output *output) { struct cg_output_config *tot_config = empty_output_config(); struct cg_output_config *config; wl_list_for_each(config, &server->output_config, link) { - if(strcmp(config->output_name, output->wlr_output->name) == 0) { + if(strcmp(config->output_name, output->name) == 0) { if(tot_config == NULL) { return; } @@ -459,9 +573,9 @@ handle_output_commit(struct wl_listener *listener, void *data) { void output_make_workspace_fullscreen(struct cg_output *output, int ws) { struct cg_server *server = output->server; - struct cg_view *current_view = seat_get_focus(server->seat); + struct cg_view *current_view = output->workspaces[ws]->focused_tile->view; - if(current_view == NULL || ws != output->curr_workspace) { + if(current_view == NULL) { struct cg_view *it = NULL; wl_list_for_each(it, &output->workspaces[ws]->views, link) { if(view_is_visible(it)) { @@ -472,7 +586,7 @@ output_make_workspace_fullscreen(struct cg_output *output, int ws) { } workspace_free_tiles(output->workspaces[ws]); - if(full_screen_workspace_tiles(server->output_layout, output->wlr_output, + if(full_screen_workspace_tiles(server->output_layout, output->workspaces[ws], &server->tiles_curr_id) != 0) { wlr_log(WLR_ERROR, "Failed to allocate space for fullscreen workspace"); @@ -484,19 +598,18 @@ output_make_workspace_fullscreen(struct cg_output *output, int ws) { it_view->tile = output->workspaces[ws]->focused_tile; } - if(ws == output->curr_workspace) { + workspace_tile_update_view(output->workspaces[ws]->focused_tile, + current_view); + if((ws == output->curr_workspace) && (output == server->curr_output)) { seat_set_focus(server->seat, current_view); } } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" -#endif void handle_new_output(struct wl_listener *listener, void *data) { struct cg_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; + wlr_output_enable(wlr_output, true); if(!wlr_output_init_render(wlr_output, server->allocator, server->renderer)) { @@ -504,59 +617,102 @@ handle_new_output(struct wl_listener *listener, void *data) { return; } - struct cg_output *output = calloc(1, sizeof(struct cg_output)); - output->scene_output = wlr_scene_output_create(server->scene, wlr_output); + struct cg_output *ito; + bool reinit = false; + struct cg_output *output = NULL; + wl_list_for_each(ito, &server->outputs, link) { + if((strcmp(ito->name, wlr_output->name) == 0) && (ito->destroyed)) { + reinit = true; + output = ito; + } + } + if(reinit) { + wlr_output_layout_remove(server->output_layout, output->wlr_output); + wlr_scene_output_destroy(output->scene_output); + } else { + output = calloc(1, sizeof(struct cg_output)); + } if(!output) { wlr_log(WLR_ERROR, "Failed to allocate output"); return; } + output->scene_output = wlr_scene_output_create(server->scene, wlr_output); output->wlr_output = wlr_output; - output->server = server; - output->last_scanned_out_view = NULL; + output->destroyed = false; - struct cg_output_priorities *it; - int prio = -1; - wl_list_for_each(it, &server->output_priorities, link) { - if(strcmp(output->wlr_output->name, it->ident) == 0) { - prio = it->priority; + if(!reinit) { + output->server = server; + output->name = strdup(wlr_output->name); + + struct cg_output_priorities *it; + int prio = -1; + wl_list_for_each(it, &server->output_priorities, link) { + if(strcmp(output->name, it->ident) == 0) { + prio = it->priority; + } } - } - output->priority = prio; - wlr_output_set_transform(wlr_output, WL_OUTPUT_TRANSFORM_NORMAL); - output->workspaces = NULL; + output->priority = prio; + wlr_output_set_transform(wlr_output, WL_OUTPUT_TRANSFORM_NORMAL); + output->workspaces = NULL; - wl_list_init(&output->messages); + wl_list_init(&output->messages); - if(!wlr_xcursor_manager_load(server->seat->xcursor_manager, - wlr_output->scale)) { - wlr_log(WLR_ERROR, - "Cannot load XCursor theme for output '%s' with scale %f", - wlr_output->name, wlr_output->scale); - } - - output_insert(server, output); - output_configure(server, output); - - output->workspaces = malloc(server->nws * sizeof(struct cg_workspace *)); - for(unsigned int i = 0; i < server->nws; ++i) { - output->workspaces[i] = full_screen_workspace(output); - if(!output->workspaces[i]) { - wlr_log(WLR_ERROR, "Failed to allocate workspaces for output"); - return; + if(!wlr_xcursor_manager_load(server->seat->xcursor_manager, + wlr_output->scale)) { + wlr_log(WLR_ERROR, + "Cannot load XCursor theme for output '%s' with scale %f", + output->name, wlr_output->scale); } - output->workspaces[i]->num = i; - wl_list_init(&output->workspaces[i]->views); - wl_list_init(&output->workspaces[i]->unmanaged_views); + + output_insert(server, output); + // This is duplicated here only as a cue for the static analysis tool + output->destroyed = false; + output_configure(server, output); + wlr_output_layout_get_box(server->output_layout, output->wlr_output, + &output->layout_box); + + output->workspaces = + malloc(server->nws * sizeof(struct cg_workspace *)); + for(unsigned int i = 0; i < server->nws; ++i) { + output->workspaces[i] = full_screen_workspace(output); + if(!output->workspaces[i]) { + wlr_log(WLR_ERROR, "Failed to allocate workspaces for output"); + return; + } + output->workspaces[i]->num = i; + wl_list_init(&output->workspaces[i]->views); + wl_list_init(&output->workspaces[i]->unmanaged_views); + } + + wlr_scene_node_raise_to_top(&output->workspaces[0]->scene->node); + workspace_focus(output, 0); + + /* We are the first output. Set the current output to this one. */ + if(server->curr_output == NULL) { + server->curr_output = output; + } + } else { + struct wlr_output_layout_output *lo = + wlr_output_layout_add(server->output_layout, wlr_output, + output->layout_box.x, output->layout_box.y); + wlr_scene_output_layout_add_output(server->scene_output_layout, lo, + output->scene_output); + + struct wlr_output_mode *preferred_mode = + wlr_output_preferred_mode(wlr_output); + if(preferred_mode) { + wlr_output_set_mode(wlr_output, preferred_mode); + } + wlr_output_set_transform(wlr_output, WL_OUTPUT_TRANSFORM_NORMAL); + wlr_scene_output_set_position( + output->scene_output, output->layout_box.x, output->layout_box.y); + wlr_output_enable(wlr_output, true); + wlr_output_commit(wlr_output); + output_configure(server, output); + output_get_layout_box(output); } - wlr_scene_node_raise_to_top(&output->workspaces[0]->scene->node); - workspace_focus(output, 0); - - /* We are the first output. Set the current output to this one. */ - if(server->curr_output == NULL) { - server->curr_output = output; - } wlr_cursor_set_xcursor(server->seat->cursor, server->seat->xcursor_manager, DEFAULT_XCURSOR); wlr_cursor_warp(server->seat->cursor, NULL, 0, 0); @@ -570,10 +726,7 @@ handle_new_output(struct wl_listener *listener, void *data) { ipc_send_event(server, "{\"event_name\":\"new_output\",\"output\":\"%s\",\"output_" - "id\":%d,\"priority\":%d}", - output->wlr_output->name, output_get_num(output), - output->priority); + "id\":%d,\"priority\":%d,\"restart\":%d}", + output->name, output_get_num(output), output->priority, + reinit); } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic pop -#endif diff --git a/output.h b/output.h index c1d4853..573c259 100644 --- a/output.h +++ b/output.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_OUTPUT_H @@ -12,6 +12,12 @@ struct cg_view; struct wlr_output; struct wlr_surface; +enum output_role { + OUTPUT_ROLE_PERIPHERAL, + OUTPUT_ROLE_PERMANENT, + OUTPUT_ROLE_DEFAULT +}; + struct cg_output { struct cg_server *server; struct wlr_output *wlr_output; @@ -23,9 +29,12 @@ struct cg_output { struct wl_listener frame; struct cg_workspace **workspaces; struct wl_list messages; + struct wlr_box layout_box; int curr_workspace; int priority; - struct cg_view *last_scanned_out_view; + enum output_role role; + bool destroyed; + char *name; struct wl_list link; // cg_server::outputs }; @@ -40,6 +49,7 @@ enum output_status { OUTPUT_ENABLE, OUTPUT_DISABLE, OUTPUT_DEFAULT }; struct cg_output_config { enum output_status status; + enum output_role role; struct wlr_box pos; char *output_name; float refresh_rate; @@ -53,7 +63,8 @@ typedef void (*cg_surface_iterator_func_t)(struct cg_output *output, struct wlr_surface *surface, struct wlr_box *box, void *user_data); - +struct wlr_box +output_get_layout_box(struct cg_output *output); void handle_new_output(struct wl_listener *listener, void *data); void @@ -64,4 +75,8 @@ void output_make_workspace_fullscreen(struct cg_output *output, int ws); int output_get_num(const struct cg_output *output); +void +handle_output_gamma_control_set_gamma(struct wl_listener *listener, void *data); +void +output_insert(struct cg_server *server, struct cg_output *output); #endif diff --git a/pango.c b/pango.c index 3af6f7f..3006f5b 100644 --- a/pango.c +++ b/pango.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #include diff --git a/pango.h b/pango.h index 53a78cc..5aa6c8d 100644 --- a/pango.h +++ b/pango.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef _SWAY_PANGO_H diff --git a/parse.c b/parse.c index c163b3a..72d8295 100644 --- a/parse.c +++ b/parse.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -543,6 +543,10 @@ parse_output_config_keyword(char *key_str, enum output_status *status) { *status = OUTPUT_DEFAULT; } else if(strcmp(key_str, "enable") == 0) { *status = OUTPUT_ENABLE; + } else if(strcmp(key_str, "permanent") == 0) { + *status = OUTPUT_DEFAULT; + } else if(strcmp(key_str, "peripheral") == 0) { + *status = OUTPUT_DEFAULT; } else if(strcmp(key_str, "disable") == 0) { *status = OUTPUT_DISABLE; } else { @@ -566,6 +570,7 @@ parse_output_config(char **saveptr, char **errstr) { cfg->priority = -1; cfg->scale = -1; cfg->angle = -1; + cfg->role = OUTPUT_ROLE_DEFAULT; char *name = strtok_r(NULL, " ", saveptr); if(name == NULL) { *errstr = @@ -574,8 +579,9 @@ parse_output_config(char **saveptr, char **errstr) { } char *key_str = strtok_r(NULL, " ", saveptr); if(parse_output_config_keyword(key_str, &(cfg->status)) != 0) { - *errstr = log_error("Expected keyword \"pos\", \"prio\", \"enable\" or " - "\"disable\" in output configuration for output %s", + *errstr = log_error("Expected keyword \"pos\", \"prio\", \"enable\", " + "\"disable\", \"permanent\" or \"peripheral\" in " + "output configuration for output %s", name); goto error; } @@ -622,6 +628,18 @@ parse_output_config(char **saveptr, char **errstr) { return cfg; } + if(strcmp(key_str, "peripheral") == 0) { + cfg->output_name = strdup(name); + cfg->role = OUTPUT_ROLE_PERIPHERAL; + return cfg; + } + + if(strcmp(key_str, "permanent") == 0) { + cfg->output_name = strdup(name); + cfg->role = OUTPUT_ROLE_PERMANENT; + return cfg; + } + cfg->pos.x = parse_uint(saveptr, " "); if(cfg->pos.x < 0) { *errstr = log_error( @@ -702,6 +720,7 @@ parse_message_config(char **saveptr, char **errstr) { cfg->fg_color[0] = -1; cfg->display_time = -1; cfg->font = NULL; + cfg->anchor = CG_MESSAGE_NOPT; char *setting = strtok_r(NULL, " ", saveptr); if(setting == NULL) { @@ -745,6 +764,22 @@ parse_message_config(char **saveptr, char **errstr) { goto error; } } + } else if(strcmp(setting, "anchor") == 0) { + char *anchors[] = {"top_left", "top_center", "top_right", + "bottom_left", "bottom_center", "bottom_right", + "center"}; + for(int i = 0; i < 7; ++i) { + if(strcmp(*saveptr, anchors[i]) == 0) { + cfg->anchor = i; + break; + } + } + if(cfg->anchor == CG_MESSAGE_NOPT) { + *errstr = + log_error("Error parsing command \"configure_message anchor\", " + "the given anchor value is not a valid option"); + goto error; + } } else { *errstr = log_error("Invalid option to command \"configure_message\""); goto error; diff --git a/parse.h b/parse.h index 2949315..d78df94 100644 --- a/parse.h +++ b/parse.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef PARSE_H diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index 16e03cd..b196533 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index 16e03cd..b196533 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index 16e03cd..b196533 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index 16e03cd..b196533 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/acknowledge-contributors b/release-non-auto-checks/acknowledge-contributors index 16e03cd..b196533 100644 --- a/release-non-auto-checks/acknowledge-contributors +++ b/release-non-auto-checks/acknowledge-contributors @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/archwiki b/release-non-auto-checks/archwiki new file mode 100644 index 0000000..b196533 --- /dev/null +++ b/release-non-auto-checks/archwiki @@ -0,0 +1,2 @@ +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index 16e03cd..b196533 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index 16e03cd..b196533 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index 16e03cd..b196533 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index 16e03cd..b196533 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index 16e03cd..b196533 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/release-non-auto-checks/version-restrictions b/release-non-auto-checks/version-restrictions index 16e03cd..b196533 100644 --- a/release-non-auto-checks/version-restrictions +++ b/release-non-auto-checks/version-restrictions @@ -1,2 +1,2 @@ -2.2.3 -2023-12-05 +2.3.0 +2024-01-26 diff --git a/scripts/adjust-epoch b/scripts/adjust-epoch index 362c840..14b935c 100755 --- a/scripts/adjust-epoch +++ b/scripts/adjust-epoch @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT if [[ -n ${MESON_SOURCE_ROOT} ]] diff --git a/scripts/create-release-artefacts b/scripts/create-release-artefacts index 4b16167..05212a5 100755 --- a/scripts/create-release-artefacts +++ b/scripts/create-release-artefacts @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT if [[ -n ${MESON_SOURCE_ROOT} ]] diff --git a/scripts/create-signatures b/scripts/create-signatures index 3292374..958825f 100755 --- a/scripts/create-signatures +++ b/scripts/create-signatures @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT if [[ -n ${MESON_SOURCE_ROOT} ]] diff --git a/scripts/fuzz b/scripts/fuzz index 7f227ec..e90e17a 100755 --- a/scripts/fuzz +++ b/scripts/fuzz @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT readonly fuzzing_corpus="${1}" diff --git a/scripts/git-tag b/scripts/git-tag index bd8e541..4b5dbbc 100755 --- a/scripts/git-tag +++ b/scripts/git-tag @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT readonly gpg_id="${1}" diff --git a/scripts/install-development-environment b/scripts/install-development-environment old mode 100644 new mode 100755 index 1b71ce5..b799eec --- a/scripts/install-development-environment +++ b/scripts/install-development-environment @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT sudo pacman -Syu --noconfirm git grep sed xorg-xev meson ninja clang gcc shellcheck jq openbsd-netcat gnupg binutils alacritty wlroots wayland wayland-protocols libxkbcommon cairo pango fontconfig libinput libevdev pkgconf scdoc systemd-libs # systemd-libs is included because of libudev diff --git a/scripts/output-hashes b/scripts/output-hashes index cf7cacf..d18088b 100755 --- a/scripts/output-hashes +++ b/scripts/output-hashes @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT if [[ -n ${MESON_SOURCE_ROOT} ]] diff --git a/scripts/set-version b/scripts/set-version index 3ee035c..3f7875e 100755 --- a/scripts/set-version +++ b/scripts/set-version @@ -1,9 +1,7 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT -# TODO man pages - if [[ -n ${MESON_SOURCE_ROOT} ]] then # shellcheck disable=2164 diff --git a/seat.c b/seat.c index 80206e9..a011251 100644 --- a/seat.c +++ b/seat.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200812L @@ -95,7 +95,7 @@ new_touch(struct cg_seat *seat, struct cg_input_device *input_device) { if(wlr_touch->output_name != NULL) { struct cg_output *output; wl_list_for_each(output, &seat->server->outputs, link) { - if(strcmp(wlr_touch->output_name, output->wlr_output->name) == 0) { + if(strcmp(wlr_touch->output_name, output->name) == 0) { wlr_cursor_map_input_to_output(seat->cursor, device, output->wlr_output); break; @@ -133,8 +133,7 @@ new_pointer(struct cg_seat *seat, struct cg_input_device *input_device) { if(wlr_pointer->output_name != NULL) { struct cg_output *output; wl_list_for_each(output, &seat->server->outputs, link) { - if(strcmp(wlr_pointer->output_name, output->wlr_output->name) == - 0) { + if(strcmp(wlr_pointer->output_name, output->name) == 0) { wlr_cursor_map_input_to_output(seat->cursor, device, output->wlr_output); break; @@ -732,35 +731,39 @@ process_cursor_motion(struct cg_seat *seat, uint32_t time) { break; } } - struct cg_tile *c_tile; - bool first = true; - for(c_tile = cg_outp->workspaces[cg_outp->curr_workspace]->focused_tile; - first || - c_tile != cg_outp->workspaces[cg_outp->curr_workspace]->focused_tile; - c_tile = c_tile->next) { - first = false; - double ox = seat->cursor->x, oy = seat->cursor->y; - wlr_output_layout_output_coords(seat->server->output_layout, c_outp, - &ox, &oy); - if(c_tile->tile.x <= ox && c_tile->tile.y <= oy && - c_tile->tile.x + c_tile->tile.width >= ox && - c_tile->tile.y + c_tile->tile.height >= oy) { - break; + if(c_outp) { + struct cg_tile *c_tile; + bool first = true; + for(c_tile = cg_outp->workspaces[cg_outp->curr_workspace]->focused_tile; + first || + c_tile != + cg_outp->workspaces[cg_outp->curr_workspace]->focused_tile; + c_tile = c_tile->next) { + first = false; + double ox = seat->cursor->x, oy = seat->cursor->y; + wlr_output_layout_output_coords(seat->server->output_layout, c_outp, + &ox, &oy); + if(c_tile->tile.x <= ox && c_tile->tile.y <= oy && + c_tile->tile.x + c_tile->tile.width >= ox && + c_tile->tile.y + c_tile->tile.height >= oy) { + break; + } } + if(seat->cursor_tile != NULL && seat->cursor_tile != c_tile && + seat->server->running) { + ipc_send_event( + seat->server, + "{\"event_name\":\"cursor_switch_tile\",\"old_output\":" + "\"%s\",\"old_output_id\":%d," + "\"old_tile\":%d,\"new_output\":\"%s\",\"new_output_" + "id\":%d,\"new_tile\":%d}", + seat->cursor_tile->workspace->output->name, + output_get_num(seat->cursor_tile->workspace->output), + seat->cursor_tile->id, c_outp->name, output_get_num(cg_outp), + c_tile->id); + } + seat->cursor_tile = c_tile; } - if(seat->cursor_tile != NULL && seat->cursor_tile != c_tile && - seat->server->running) { - ipc_send_event(seat->server, - "{\"event_name\":\"cursor_switch_tile\",\"old_output\":" - "\"%s\",\"old_output_id\":%d," - "\"old_tile\":%d,\"new_output\":\"%s\",\"new_output_" - "id\":%d,\"new_tile\":%d}", - seat->cursor_tile->workspace->output->wlr_output->name, - output_get_num(seat->cursor_tile->workspace->output), - seat->cursor_tile->id, c_outp->name, - output_get_num(cg_outp), c_tile->id); - } - seat->cursor_tile = c_tile; } static void @@ -915,6 +918,7 @@ handle_destroy(struct wl_listener *listener, void *_data) { wl_list_remove(&seat->request_set_cursor.link); wl_list_remove(&seat->request_set_selection.link); wl_list_remove(&seat->request_set_primary_selection.link); + seat->server->seat = NULL; free(seat); } @@ -1095,9 +1099,8 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view) { wlr_scene_node_raise_to_top(&view->scene_tree->node); process_cursor_motion(seat, -1); - struct wlr_box box; - wlr_output_layout_get_box(server->output_layout, - view->workspace->output->wlr_output, &box); - wlr_scene_node_set_position(&view->workspace->output->bg->node, box.x, - box.y); + wlr_scene_node_set_position( + &view->workspace->output->bg->node, + output_get_layout_box(view->workspace->output).x, + output_get_layout_box(view->workspace->output).y); } diff --git a/seat.h b/seat.h index 74f4092..135c06a 100644 --- a/seat.h +++ b/seat.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_SEAT_H diff --git a/server.c b/server.c index c50f528..98c7630 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -43,8 +43,7 @@ server_show_info(struct cg_server *server) { return NULL; } output_str_tmp = output_str; - output_str = malloc_vsprintf("%s\t * %s\n", output_str, - output->wlr_output->name); + output_str = malloc_vsprintf("%s\t * %s\n", output_str, output->name); free(output_str_tmp); } char *input_str = strdup(""), *input_str_tmp; diff --git a/server.h b/server.h index 0c067ec..3224174 100644 --- a/server.h +++ b/server.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_SERVER_H @@ -29,6 +29,8 @@ struct cg_server { struct wlr_idle_notifier_v1 *idle; struct wlr_idle_inhibit_manager_v1 *idle_inhibit_v1; struct wl_listener new_idle_inhibitor_v1; + struct wlr_gamma_control_manager_v1 *gamma_control; + struct wl_listener gamma_control_set_gamma; struct wl_list inhibitors; struct wlr_output_layout *output_layout; @@ -38,6 +40,7 @@ struct cg_server { struct cg_output *curr_output; struct wl_listener new_output; struct wl_list output_priorities; + struct wlr_backend *headless_backend; struct wlr_session *session; struct wlr_renderer *renderer; diff --git a/signatures/2.2.3-cagebreak-config.5.sig b/signatures/2.2.3-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..6d7f6c16507165c9ac9b5646e45cb4cc3a89863b GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dO=&HxGt5J?I6 zOsG4!XG8W6|9R#;J{FE-UT8#I!Fi4#zi*ov9Xy@$5_IOwHC)DCP)s(==UVe6N7@ z7-A^-dEBpXnVsr`4n6aH48XT2AyHl2pVYRfFaF(bzfgb5CP>9$GN1&xC*(lsKc$ES zs%PuSW{ZB7f7oK6icaf23!q$wo7AdmkJ8aL2E@?F2594cy;Bn5~L z9(UAzOi$oHQJh|t!#oTPbMGoOZ^%H@=|cd#EU(M^3U*H3e9_{g{BV#!>42q+@7Wxi}6Hzo4QkhM=B3~=^{TsW09d;k=38L|LYbj z1!=3-gW5s4#~j8OX3#|G#e)MUguD-d$ATD;!Z5iJ0K4(!s?r{__=2_g72L z?`g>X^*N-@l^ncjW8n9PqAzR}vsQF-1=>w_+i&?Sy88qG&0dbXVAB?;Pby!`eiwUBN@f;NyKrXVlUf?VnplxxC=W^W_Zg+WAns( zFor@FIpAV*0laHJ%ILoX*MD55X=+$Zn3=->a9yE$BwCpc6jSY57l9Y~B;!p=jC522 z7h9{U8HL#aL&CA)`KAkQj5mm=SosFH8@H_a{Q`~Uy| literal 0 HcmV?d00001 diff --git a/signatures/2.2.3-cagebreak.1.sig b/signatures/2.2.3-cagebreak.1.sig new file mode 100644 index 0000000000000000000000000000000000000000..14ac7ab7fd60b8337eaa18e060f7a24402925528 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dO=%>W7s5J?I6 zOsG4!XL#rj{T+Al-oPBN+x!MHM~QdkHzBr|Cl+us_ro^WM3!tDhfsBw7Pq%1Z{RD62N4N=i9+{y)3(Ru$V?xv1!7mfQc zC$)a&YY~(X8+6uKax?zdKvEm$?XN0+!~nA+>4rgX2FGfWUVr~jg!oq%fFplfE=b^F z*E|X$ABEacp-D>5QmMs>^C6Kt%bZKs7tqA@eZhm@7mF-$$2nRbtUkK-UAVyflBeE9)=j4Yx^^blg0G{qp7&RP?Tv#W249hQ1 z;a&i5R!X|YVS?xn#d0KHbp+uZ^eJiDp=DK7Q8q&K9V9}>7lfH+!()^ zhVi<3>Oy_K@#g6CBoJ+moJ(*_iX~jCgMSc+nVn=Xw^uft*T^QSAPhrD>@L20qNDU4 ztoB5mA&Wu>syLrBc^DsmQiQ@QL)6zpT7!BG>>{O|HFtXgh)1Ps5ZqLl)Cx&OS1)v+ z86sR8$66K)Dqhg=5(4#f`GiL&3yh2z0{z#Pk)7X@=tDjJ_J`^&YaK-^$7k{&2ct;Q Er@2=MA^-pY literal 0 HcmV?d00001 diff --git a/signatures/2.2.3-cagebreak.sig b/signatures/2.2.3-cagebreak.sig new file mode 100644 index 0000000000000000000000000000000000000000..b06130553f46759a6b0c15d2ec5e4a7f3fe3714d GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dO=%>W7s5J?I6 zOsG4!XRMG9{S^4?G%^Y3m5el0Q_7oaILK}lji>EKqg2qNLmPHp`AzALIN3h@;a~B) zymaY@9KZ9Z?6L?yxsZ1pU=68cL;~wowNV!k(}NRXx`~nO6O%vds-sG3-$iS`TqsdT zy69<@`z1%3|EV0;2c&?;WEN~;S=m2 z?~wRpF((7yAP7A+^P8Iwf*BC^zzRW1uK-TzJJQ?z8i%||)(5V~qx+VB?pRqYq0@!B zIo-vd&QOv|KoOWnF*@AlRmS2Vrdh0b@5a>H^Utb8$FV@;+I0D^9Evlne?qQS(sCt|#67`gVa4;YZrz^IadZjiZg9AM5Fl9NuDd;L(g z&FIcmFW`pIpf2uSMXG4XO*XTp=PDjn_=?Cj??Ulzglg^5MEoC{ov(CO@X&I^k=_&SbK2pEm= z$xVU0w5U2fRup=?k;RFm<^v-=7j1p_kBSLFi6GH%D|&C5CQzLQyERg2;zbHi5TCEB z2E`HAgZKmA1oxlZA>XrJzsaQz?}HqL42v|+;2>1ttB1PS6An1bsU4@-s1J&RP&mrK z(WsT%{ZdE1su#g$PZgU}DU`kptkABdLg0u`2(vP_yQ+ULFY#KWBCx7sCo=u?!lR3= z1#?mWI=axdoptn(;m%cZG0E15^Hw+mp9NR=q=V3&F5!2q_hG;5G^ZY%ZD#|8{?Fvr z+ryfm1qlP46HZAeyVV_h!L{CO{ZFg7-w3c{079Ut3SJ6GY1fxb`{;S9HB#*RnzDcr zGU-k3EmW4k#|}>t(>%&H%~--iT-T?Aghiw!Y$=;2r9u#e%JI_ zf>*aS(~y`kMIFhqZepjqnQjEIm7aEGdd^pSAGKhdK3_M E_N;CdYybcN literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dO=&HxGt5J?I6 zOsG4!XG8W6|9R#;J{FE-UT8#I!Fi4#zi*ov9Xy@$5_IOwHC)DCP)s(==UVe6N7@ z7-A^-dEBpXnVsr`4n6aH48XT2AyHl2pVYRfFaF(bzfgb5CP>9$GN1&xC*(lsKc$ES zs%PuSW{ZB7f7oK6icaf23!q$wo7AdmkJ8aL2E@?F2594cy;Bn5~L z9(UAzOi$oHQJh|t!#oTPbMGoOZ^%H@=|cd#EU(M^3U*H3e9_{g{BV#!>4$FV+{ci0FVk4pZ@5#p=MAnB%={2LAyG)?MEy$jYUmyuCHfqeovKF_esgy{%6Dq zu&rvF7KjJyT-2;|Nkg$$rxABsjv{d9b_R~p6NL-VnF~x)%X_eQrXGRA{)Hy zCNN~()r+T2gBPip7Sfc2JtyA8Z|~@M6!;`Q>gl?;Dh9xd^I~UT<58VO#{ww`uJ2p1e-C!xr_dy z!TdS*h()PclryOEj;7V%Hv!N=O)@ZMFnS}iq?>j~Y{Ls3gjPhjXX$AaH$Fy?3eq%> zhmt>=2`ja(4kMFI!rg6nXHu6rnGLjBMUC23S3cFs2h(4)18;bGgPRT#QPkr%C?%h* zmfi!WR#{#pEGvCF`U(PDgIFH{>dl6IR@W6pN;T)ohQ3VC-`{QomcHY)oVU1ZK+Kvy EdRn&%eE2q+@7Wxi}6Hzo4QkhM=B3~=^{TsW09d;k=38L|LYbj z1!=3-gW5s4#~j8OX3#|G#e)MUguD-d$ATD;!Z5iJ0K4(!s?r{__=2_g72L z?`g>X^*N-@l^ncjW8n9PqAzR}vsQF-1=>w_+i&?Sy88qG&0dbXVAB?;Pby!`eiwUBN@f;NyKrXVlUf?VnplxxC=W^W_Zg+WAns( zFor@FIpAV*0laHJ%ILoX*MD55X=+$Zn3=->a9yE$BwCpc6jSY57l9Y~B;!p=jC522 z7h9{U8HL#aL&CA)`KAkQj5mm=SosFH8@H_a{Q`~Uy| diff --git a/signatures/cagebreak.1.sig b/signatures/cagebreak.1.sig index 14ac7ab7fd60b8337eaa18e060f7a24402925528..8ed93af821b8d4f18114dfe28a85eb40dc9d9651 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*fj3?c-(R61$^wxVt5(TqTjC^AS0%fy{!~hBj5JeIN zvr>$FV`bD2{yS8osLz6ml84%T-f}!GvPVdfu|-TyrQeyFp(z+PiP6t8h#G!k@UNsI z>o5@MLpYGCN<_`qGHFe5=O|Hklc;hup6}kum#9)G1y=i2i%AoB{8g|vMxnc)1vmK- z^CxGI8n8|`xuy|uXKOm_f9+#7nAZqq65L^ZJ!)i<@w#)vCtdqq)vM&}2mdiP*Oxs0 zvVwvXBKXkWdN>Xp_4_RlqqiFsp-S0@%m~uaVV>a?+ny`R^i%(lPqKq40yA)pGmh1Q zLmboYtiy1*rykfKYLZCl1McA}nm4?1SW-T}WO+m=eTCZxM_U|x#8&vi8;n{l~9SK_#Y&WCr<~f(^czt;VRa!&+j~d6&D=ilcyY2rZIKkHc?O z2XK9!5hQ5rQnk@5AXe8H5{?2>{e5rRuBu_XUh)g$iRx7ipdG|vd4}sxymQ>Z`P|&v z%Iq!5F6mrXzh5b%|6PI|t6~`96ICAM5J8%IKSNMdsEqm^r(~Gl)$FdjUv@ER-PZM| z3!Ga}Ul3sLZ%{9aH@E!*QF;eAQcyFim?vxb6YC9-`Uc)S{qn@%WwJ|U z=eALOpD4cziVP2@eSHkgm-Ok(>qUsH8p22gT_eT(4ENH>>sl&HCxEJ#242_z4h%E< Ex^_eog8%>k literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dO=%>W7s5J?I6 zOsG4!XL#rj{T+Al-oPBN+x!MHM~QdkHzBr|Cl+us_ro^WM3!tDhfsBw7Pq%1Z{RD62N4N=i9+{y)3(Ru$V?xv1!7mfQc zC$)a&YY~(X8+6uKax?zdKvEm$?XN0+!~nA+>4rgX2FGfWUVr~jg!oq%fFplfE=b^F z*E|X$ABEacp-D>5QmMs>^C6Kt%bZKs7tqA@eZhm@7mF-$$2nRbtUkK-UAVyflBeE9)=j4Yx^^blg0G{qp7&RP?Tv#W249hQ1 z;a&i5R!X|YVS?xn#d0KHbp+uZ^eJiDp=DK7Q8q&K9V9}>7lfH+!()^ zhVi<3>Oy_K@#g6CBoJ+moJ(*_iX~jCgMSc+nVn=Xw^uft*T^QSAPhrD>@L20qNDU4 ztoB5mA&Wu>syLrBc^DsmQiQ@QL)6zpT7!BG>>{O|HFtXgh)1Ps5ZqLl)Cx&OS1)v+ z86sR8$66K)Dqhg=5(4#f`GiL&3yh2z0{z#Pk)7X@=tDjJ_J`^&YaK-^$7k{&2ct;Q Er@2=MA^-pY diff --git a/signatures/cagebreak.sig b/signatures/cagebreak.sig index b06130553f46759a6b0c15d2ec5e4a7f3fe3714d..e106209e41a6bc13a33cc9aa55e3b69e7b2586f4 100644 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*fj3?c-(R61$^wxVt5(TqTjC^AS0%fy{!~hBj5JeIN zvr>$FV`0b-|6sTKs%81)qQ(2WTT;zI;D3i|(&bmgFIMKXHUUH#P8VWTQwxv31z{)GG*1|?@P=OqGu(-c||L}F3ukC8;C=2;C0-2qv zNyyrDjgI2;(Sjt${|gcD%cXlm69&36I+EXi|5cFyo(-51B$llX+QTcB>=yAin9pT! zWo#@SSY@vb6AYPts>DbiLtLY=fxFX%MI-4s;Wo9VgW^OuIDQY;Zd6Z2;!^Tx#X20~kzP7eKjm};|Ek*U% EY6-U&D*ylh literal 566 zcmV-60?GY}0y6{v0SEvc79j*qg2yatK3J!`Pxw_y3HVH?JGf^B0%dO=%>W7s5J?I6 zOsG4!XRMG9{S^4?G%^Y3m5el0Q_7oaILK}lji>EKqg2qNLmPHp`AzALIN3h@;a~B) zymaY@9KZ9Z?6L?yxsZ1pU=68cL;~wowNV!k(}NRXx`~nO6O%vds-sG3-$iS`TqsdT zy69<@`z1%3|EV0;2c&?;WEN~;S=m2 z?~wRpF((7yAP7A+^P8Iwf*BC^zzRW1uK-TzJJQ?z8i%||)(5V~qx+VB?pRqYq0@!B zIo-vd&QOv|KoOWnF*@AlRmS2Vrdh0b@5a>H^Utb8 CONFIGPATH ) quit diff --git a/example_scripts/cb_script_header.sh b/test/testing-configurations/cb_script_header.sh similarity index 89% rename from example_scripts/cb_script_header.sh rename to test/testing-configurations/cb_script_header.sh index 770f075..d844a0a 100644 --- a/example_scripts/cb_script_header.sh +++ b/test/testing-configurations/cb_script_header.sh @@ -1,7 +1,5 @@ -#!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT - named_pipe_send="$(mktemp -u)" named_pipe_recv="$(mktemp -u)" mkfifo "${named_pipe_send}" diff --git a/test/testing-configurations/config b/test/testing-configurations/config index 9925aec..268fe77 100644 --- a/test/testing-configurations/config +++ b/test/testing-configurations/config @@ -1,4 +1,4 @@ -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT exec (echo $CAGEBREAK_SOCKET > CONFIGPATH) quit diff --git a/test/testing-configurations/env-var-config b/test/testing-configurations/env-var-config index a769e73..8476149 100644 --- a/test/testing-configurations/env-var-config +++ b/test/testing-configurations/env-var-config @@ -1,4 +1,4 @@ -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT exec (echo "SUCCESS" > CONFIGPATH ) quit diff --git a/test/testing-configurations/my-scan-build b/test/testing-configurations/my-scan-build index 526f1dd..db3f3d0 100755 --- a/test/testing-configurations/my-scan-build +++ b/test/testing-configurations/my-scan-build @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT scan-build --status-bugs "$@" diff --git a/test/versions b/test/versions index b408c71..66b6d11 100644 --- a/test/versions +++ b/test/versions @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2023, project-repo and the cagebreak contributors +# Copyright 2023 - 2024, project-repo and the cagebreak contributors # SPDX-License-Identifier: MIT readonly newversion="${1}" diff --git a/util.c b/util.c index f8c7a82..1f84bdc 100644 --- a/util.c +++ b/util.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #include diff --git a/util.h b/util.h index b509a00..b9a95ef 100644 --- a/util.h +++ b/util.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_UTIL_H diff --git a/view.c b/view.c index 69ee5fe..1d2d9c3 100644 --- a/view.c +++ b/view.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -80,11 +80,10 @@ void view_maximize(struct cg_view *view, struct cg_tile *tile) { view->ox = tile->tile.x; view->oy = tile->tile.y; - struct wlr_box box; - wlr_output_layout_get_box(view->server->output_layout, - view->workspace->output->wlr_output, &box); - wlr_scene_node_set_position(&view->scene_tree->node, view->ox + box.x, - view->oy + box.y); + wlr_scene_node_set_position( + &view->scene_tree->node, + view->ox + output_get_layout_box(view->workspace->output).x, + view->oy + output_get_layout_box(view->workspace->output).y); view->impl->maximize(view, tile->tile.width, tile->tile.height); view->tile = tile; wlr_scene_node_raise_to_top(&view->scene_tree->node); @@ -96,7 +95,7 @@ view_unmap(struct cg_view *view) { uint32_t id = view->id; uint32_t tile_id = 0; uint32_t ws = view->workspace->num; - char *output_name = view->workspace->output->wlr_output->name; + char *output_name = view->workspace->output->name; int output_id = output_get_num(view->workspace->output); pid_t pid = view->impl->get_pid(view); /* If the view is not mapped, do nothing */ @@ -170,11 +169,10 @@ view_map(struct cg_view *view, struct wlr_surface *surface, their own (x,y) coordinates in handle_wayland_surface_map. */ if(view->type == CG_XWAYLAND_VIEW && !xwayland_view_should_manage(view)) { wl_list_insert(&ws->unmanaged_views, &view->link); - struct wlr_box box; - wlr_output_layout_get_box(view->server->output_layout, - view->workspace->output->wlr_output, &box); - wlr_scene_node_set_position(&view->scene_tree->node, view->ox + box.x, - view->oy + box.y); + wlr_scene_node_set_position( + &view->scene_tree->node, + view->ox + output_get_layout_box(view->workspace->output).x, + view->oy + output_get_layout_box(view->workspace->output).y); } else #endif { @@ -192,8 +190,8 @@ view_map(struct cg_view *view, struct wlr_surface *surface, "{\"event_name\":\"view_map\",\"view_id\":%d,\"tile_id\":%d," "\"workspace\":%d,\"output\":\"%s\",\"output_id\":%d,\"view_pid\":%d}", view->id, tile_id, view->workspace->num + 1, - view->workspace->output->wlr_output->name, - output_get_num(view->workspace->output), view->impl->get_pid(view)); + view->workspace->output->name, output_get_num(view->workspace->output), + view->impl->get_pid(view)); } void diff --git a/view.h b/view.h index b9ec0a1..b2ff05d 100644 --- a/view.h +++ b/view.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_VIEW_H diff --git a/workspace.c b/workspace.c index 3f84c6f..7d93183 100644 --- a/workspace.c +++ b/workspace.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -29,13 +29,8 @@ workspace_tile_update_view(struct cg_tile *tile, struct cg_view *view) { } } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" -#endif int full_screen_workspace_tiles(struct wlr_output_layout *layout, - struct wlr_output *output, struct cg_workspace *workspace, uint32_t *tiles_curr_id) { workspace->focused_tile = calloc(1, sizeof(struct cg_tile)); @@ -47,18 +42,15 @@ full_screen_workspace_tiles(struct wlr_output_layout *layout, workspace->focused_tile->prev = workspace->focused_tile; workspace->focused_tile->tile.x = 0; workspace->focused_tile->tile.y = 0; - struct wlr_box output_box; - wlr_output_layout_get_box(layout, output, &output_box); - workspace->focused_tile->tile.width = output_box.width; - workspace->focused_tile->tile.height = output_box.height; + workspace->focused_tile->tile.width = + output_get_layout_box(workspace->output).width; + workspace->focused_tile->tile.height = + output_get_layout_box(workspace->output).height; workspace_tile_update_view(workspace->focused_tile, NULL); workspace->focused_tile->id = *tiles_curr_id; ++(*tiles_curr_id); return 0; } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic pop -#endif struct cg_workspace * full_screen_workspace(struct cg_output *output) { @@ -72,16 +64,15 @@ full_screen_workspace(struct cg_output *output) { free(workspace); return NULL; } + workspace->output = output; workspace->server = output->server; workspace->num = -1; workspace->scene = wlr_scene_tree_create(&scene_output->scene->tree); - if(full_screen_workspace_tiles(output->server->output_layout, - output->wlr_output, workspace, + if(full_screen_workspace_tiles(output->server->output_layout, workspace, &output->server->tiles_curr_id) != 0) { free(workspace); return NULL; } - workspace->output = output; return workspace; } @@ -102,10 +93,10 @@ void workspace_free_tiles(struct cg_workspace *workspace) { workspace->focused_tile->prev->next = NULL; while(workspace->focused_tile != NULL) { - if(workspace->output->server->running && - workspace->output->server->seat->cursor_tile == - workspace->focused_tile) { - workspace->output->server->seat->cursor_tile = NULL; + if(workspace->server->seat != NULL && + (!workspace->output->server->running || + workspace->focused_tile == workspace->server->seat->cursor_tile)) { + workspace->server->seat->cursor_tile = NULL; } struct cg_tile *next = workspace->focused_tile->next; free(workspace->focused_tile); diff --git a/workspace.h b/workspace.h index b669cec..83b41a1 100644 --- a/workspace.h +++ b/workspace.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_WORKSPACE_H @@ -33,7 +33,6 @@ struct cg_workspace * full_screen_workspace(struct cg_output *output); int full_screen_workspace_tiles(struct wlr_output_layout *layout, - struct wlr_output *output, struct cg_workspace *workspace, uint32_t *tiles_curr_id); void diff --git a/xdg_shell.c b/xdg_shell.c index 79f322f..fa15ad0 100644 --- a/xdg_shell.c +++ b/xdg_shell.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #define _POSIX_C_SOURCE 200809L @@ -53,10 +53,6 @@ xdg_decoration_handle_destroy(struct wl_listener *listener, void *data) { free(xdg_decoration); } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" -#endif static void xdg_decoration_handle_request_mode(struct wl_listener *listener, void *_data) { struct cg_xdg_decoration *xdg_decoration = @@ -67,21 +63,18 @@ xdg_decoration_handle_request_mode(struct wl_listener *listener, void *_data) { wlr_xdg_toplevel_decoration_v1_set_mode(xdg_decoration->wlr_decoration, mode); } -#if CG_HAS_FANALYZE -#pragma GCC diagnostic pop -#endif static void popup_unconstrain(struct cg_view *view, struct wlr_xdg_popup *popup) { struct wlr_box *popup_box = &popup->current.geometry; struct wlr_output_layout *output_layout = view->server->output_layout; - struct wlr_box view_output_box; - wlr_output_layout_get_box( - output_layout, view->workspace->output->wlr_output, &view_output_box); struct wlr_output *wlr_output = wlr_output_layout_output_at( - output_layout, view_output_box.x + view->ox + popup_box->x, - view_output_box.y + view->oy + popup_box->y); + output_layout, + output_get_layout_box(view->workspace->output).x + view->ox + + popup_box->x, + output_get_layout_box(view->workspace->output).y + view->oy + + popup_box->y); struct wlr_box output_box; wlr_output_layout_get_box(output_layout, wlr_output, &output_box); @@ -171,8 +164,9 @@ handle_xdg_shell_surface_request_fullscreen(struct wl_listener *listener, * they display in fullscreen mode, so we set it here. */ struct wlr_box layout_box; - wlr_output_layout_get_box(xdg_shell_view->view.server->output_layout, NULL, - &layout_box); + wlr_output_layout_get_box( + xdg_shell_view->view.server->output_layout, + xdg_shell_view->view.workspace->output->wlr_output, &layout_box); wlr_xdg_toplevel_set_size(xdg_shell_view->xdg_surface->toplevel, layout_box.width, layout_box.height); diff --git a/xdg_shell.h b/xdg_shell.h index fd80b99..5f9456c 100644 --- a/xdg_shell.h +++ b/xdg_shell.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_XDG_SHELL_H diff --git a/xwayland.c b/xwayland.c index 21cc2ba..5755148 100644 --- a/xwayland.c +++ b/xwayland.c @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #include "config.h" @@ -96,13 +96,11 @@ maximize(struct cg_view *view, int width, int height) { } } - struct wlr_box output_box; - wlr_output_layout_get_box(view->server->output_layout, - view->server->curr_output->wlr_output, - &output_box); - wlr_xwayland_surface_configure(xwayland_view->xwayland_surface, - view->ox + output_box.x, - view->oy + output_box.y, width, height); + wlr_xwayland_surface_configure( + xwayland_view->xwayland_surface, + view->ox + output_get_layout_box(view->server->curr_output).x, + view->oy + output_get_layout_box(view->server->curr_output).y, width, + height); wlr_xwayland_surface_set_maximized(xwayland_view->xwayland_surface, true); } @@ -138,12 +136,10 @@ handle_xwayland_surface_map(struct wl_listener *listener, void *_data) { wl_container_of(listener, xwayland_view, map); struct cg_view *view = &xwayland_view->view; if(!xwayland_view_should_manage(view)) { - struct wlr_output_layout *output_layout = view->server->output_layout; - struct wlr_box output_box; - wlr_output_layout_get_box( - output_layout, view->server->curr_output->wlr_output, &output_box); - view->ox = xwayland_view->xwayland_surface->x - output_box.x; - view->oy = xwayland_view->xwayland_surface->y - output_box.y; + view->ox = xwayland_view->xwayland_surface->x - + view->server->curr_output->layout_box.x; + view->oy = xwayland_view->xwayland_surface->y - + view->server->curr_output->layout_box.y; } view_map(view, xwayland_view->xwayland_surface->surface, diff --git a/xwayland.h b/xwayland.h index 79c265a..6661f0e 100644 --- a/xwayland.h +++ b/xwayland.h @@ -1,4 +1,4 @@ -// Copyright 2020 - 2023, project-repo and the cagebreak contributors +// Copyright 2020 - 2024, project-repo and the cagebreak contributors // SPDX-License-Identifier: MIT #ifndef CG_XWAYLAND_H From ace4ff04c61806d9c321392cbdc443435a6274ee Mon Sep 17 00:00:00 2001 From: project-repo Date: Sat, 27 Jan 2024 16:50:27 +0000 Subject: [PATCH 19/19] Release 2.3.1 * Unbreak build on FreeBSD (#74, 73 in Bugs.md) * Thanks to Jan Beich for pointing this out. * Add Issue 74 to Bugs.md (#71, was fixed in 2.3.0) --- Bugs.md | 27 ++++++++++++++---- Hashes.md | 20 +++++++++++++ README.md | 2 +- keybinding.c | 1 + man/cagebreak-config.5.md | 2 +- man/cagebreak-socket.7.md | 2 +- man/cagebreak.1.md | 2 +- meson.build | 4 +-- release-non-auto-checks/Bugs.md | 4 +-- release-non-auto-checks/FAQ.md | 4 +-- release-non-auto-checks/SECURITY.md | 4 +-- release-non-auto-checks/WLR_XDG_VERSION | 4 +-- .../acknowledge-contributors | 4 +-- release-non-auto-checks/archwiki | 4 +-- release-non-auto-checks/changelog-major-minor | 4 +-- release-non-auto-checks/internal-wiki | 4 +-- release-non-auto-checks/release-note | 4 +-- .../reproducibility-checked | 4 +-- .../security-to-man-page-info-transfer | 4 +-- release-non-auto-checks/version-restrictions | 4 +-- signatures/2.3.0-cagebreak-config.5.sig | Bin 0 -> 566 bytes signatures/2.3.0-cagebreak-socket.7.sig | Bin 0 -> 566 bytes signatures/2.3.0-cagebreak.1.sig | Bin 0 -> 566 bytes signatures/2.3.0-cagebreak.sig | Bin 0 -> 566 bytes signatures/cagebreak-config.5.sig | Bin 566 -> 566 bytes signatures/cagebreak-socket.7.sig | Bin 566 -> 566 bytes signatures/cagebreak.1.sig | Bin 566 -> 566 bytes signatures/cagebreak.sig | Bin 566 -> 566 bytes 28 files changed, 73 insertions(+), 35 deletions(-) create mode 100644 signatures/2.3.0-cagebreak-config.5.sig create mode 100644 signatures/2.3.0-cagebreak-socket.7.sig create mode 100644 signatures/2.3.0-cagebreak.1.sig create mode 100644 signatures/2.3.0-cagebreak.sig diff --git a/Bugs.md b/Bugs.md index 4ecef6c..970edf4 100644 --- a/Bugs.md +++ b/Bugs.md @@ -1254,7 +1254,7 @@ established behaviour. ## Issue 68 - * github issue numner: #38 + * github issue number: #38 * Fixed: 2.3.0 After extensive discussion of how to deal with turning off outputs, the @@ -1265,7 +1265,7 @@ Thanks to sodface for the great cooperation. ## Issue 69 - * github issue numner: #68 + * github issue number: #68 * Fixed: 2.3.0 The config man page (5) was badly formatted up to version 2.3.0. @@ -1275,7 +1275,7 @@ shown in the web browser view of our repo. ## Issue 70 - * github issue numner: #62 + * github issue number: #62 * Fixed: 2.3.0 The README contained a few non-intuitive phrases up to version 2.3.0. @@ -1288,7 +1288,7 @@ To alleviate this, the following changes were made: ## Issue 71 - * github issue numner: #60 + * github issue number: #60 * Fixed: 2.3.0 Cagebreak up to 2.3.0 did not have configuration for the message location. @@ -1298,9 +1298,26 @@ accessibility. ## Issue 72 - * github issue numner: N/A + * github issue number: N/A * Fixed: 2.3.0 A Cagebreak version before 2.3.0 broke the gamma toolkit used to tune the monitor colors. +## Issue 73 + + * github issue number: #73 + * Fixed: 2.3.1 + +After 2.3.0 cagebreak did not build on FreeBSD. Since the fix was trivial, +this is fixed in 2.3.1. Thank to Jan Beich for pointing this out. + +## Issue 74 + + * github issue number: #71 + * Fixed. 2.3.0 + +Before 2.3.0 there was an issue with rendering fullscreen applications, particularly +under setups with multiple outputs applications spanned both outputs. Output ordering +also did not work as advertised. + diff --git a/Hashes.md b/Hashes.md index 2930148..7f0018a 100644 --- a/Hashes.md +++ b/Hashes.md @@ -1,5 +1,25 @@ # Hashes +2.3.1 cagebreak + + * sha 256: 51d76608726a6251690d6dd1371cdfaa6eae5188a08798cda9c9280b3fcbe3fa + * sha 512: 648c61958f5920b3377f53706f7a820750a2b7dd1d486db4a93d803fe38be4aa728058e82d404fde4e7f1627b9809050a5760c4193562a6c23e39d0851f1ddf0 + +2.3.1 cagebreak.1 + + * sha 256: c58390d641514b2eb623a803dc665116d60079b8aac39219b939cc36ffb72038 + * sha 512: 82c0248764026666e6fbe3e29bf48062db07d6a86c787258474312a0eae23a73898bcc2fd6c407fbac0a25d6414f9ca9a56e5d17d7c8adfe9e7ce903e6ed5978 + +2.3.1 cagebreak-config.5 + + * sha 256: 5cf2f8c883ce89563bbae1fa4f0e00bda42c4ba01f680fc75fc71ab3f6e1f2a8 + * sha 512: 10d72ca588f5e2123dc59ede89dafd0e6fb9cd6cbc83922ada751c37f9000c86f68e5e6bf9f68298380ec0f9cbce1f22d0a0f712d0004b168a0b039a41f32358 + +2.3.1 cagebreak-socket.7 + + * sha 256: 0363113a32533a6fb4a1e7030cff880f001db5e0c29bb8bd74f8f11067dce3d1 + * sha 512: f957ebad717456901a028344211609d009d9b8c2a68ef88a0d60fca8dc91cc1fe1aba58a9e84d16782190b59b9fcd1d45ecc154c020018609c8fcdf940aa18e4 + 2.3.0 cagebreak * sha 256: 549e82f6bb1af87c9272fb92d39c6f235b0f780885b066c32db5a5c7588da378 diff --git a/README.md b/README.md index 79397ea..c4ce338 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cagebreak: A Tiling Wayland Compositor -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.3.0)](https://repology.org/project/cagebreak/versions) +[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6532/badge)](https://bestpractices.coreinfrastructure.org/projects/6532) [![Packaging status](https://repology.org/badge/tiny-repos/cagebreak.svg)](https://repology.org/project/cagebreak/versions) [![AUR package](https://repology.org/badge/version-for-repo/aur/cagebreak.svg?minversion=2.3.1)](https://repology.org/project/cagebreak/versions) [![Contact](img/mail.svg)](SECURITY.md) [![Manuals](img/manuals.svg)](manuals.md) [![FAQ](img/faq.svg)](FAQ.md) [![CONTRIBUTING](img/contributing.svg)](CONTRIBUTING.md) [![ArchWiki](img/archwiki.svg)](https://wiki.archlinux.org/title/Cagebreak) [![AUR](img/aur.svg)](https://aur.archlinux.org/packages?O=0&K=cagebreak) diff --git a/keybinding.c b/keybinding.c index 2432e59..9878a58 100644 --- a/keybinding.c +++ b/keybinding.c @@ -3,6 +3,7 @@ #define _POSIX_C_SOURCE 200809L +#include #include #include #include diff --git a/man/cagebreak-config.5.md b/man/cagebreak-config.5.md index ee68d72..7c18c9a 100644 --- a/man/cagebreak-config.5.md +++ b/man/cagebreak-config.5.md @@ -1,4 +1,4 @@ -cagebreak-config(5) "Version 2.3.0" "Cagebreak Manual" +cagebreak-config(5) "Version 2.3.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak-socket.7.md b/man/cagebreak-socket.7.md index ed47f05..a5f3d8a 100644 --- a/man/cagebreak-socket.7.md +++ b/man/cagebreak-socket.7.md @@ -1,4 +1,4 @@ -cagebreak-socket(7) "Version 2.3.0" "Cagebreak Manual" +cagebreak-socket(7) "Version 2.3.1" "Cagebreak Manual" # NAME diff --git a/man/cagebreak.1.md b/man/cagebreak.1.md index 4dfd854..d91c589 100644 --- a/man/cagebreak.1.md +++ b/man/cagebreak.1.md @@ -1,4 +1,4 @@ -cagebreak(1) "Version 2.3.0" "Cagebreak Manual" +cagebreak(1) "Version 2.3.1" "Cagebreak Manual" # NAME diff --git a/meson.build b/meson.build index b0b458d..6b57a32 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cagebreak', 'c', -version : '2.3.0', +version : '2.3.1', license : 'MIT', default_options : ['c_std=c11', 'warning_level=3'] ) @@ -260,7 +260,7 @@ install_data('LICENSE', install_dir : '/usr/share/licenses/' + meson.project_nam if get_option('man-pages') scdoc = find_program('scdoc') - secssinceepoch = 1706213605 + secssinceepoch = 1706350970 shcommand = 'export SOURCE_DATE_EPOCH=' + secssinceepoch.to_string() + ' ; @0@ < @INPUT@'.format(scdoc.path()) sh = find_program('sh') mandir1 = join_paths(get_option('mandir'), 'man1') diff --git a/release-non-auto-checks/Bugs.md b/release-non-auto-checks/Bugs.md index b196533..8e6104c 100644 --- a/release-non-auto-checks/Bugs.md +++ b/release-non-auto-checks/Bugs.md @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/FAQ.md b/release-non-auto-checks/FAQ.md index b196533..8e6104c 100644 --- a/release-non-auto-checks/FAQ.md +++ b/release-non-auto-checks/FAQ.md @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/SECURITY.md b/release-non-auto-checks/SECURITY.md index b196533..8e6104c 100644 --- a/release-non-auto-checks/SECURITY.md +++ b/release-non-auto-checks/SECURITY.md @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/WLR_XDG_VERSION b/release-non-auto-checks/WLR_XDG_VERSION index b196533..8e6104c 100644 --- a/release-non-auto-checks/WLR_XDG_VERSION +++ b/release-non-auto-checks/WLR_XDG_VERSION @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/acknowledge-contributors b/release-non-auto-checks/acknowledge-contributors index b196533..8e6104c 100644 --- a/release-non-auto-checks/acknowledge-contributors +++ b/release-non-auto-checks/acknowledge-contributors @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/archwiki b/release-non-auto-checks/archwiki index b196533..8e6104c 100644 --- a/release-non-auto-checks/archwiki +++ b/release-non-auto-checks/archwiki @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/changelog-major-minor b/release-non-auto-checks/changelog-major-minor index b196533..8e6104c 100644 --- a/release-non-auto-checks/changelog-major-minor +++ b/release-non-auto-checks/changelog-major-minor @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/internal-wiki b/release-non-auto-checks/internal-wiki index b196533..8e6104c 100644 --- a/release-non-auto-checks/internal-wiki +++ b/release-non-auto-checks/internal-wiki @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/release-note b/release-non-auto-checks/release-note index b196533..8e6104c 100644 --- a/release-non-auto-checks/release-note +++ b/release-non-auto-checks/release-note @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/reproducibility-checked b/release-non-auto-checks/reproducibility-checked index b196533..8e6104c 100644 --- a/release-non-auto-checks/reproducibility-checked +++ b/release-non-auto-checks/reproducibility-checked @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/security-to-man-page-info-transfer b/release-non-auto-checks/security-to-man-page-info-transfer index b196533..8e6104c 100644 --- a/release-non-auto-checks/security-to-man-page-info-transfer +++ b/release-non-auto-checks/security-to-man-page-info-transfer @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/release-non-auto-checks/version-restrictions b/release-non-auto-checks/version-restrictions index b196533..8e6104c 100644 --- a/release-non-auto-checks/version-restrictions +++ b/release-non-auto-checks/version-restrictions @@ -1,2 +1,2 @@ -2.3.0 -2024-01-26 +2.3.1 +2024-01-27 diff --git a/signatures/2.3.0-cagebreak-config.5.sig b/signatures/2.3.0-cagebreak-config.5.sig new file mode 100644 index 0000000000000000000000000000000000000000..fdbf9e3353a8735dd5852b1594354e1bb7c3601d GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*fj3?c-(R61$^wxVt5(TqTjC^AS0%fy{!~hBj5JeIN zvr>$FV@;+I0D^9Evlne?qQS(sCt|#67`gVa4;YZrz^IadZjiZg9AM5Fl9NuDd;L(g z&FIcmFW`pIpf2uSMXG4XO*XTp=PDjn_=?Cj??Ulzglg^5MEoC{ov(CO@X&I^k=_&SbK2pEm= z$xVU0w5U2fRup=?k;RFm<^v-=7j1p_kBSLFi6GH%D|&C5CQzLQyERg2;zbHi5TCEB z2E`HAgZKmA1oxlZA>XrJzsaQz?}HqL42v|+;2>1ttB1PS6An1bsU4@-s1J&RP&mrK z(WsT%{ZdE1su#g$PZgU}DU`kptkABdLg0u`2(vP_yQ+ULFY#KWBCx7sCo=u?!lR3= z1#?mWI=axdoptn(;m%cZG0E15^Hw+mp9NR=q=V3&F5!2q_hG;5G^ZY%ZD#|8{?Fvr z+ryfm1qlP46HZAeyVV_h!L{CO{ZFg7-w3c{079Ut3SJ6GY1fxb`{;S9HB#*RnzDcr zGU-k3EmW4k#|}>t(>%&H%~--iT-T?Aghiw!Y$=;2r9u#e%JI_ zf>*aS(~y`kMIFhqZepjqnQjEIm7aEGdd^pSAGKhdK3_M E_N;CdYybcN literal 0 HcmV?d00001 diff --git a/signatures/2.3.0-cagebreak-socket.7.sig b/signatures/2.3.0-cagebreak-socket.7.sig new file mode 100644 index 0000000000000000000000000000000000000000..274e8e511d81717770e4b85ebe15fc540eaf15e4 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*fj3?c-(R61$^wxVt5(TqTjC^AS0%fy{!~hBj5JeIN zvr>$FV+{ci0FVk4pZ@5#p=MAnB%={2LAyG)?MEy$jYUmyuCHfqeovKF_esgy{%6Dq zu&rvF7KjJyT-2;|Nkg$$rxABsjv{d9b_R~p6NL-VnF~x)%X_eQrXGRA{)Hy zCNN~()r+T2gBPip7Sfc2JtyA8Z|~@M6!;`Q>gl?;Dh9xd^I~UT<58VO#{ww`uJ2p1e-C!xr_dy z!TdS*h()PclryOEj;7V%Hv!N=O)@ZMFnS}iq?>j~Y{Ls3gjPhjXX$AaH$Fy?3eq%> zhmt>=2`ja(4kMFI!rg6nXHu6rnGLjBMUC23S3cFs2h(4)18;bGgPRT#QPkr%C?%h* zmfi!WR#{#pEGvCF`U(PDgIFH{>dl6IR@W6pN;T)ohQ3VC-`{QomcHY)oVU1ZK+Kvy EdRn&%eE$FV`bD2{yS8osLz6ml84%T-f}!GvPVdfu|-TyrQeyFp(z+PiP6t8h#G!k@UNsI z>o5@MLpYGCN<_`qGHFe5=O|Hklc;hup6}kum#9)G1y=i2i%AoB{8g|vMxnc)1vmK- z^CxGI8n8|`xuy|uXKOm_f9+#7nAZqq65L^ZJ!)i<@w#)vCtdqq)vM&}2mdiP*Oxs0 zvVwvXBKXkWdN>Xp_4_RlqqiFsp-S0@%m~uaVV>a?+ny`R^i%(lPqKq40yA)pGmh1Q zLmboYtiy1*rykfKYLZCl1McA}nm4?1SW-T}WO+m=eTCZxM_U|x#8&vi8;n{l~9SK_#Y&WCr<~f(^czt;VRa!&+j~d6&D=ilcyY2rZIKkHc?O z2XK9!5hQ5rQnk@5AXe8H5{?2>{e5rRuBu_XUh)g$iRx7ipdG|vd4}sxymQ>Z`P|&v z%Iq!5F6mrXzh5b%|6PI|t6~`96ICAM5J8%IKSNMdsEqm^r(~Gl)$FdjUv@ER-PZM| z3!Ga}Ul3sLZ%{9aH@E!*QF;eAQcyFim?vxb6YC9-`Uc)S{qn@%WwJ|U z=eALOpD4cziVP2@eSHkgm-Ok(>qUsH8p22gT_eT(4ENH>>sl&HCxEJ#242_z4h%E< Ex^_eog8%>k literal 0 HcmV?d00001 diff --git a/signatures/2.3.0-cagebreak.sig b/signatures/2.3.0-cagebreak.sig new file mode 100644 index 0000000000000000000000000000000000000000..e106209e41a6bc13a33cc9aa55e3b69e7b2586f4 GIT binary patch literal 566 zcmV-60?GY}0y6{v0SEvc79j*fj3?c-(R61$^wxVt5(TqTjC^AS0%fy{!~hBj5JeIN zvr>$FV`0b-|6sTKs%81)qQ(2WTT;zI;D3i|(&bmgFIMKXHUUH#P8VWTQwxv31z{)GG*1|?@P=OqGu(-c||L}F3ukC8;C=2;C0-2qv zNyyrDjgI2;(Sjt${|gcD%cXlm69&36I+EXi|5cFyo(-51B$llX+QTcB>=yAin9pT! zWo#@SSY@vb6AYPts>DbiLtLY=fxFX%MI-4s;Wo9VgW^OuIDQY;Zd6Z2;!^Tx#X20~kzP7eKjm};|Ek*U% EY6-U&D*ylh literal 0 HcmV?d00001 diff --git a/signatures/cagebreak-config.5.sig b/signatures/cagebreak-config.5.sig index fdbf9e3353a8735dd5852b1594354e1bb7c3601d..62cebfaba585b711bc49dc7839295f7ffd85c68c 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY(8psQ?NI5JeINvr>$FW8Cl$|45rH8WFc5lrS%z74%wY9GI|z z!VFw8XeZdd`n!c2nU}Rv^&>GFvX#rXfjvv$5L-XAnuQM*Qfsy^H+D$6QzdMlcU$C^ z^sE$o8rkqt(JEhKNk zUfa$2gL%9N{gx!x0+lGSA|LYpFR}hVXB`6MZ@R0cM6&}~QQC?vuog0)IJPeyBxgW* zSrH|vV7k@<#(&@xNTMp87L1~YGoi)lNkRYcK@0n;!5+CqzUk)J&)>I!)_I@6KkQUv zRhOQ2$u)7cwK$d;8mCp%Ka0)yD*2mN6dtpZA09C}{nQ}1qiGmzrTdjnG9B$BM%<%0 z`AVaf_DF!cMfS6zFg_pRNHPCV&B+j2SYK4F(~nH!Eq|x1DxI%_vD@GsS+X}_UjgdZ z(GB&RGyD4MmyU>umCFKIbu5wpG;xPo2I|~O)dY#K`B%w*!;}}ZnT#ITHnhhzXnov} zZS<*j_hBu-vp+f?4rq^|En~(C&jOHnX0s=lQAo~XOt0X(vR=f4J!w*~;`A9c$Q*{% gFw|E12N$GwrGC{V>oS0=_oj{7J(bi1+ZL418$(zKi~s-t delta 542 zcmV+(0^$9(1hxc_BY(4t!~hBj5JeINvr>$FV@;+I0D^9Evlne?qQS(sCt|#67`gVa z4;YZrz^IadZjiZg9AM5Fl9NuDd;L(g&FIcmFW`pIpf2uSMXG4XO*XMe(zuqqwy6zuHhHD4CN z_l1c?xtt4JiqProdCm)qI`}${QV1B0@yShrytJq~JXREXyphF;q~-%7Jr`|#_m7GR zL5U#Ia4ULmnkG=42D>#(E7QUE%-(6*g*^pN4sRdO-O)`;^~I0K&r zSNNoZ(4H>gcdYkezw0!o9-M7w1BL$2h($ diff --git a/signatures/cagebreak-socket.7.sig b/signatures/cagebreak-socket.7.sig index 274e8e511d81717770e4b85ebe15fc540eaf15e4..aef73c01926681303c84a6e4ec26f7a8fdbae5cf 100644 GIT binary patch delta 542 zcmV+(0^$9(1hxc_BY(8psQ?NI5JeINvr>$FV_&Ne|8g17?vtmp>3vx=zNZM!kMq2S z^V-sec=@NKc*~G3Vtq>kgBHDzsT0d2rV5#w{0NKQScyx+3Fk|R-4%UA6lKTogJ*LW{{MJiaAl0$KQ!YhYR-}d102pz;c1_)J+L^dtdK|CSZ$FV+{ci0FVk4pZ@5#p=MAnB%={2LAyG) z?MEy$jYUmyuCHfqeovKF_esgy{%6Dqu&rvF7KjJyT-2;|Nkg$$rxABsjv{d9b_R~p6NL-VnF~x)%X_eQrXGRA{)HyCNN~()r+T2gBPip7Jt%|ggqzT#BcBDc;l7- zCi{ujy8TYSn>a$M9#zxz?6^6yrvM-YldOcuYS#wm@fXnpcv)Dh>)PD!$sig;4FBUD z1NA7n{MT||H=0we2h~Z|=63spux>tr_86lppXr(hZ&RrHs^Ejy*Up+RAr$Fe(bxM3;f(a^reu9 z2xK+wcQGF+kofvVL*_KRB9A#V)7NF>f12W_RlXMb@8^PnR86k$Td{u+dVoDHSO;c{ zEqH$O0!0oOKP>St38T6oD5Wd9u2i{;{-VMBIroS~sef6NGpO>8rq$p#0nkBBGB9Q^ zdLy%>n|4TS!wVgRRz$dG>1h-$FV{T{<|6Ks-TbRaT8r zP-<=GyDZMhh(G0u$8VZ(2k36vHjKq-;c1H_3tOsROcZpS4u78198`3pv}0Z2>Ha)f z-}m#-r6x{1Tp~%k@*JRtI~+_HBw_`I>Wvszoje7i6XDmU@?^38*B0A63!d-hyA~UQ zZvm3<#daHk`?g1~GoQWZ5pqvT;;McP_qV>Oc8&<62* zd*>mole0Yp%YXSU*lZ8>P@YRTFAMcC_!v-@2Lh($ delta 542 zcmV+(0^$9(1hxc_BY(4t!~hBj5JeINvr>$FV`bD2{yS8osLz6ml84%T-f}!GvPVdf zu|-TyrQeyFp(z+PiP6t8h#G!k@UNsI>o5@MLpYGCN<_`qGHFe5=O|Hklc;hup6}ku zm#9)G1y=i2i%AoB{8g|vMxnc)1vmK-^CxGI8n8|`xuy|uXMbxt?0@ZJHkj84W)j?C zeLZSqlJUB8!zW$)Ue&AQ><9lbHrJOt{<4CC6e9T0-g-C=9rgPy5Tmyn6`@Mmhs+4l z(P5t972BRG%JftJkx#ONDFQQajWdqbfzWJDw;REa#&J6 zzhrqtD1C+72Y*Lf9DKx9_`(~ES}o+545Qe>&=u%%HMLjbCtVw?I>bRGrix?+`I>?a zzL~AYsIkLZV$*q-yV8oIfO7~fl1z`oZ&e3yeV!2{XzWt8(JLTU*BBCx0#p5cZ`!V^ zVY^=P3*(9ERSlpW#9?`c>rcFM+`#$V+}g_QEy^zGTz^-;Un!&iU4k8}Vi@8RRUYIJ zL7IC%Lr_$xjQSp@WSHO8?5?|Cb}?z)*7c_goLf*|5Mb|bP%nx%xBUZAdIvXBP&2ET zCu{i=>mr<(wo!ebD8CDe3=gM$eGJW)^y$p&MTo2# g!bk;OBNxT|4ENH>>sl&HCxEJ#242_z4h%E$FV{;4-|5@q1Qne+3wGrkR`oF!b&U&^; z#9`%VL z(gM&4CJh~yB9gudHiY%GB+n?U%g0kTt)MjeG-91;E>3l;kAJ}RzG5|Y>f%#u9PhT8 zRNtoFK0-LgF-Wq;fvMosmVQ0jQd`2Bpo3T*g;zz1G~o6XZlC~v)|uk&9?dNWFJobumJ4!P!j8 zFX8CJj=)@FXn%vXXQ8iV$UIYk7oogtg7f`s_@Yrv0ey)*`rYy!4;KG;=3vSv(n^tI(EryNaox{WK%D*|Yd|tv=rkcwa*~HSHt4DJgzsIj|96>?&DG#Ezje zmxbsoiri6rShhc5xbZ2Y(w4A4QDlt*Z%1%TE0aV`Ryf zYlKf}5=YbwkPJ1};3TUE3s6B_=@6tLp9}|8I>~rkVMClL_1+jWhUjN=CX*H=?l(PR znCcpQE}l$M~GUxC!rsJ8&pI$!MB)FG=cHK gk*_W+%on}+ks80OtcWR@@05CHeO1#_hCj$e_^lEU{{R30 delta 542 zcmV+(0^$9(1hxc_BY(4t!~hBj5JeINvr>$FV`0b-|6sTKs%81)qQ(2WTT;zI;D3i| z(&bmgFIMKXHUUH#P8VWTQwxv31z