From 498800a3e2252f511f039b17cc13b1a4e4424af8 Mon Sep 17 00:00:00 2001 From: webadderall <131426131+webadderall@users.noreply.github.com> Date: Sat, 5 Sep 2026 11:53:05 +1000 Subject: [PATCH] fix(windows): crop window captures without padding --- electron/ipc/recording/windows.test.ts | 7 +- electron/ipc/register/recording.ts | 5 +- .../bin/win32-x64/helpers-manifest.json | 6 +- electron/native/bin/win32-x64/wgc-capture.exe | Bin 119808 -> 121856 bytes electron/native/wgc-capture/src/main.cpp | 4 + .../native/wgc-capture/src/wgc_session.cpp | 69 +++++++++++++----- electron/native/wgc-capture/src/wgc_session.h | 2 +- 7 files changed, 61 insertions(+), 32 deletions(-) diff --git a/electron/ipc/recording/windows.test.ts b/electron/ipc/recording/windows.test.ts index 5d691cb8..5881eecc 100644 --- a/electron/ipc/recording/windows.test.ts +++ b/electron/ipc/recording/windows.test.ts @@ -115,12 +115,11 @@ describe("native Windows window capture", () => { expect(windowsCaptureSource).toContain("CopySubresourceRegion(cropTexture_"); }); - it("resizes the crop texture when the selected window size changes", () => { - expect(windowsCaptureSource).toContain( - "nextWidth != captureWidth_ || nextHeight != captureHeight_", - ); + it("maps desktop bounds into WGC texture coordinates and keeps the encoder size fixed", () => { + expect(windowsCaptureSource).toContain("normalized * framePoolWidth_"); expect(windowsCaptureSource).toContain( "d3dDevice_->CreateTexture2D(&desc, nullptr, &resizedTexture)", ); + expect(windowsCaptureSource).not.toContain("nextWidth != captureWidth_"); }); }); diff --git a/electron/ipc/register/recording.ts b/electron/ipc/register/recording.ts index 05373691..438b6eee 100644 --- a/electron/ipc/register/recording.ts +++ b/electron/ipc/register/recording.ts @@ -562,13 +562,10 @@ export function registerRecordingHandlers( setWindowsCaptureStopRequested(false); setWindowsCapturePaused(false); - // The native helper currently does not declare DPI awareness in its own - // manifest or process setup, so we keep the compatibility flag here until - // scaled-display capture is verified without it on Windows. wcProc = spawn(exePath, [JSON.stringify(config)], { cwd: recordingsDir, stdio: ["pipe", "pipe", "pipe"], - env: { ...process.env, __COMPAT_LAYER: "HighDpiAware" }, + env: process.env, }); setWindowsCaptureProcess(wcProc); attachWindowsCaptureLifecycle(wcProc); diff --git a/electron/native/bin/win32-x64/helpers-manifest.json b/electron/native/bin/win32-x64/helpers-manifest.json index 62ee78b5..5fe298ae 100644 --- a/electron/native/bin/win32-x64/helpers-manifest.json +++ b/electron/native/bin/win32-x64/helpers-manifest.json @@ -5,10 +5,10 @@ "helpers": { "wgc-capture": { "binaryName": "wgc-capture.exe", - "binarySha256": "4d89fdff8e3343998c7a3b4d75d964c1f75f93594aa097c6681e477d25ec9f01", + "binarySha256": "c0dca95216a46474f1c71e2274228cbc78dd09c49e1539333a76183b115b1c5a", "sourceDir": "electron/native/wgc-capture", - "sourceFingerprint": "c6dac250c9d16f7aa881998353441b4ae3fb59731b802e3b8491a136e79726b0", - "updatedAt": "2026-07-11T11:58:45.856Z" + "sourceFingerprint": "9d8ba313407468ddff200317b210e74953e683c9ccd2e27104dd9e94b8efa7cb", + "updatedAt": "2026-09-04T21:09:08.014Z" }, "cursor-monitor": { "binaryName": "cursor-monitor.exe", diff --git a/electron/native/bin/win32-x64/wgc-capture.exe b/electron/native/bin/win32-x64/wgc-capture.exe index a882ee87abd419a1fdf1058fcc609a99a77574aa..5ea3098e9f8140306b567bf796f92363e7c0c0c5 100644 GIT binary patch delta 41301 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Ⓢi(f-G&YDl2q&rTVWg1EIf#ioAc&&gWNHYt- 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�@MRvM@8L=Byv!yZsFL>gWgQQ8mYUCI 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 A9{>OV delta 39136 zcmb5X34Bb~`#*lq%}h3863NI)CM3ij1hFS1Oe!HX_ALlvX$3*76HS6KLOAqlt4gc= z&{k`!tyHXuJ=E4JOip7We@p0nJ0Bj=D? z&JMT2?yrtzx^=O!mfKcGpUw7l-p&v_e!b6IfP=?x^m$dJ8+>v_TIlmS(g#xueYS{n zgGe_P%HHn)-fS=Q?u%3!zrp7m$T1oYpB%M~VDIUB%o7_BPJClyegp#E)P^AjMUMh=-y=BP+dl(Ak z{J1WR>G(Ig!0`5HGRkI!o4XZfg_><84r8xSplTE<=8g0%<#$ZHzrJDOQ9-<2v!-o8 z84i@1Z5JHIT@aUB>BxH7?6~~!WKAi#;7YcgPPE++m8|A_^d{4b|1B-1hO~J8Sl?8B z5Xu8xn>M`!LZSVm$C8v+G}klHhK8?d1XQA`Y9d+UL?iC-H1T}bxR_~AB($OgZJX@po`hWpx9|AbW8yV|sNAYt!$we0CeeijmH zFd_3aGV`(%J76h?@jX7yJJ@HopU~AsOxyzfg+|=w z-Ozos5xfQZ2)^4pK)!F}=e@(_FgvgC4rOn0Z=a^@Bi`AknLO0U(|nq=U8l+@vG4wi zy0t<~J3k=vin3gjtcx-q8qC%?ndXB2?hfPMetfS_FFDw6->*JNj5Xx3zQ*=ro_Y>jgV%9XG1jg)r<@bN*$_P>h4cIu)3F8mFl zYZv}3fUopzCie*7R|A7v{r@g^$)Csh8riS>KYru=c0+u!tt8%XK>vjpB460A@+4z3 zkDVH{jfWUR{4%TA7HEW7f)GddnaTZ#tf_?#Zm*&;vuJZy&t}y4H%hKE5uUH=t6Y-%BycT}3FPd|IGTDrqF&eZszD5JX_Jw`jKYU4G zNP}v^RE;qHABTg78Uy`fs%c#`T01B0CyWhEpod0dPTJ{e+84-DWmo^!WUj2H?bK-7 zoV2uR+5(L>OQY2ducjsP?SU=jg8Jw}Kle-UEf`ED{&Qfn2s12YE_e|$5B}RQtVo-I zCWDV`e??`yQJ;4SYAXNZBTDyBk=cAnP^e!F)rr}adpHNSma>{Vj2rpxpvFP3*I`o5 zqQz2HmO1xRl@=#_(Fp!iP~&D}L8b}3JcK&MMhp&PIhNtGeHJ6kBBH~X%{vA+mA85D zF~Nx~f~a0+|G5!R?1o~%jSi2Zi8Jn0e$j#-9Y!NB4Q?bay~`_tbLBnm@J~kn+|!Ym zR%rA&)FBi;;a(p2kZ%i#l5aiapNC}1-?$McAKB2miS`I>EY9L7m*!d3X1ZL+$| zpLZBvQ+eNR7=-P_v4$h%A$NFSqk-~Qb@;SK4}BNeC8^I@T~8_Q5N%D&1;)cXBXmQ3 zvnNJaqOHU}-M{q!+OGS8PcwCrLvHc6O#=)+eNW}QT6$Su3QjQ`m5f`71+Hd-n#MtcR#wTxeEb|JXS*IK#8QewdnR*qJw zbko;-Z{!tu;60w(ytDt_E0UCG``Tnd+P!yC6hF8^|!f7d>t?hf>ns^quN`29A`nSqb(FfM$> zGb*w3466P=)ZBFzYIg9=_ya1IoDwQ#sd?Tk+61GTqdWLa6+ZETScA-th~7{5>gZ1L z`=|No=r}fzyLRl*=!0LV4$RC|*d@k3D`r_I-7!Ts9E^PJc_Z`ZZ92W6 zdwNm@gZE+St7gBLcP-2FNF;=ppFGJw?6j6GSx=hS`J z?Su$t;#EKit+{CL;h*@%&NEpN*T+Q26HfA0G40qmJ~qZA*E`8`V%oAxe0NMRTfi^I zM6zuDTTH7~b%xXIObR#I`DJK?Wy7q3_3w!47FE&bT;|DLddlA%=LKD&*b4qxm%;Mr zS|&UJguw0+a&C%?bDC(rCkHvmi&eMpksVX*Ei%hFY<2PR(gA3G$+~4 zVvC<>!`QpPKkpXhI`tSge-?+d#cmGlT;0SNhVOZz-^7diq_iD^GWm|BuGUWr(fAsLlBx?uppaT7l=qEKX?t_Ov&@FtW$t3SX%&5h zT`rY5sNccQ#1HB>w5rUe+GUP8%aA2wP)bJ*HuQ}En=FME&wmIUYSQ3XzaB*uZ` z8$yQd;mPJu|3b_KNJ{ttt#5_lXz-B?2ffMqHtOn6{8HllK&cFM)6yOae6^*#V)>XC`pZur^7mhu zEoXkr8}&EGevj=1&8Qc}yeTC}n^6}j-|hCCF1i0YvU~*jFi?gAW=FTnbDIdn?JxOz z{dS3;SZT?Q_A|n#U%k8d@DCe(aaeV!!Nrl)sbIx9zC}r^CB&1nq@K4TQ~ApZB}! zV!f+ab{ydW$+zTh4)e#!(XRbIfSYPbZmN#%D=KUI+`i&4?>`{cI}w_|9C0KkiWcBE z1~g;S_^AN{vAgjd_yU{4#|}IwAODj3r@Sdwe8CT-G?72Q!SAHBkiY(dyA6tvSKi=l z1}#gCxIsFrr#hDldp#Y-{+~+{PANs$l(^A`^TJ_T0o>JF94rLCg8ms+FdW(pc_!>^ z;*L)O6nFF`Bp44JTX2`b|1q?{{t7B4nhTPDa2Wmg;lXPSt5F$noq_w^VVuW@y|~0z zg1FiWH03|M7%E@B%H31LCT%yRPeR{82Nrt+m}e3hpJ-&H4H zkjlqmC6zBmzB-a7(2ng6DVU-P zT;Sw;Tji6T6&GoIC91qVPQHc2XIb`_57Vg{ZqgW|)E1XJ83(HZQ=NR78efdc7uHL& zU<;M6u2Vs?#<%-3(U1{NK3V0%MPbfd3z^!aF>X2`7}q%&zl1x0WxSjMD={{x#amUr zb56d!Dqnz;uTFI-3uldali`hx%|J=CtQ^ z?c%*gHk0pN;Ta>%^50kZ-jU-PbhrYQ?L%-^OYSAPk_P&ew|KKr!<%0^uj<%N_?#;Q zXj9MiBag|4mj$>Q+l+iD+7x~`Nk@DU*`B$TZ+1!1Vqg%52yLO@u zuWnZ*skgOmPZ%khcO09b`?3^!#@O+JTp8QfFy#ViV|`s+HD>Xj#)kS{Jxg<+oR4uR zc+EDigS^qW)~SQAoi6_lo&khpBG9#z{la#1i7gcePTEE0g9qfkRpbu^8J50epJgFo zrDC^y_q5>a#NQg{Km0QlXjWBdQgxy8%h3q6%zsoi?<%&Q)odLg+i+0jTdVR_Ug7o9 z0zJm4(4#9nDlO2`QiXm(C#dRQd&l93vu)gsJ}wk32vj+Ktm4=WjzrtWLsc9g(oP-T=%sA72sEOE9sHxVNLPF6@Qfjz-aD-R56Q~5U6;ImhW zZBWfOQLXa+72aZeuYg4YO13+UBd9}c$(c0Fyk6tW#xFFSpcdl3Fv@JZhnsxvIU&T< z6gbRSv+WXk$iDeq82whF?XubB7jw(69Y$=%Cd9EJeC33;*q0xgkmOfHHCSih($R{G ze6#IWhp~VMOblsg0wKwECed~i`rFrRha_CTUop45>oCUiK@-DSKR$0_LZ?G?MY!xI zlO7${JhKEBo*$=S`gb^Ow&qJZQu@z?4)=5ake7^sZTegyjMshsc%t6`rAU(0YXn%Xt zr3hvddz`O1=FFYBkx=z0rW91|cpSx6ZV~=!&$~27(3|$pFopJrDO9kPQu_2EJKR7q2wJo9AO5el?+=#;lib3x% z;E(|mISl(=L9LL)ga+BAikv{?4T6kQhg$dnj$>-!CPbYlsFhA?F;NSQg<>v47Qykh z0-~dBB*eC{g5m@ZJblnJ+}8ec*Yy9r`ppA@0*9bg`|tFle0(>9BmskT`l zy1?kCmM@_4Wt&A;c{ufm1rj~3+Vr~+(M=m~Lj`m0pN4tSW?Mm##0#dhluxYVN2Uyr zXRYI&8N=QD*HL4K@DE-JawAT|aw}hz5fys85Z&-1#=I>*5*=eJxDQeJ=L`c+K+9G# z|01J#<0)N5l|#}{t%*j*_fKfl;r2>&U;Ylp!>2ZHwYitth*Y%^9nVpXUQ0hkfvc~J zM*NA?+|?to%=`{@xG-@fH=&>VCaBOz6NEP@f4*B|?l+{NL;F(5l4Yly`2lF0^3 zz9jThr=evv%?(4oA2AFo0+}AF6cnUDDSO~ZwZ|e|0Ms4Hk56wAB?x!sf%`xOo`W^P zsJVpY4feWs2wd$p344u%O2S_2c;Jkt79l`CUu=_|rQTCZt)Nn0Dx#E&vs70gog-yz zl-fBX)z0~kS}cW%y`vVpC?+z^8X#$eiR!)|p#o6YAlbhlNHs?O9)4*?Xw;Z<4hNkS zC!x2Uy@nH-=tZ^n>U35mhz{tbo_Y;p00();uIU2 zhyJFb`C;gdLYyA*j|f=*9JUhs0F+|9~wzZ_u^4IfGNuOVXLg6Bj`1)_$IdCf3dFe>W9 zlVenH+)>!S-yr(eKpug-Utb_q8~+3wLl+ZuZtk%dByMIyKLI;r<9xn!W~t9B3Z}Q0 zH^#QLZfESeJo&iH5v)5uoEgGG`OVCx*s}eTd8mFcRxF#>PPiGB@10{jEz`)qn$<_X z@d*!`9n22#9 zZ5q|2_!oQrZ*`4+XjSpEX9wbZwx(9ght-hTgg6U~x>tz<Sv3Ggq+$I(e;4rtVx>U?>KM2vf zRKVB2sp?Vz=c#n+QUPx`Th*lk-Y(#(F5L({QQ^&xplx({> zJFn*J7B^_1CwrT)qd>d9LG#frd&AZI*y8ZU4{Y$w6$u@lyz(jC%4c?dL+z=Grwdn0~)Ns#>ODt>3l zI{%ELRLuo@`YNOt=w1X2TE%mhwvwBy;(L~c%Jo+9YfJmda~APnONQLXDpd8M&0Q<2 zko+@NRZ_LNmG7~H%a2#`Tb4%hu9f_EOEdZ3UEGwDB6pw9XXk9Gv;Q!aNG`RXa^=Cx z0_9CBc&BCSJiQ2wial2FtIJ~L6U({pD^u&0{0Fwj-k=EW8@imYdL`NYB|_QP&f{Od z(pt`$&+Fxe<0%2--Eu>tvnN}Zp|`LcFM|ms>oU5a2e3&^wo+m{VJ==q+k);0c-qW& zp!M=lzzilf&!rFPFy}PLk&bTD)ms_v6i1 zG^}?MxVgCJ>FsXrroYNlSF~w8(hZ}r62m0|r^GDN5h(7cFq|;%eF1O2{mAA97itd@ zFWAS;<{z&x;*s5%6)_!up=W!!i`=Qb?r7rIfRC7{{pkEBvnYkW&L@ufjs?Fsj4$%` zD>utKEWC8(GWL)Uwl?qa+fq6XtIyaj+kXJmp(vT|3O=74XVuNX;ojbJm&5U}Aw6d+ zsl|L`DL-Uw^;9VZVhlQ8pgvd)WefhWXQ` z1nPPcHqw5Ocd|9n_c@Pd@kiFi@%#IVM!ieP|8CTJkkm%4M6On&W&&Y9|BGnUkq@X* z<3Ij@)J3BLsv7l^>RfxghDH@;i$bW# zKNxGbs^1mf+16P8yo8Uk7505$B81|KWI=z(ONTdypVvd0efWG)`#PGIWVbTf@T#{} zmyiYbNq)Q7tdN97X01>I=wAGmvl-9c+#^zcPmW-u0GY0%&PgGa3ikUzV?i`Fy@d+P#LYP#vNcNB&hO}AoM zIGy5QdfeD?V@~mV1py77*AMF2+yBk$u4x?dFJ4l@W2^t6tltHp>~9!uRmx_<-NMp) zc0$0>IYQY7G}Ng>LO^?7*~mYIvRlrRvUM#Gr7CNbc=?)Oe!8$e3*fg3lY{6{m@O|H z{ViEn2+zK@P~^08pPiMLztXS{`-u-V!OuLe5jSCst}AGy9o!vIH03SH6R zodHy^Kb-WS>&94^DUxqP*(suI2P*qaotv@t7y0@1%~?60$s>3mZ=wGJyRAZgX?;^1 zglF=8coq2|$AJPbuHZ0F#Q)x|=G&}GZeAaPJ0fkP-=s-&20p0q29#N`G~_wg{3 zjfq+uDKTV<1UjwS7K71>s}el6pQ|qq(F&WNFX=`lF$%9ZQevsFkqWCQ%VqmyY_mYa zxjZAux;^|58Q12PRFJ1;3ye43rs-(5tyU3MHLYCsso<6W zFA9gEj{m8!FIDbTnA51UZXqQ|?^vzjma2{sddCX$issUzktFm@Y!dpW%BIQGN6EIQ z52HznNt2=p!HeWHMNF8X=!^aPfP>Y>0zij_o!&D zRD)WNsI*?hiuJ;h6rN$9E-FA>!|iFvnr)lIcaTMLPiKmY{?X&co}!T+iOK!TQEjFZ z@NG@t1^_X+iBeLN@@Y-rqnd2nVrr5$)C5-41QymT^b!F)@3lC~{4LnsVfQL_ce4S| zy^f5X-cll%G{OP`d=ssm?aFVsEG6aKr|KhH*Tj( zZ5n}xO)!al-FRZFq)Y$22XrNio7$0Ec+%^^K`+fD5_L7YsJS*e=n=+GeA(-M9w>@-bFyw6(B@#{i;u~!ydJE@~y)fRoPpmuphzB~o zf;M86`2dF?`@b1jzPMNpXuTV#9*hccp@#L(UM8rb7*X4))IVp^I1w-(v$>g^ahNaP zY?Xh$gHL|KSS;`G=KIl+hP+mA0ZCn^nhbf3kvl|%RlNfTDz$Xjc0T2k|K$^KDo#~1~5%v>gwd- z_5niDfJpxAt>~bWpNQ!r-1k@9RgJBF@mHqAmXrfhYvak45C>Uv9Dl&^A>6;-m2V2RS0==<|rFA0N zWad9?tv~z(bg<4X!}6727Y<6ebKFCc-A(pzAuOTP+^rI}%k3p)xl`3%gtm4z=bnPD zb*P%O+SP34cee&vvZp>TI=h1qdkE(^b3wvw+L=NuPPGtw!M=^q)(+&-a!7;R(<$S| zj)6B57VNOU+M3Ofhx-!v;2L-X;hjJJ=e8Dd_N%<<+l?E%ItB9b@6hrZ{2@a>_3fI5WoAMcJj~_ z+jglF#9-^MEyR|wjVRwDPRlX@Gm8|iOW z_seu5Z^iiFonv`QeiW}T>iGVh$?~XF?(%*w`AHs+f4{GM?M1%&{m6zn*hN>#%>9WD zhCOibu-6$3JpX1u1Kw{}Bl+1NK4n*od~y)qwyTL(3enV?rG&x!>aJDtcmp5vQHK0# z3NQYsXP3^j`L}rmEP5622G zXSOe()XOEMO0CL)ywUD9 zmK^%dik^Ze{GMR@CIOz?_9V&n*tTS*x!|>xG$O2H){=zp2dK}&6xrv{^IEhB&AU7j-t$(u53$-#$JHs`!3_D=a1EDWU7Bu5 zuujg1vo6K4K4E?$^}Q{@g4DaiwZoZ`jK{ZqVT?)~<1mVi+f}g~ovj#t&Z3Xp@hePTAWD0*TTapH+# zxPBIJK(vBkRoU^l%P26e-@pU*HkR9L;NAB&k{fN{qxYKRx*Pb?y@3`c>fAwf;;A#% z9hh?N0<^hgIGIwk(FhnBF#Ng}l#f7(vkgrbG*(6HwH&ndDlJ3M9%MVq9i(#eR2s~W z(REIx(F+i3UjcC>h{)%T(@cB>bh0OA0KV^|J)UOIb(N|;Tg6wK^8nT}YI3A%&H;F1 z0kUqb=gao_db|yz0J^ZAzqzlmd~iKKu`kr}9*~a0-I}SXT(a#nxVHQkKJE~NlK?JA zWGSp5E8<|Ag5(wUk$uEaU3rU^GF$QrNJ^Fl%0NW8S_Hk?c{G%DHFHzuhiZbh%y9}UAH%XS59xV}p)7!YMY`4pFV0f{Yt z6EC_FPw6oJ!oki{X8bD}SGr2HcUczNd;LWk=IRWH1OhEX8z*C*WIrrO*F{^sh=ln` zE`r)luxR@Q`}}^$8Vfca9k|zlZ4tW>eGVz!0`Kr zI>q#cs^*pzw6H|c(3nl;xA~)vB-(-6ZljTQWhh1?4Is1-*Hl;RGk)cR4>z-<#tjii z^kqMlQAgVJPw2xha=m%sw}DB9@i3**;DG5u$?1JZ<2n-VHx+&m+p~NQFIDA!vjD`b z$U$L4UK?^>*ew|H!jXd)>VS9a^TIa~5$O&LefVQK%1+%V1rM2@FZNsp8x@O2b0DxW@%FdNKg%+`LHmZX-IiH5{qKu$4t>1Q_NQP1TZ&q0h?L^qP^e0m!>%7hD4ipvMtt~yv^Sa(R%C5?5drf)LS?>IG@$Rt%w(X<4MuY;V~G~=4GeLAU1AX zGxZHc+U?i!c5@&=+qz~@7CT(uec?wNvM$~7NsL$bm*8&KVh0EpTY@K3!o~Unsol!! zkOk>YIAlS(K4ag)Vk@wN#8_6wdz@@j*NO`0`Bp%=+Y&ziWJkGlG5_df zf@kyYs5tj@)Ywz>m4p244DNU8qCCUQzdhAazA>K%o^I^^%_5SzXd&-&I$S=Z=TlF| z2KJvJd~4oOGPn37=`H#y1y40ko_^P@U>a((f6QM#6X&u-$N1heon@El{Nb4;meG^R zAQj@W<0}+KtIsVal$V?i8x83rY_#+R%@ChV#F}|PDkHTbke?G?Z<8d(;W zvHKE*-fYDO)m4=DiSkEpyr31Q(UPlZHlp1F4Xflsyy|4Euhuh%>NyL%R!?wMiSbn8 zL!zklFrpL~&nIe1vxz*pI8t`Y=4(nC@PguDp57T`eymAt`J>`7^0o|~T+&Ofm zn=balHzyev8+!C@uda39^R~d}$_z9D_rGDZpKK)u# z1HO>1#`T=Vw_ckf&z;3RK5rkL4AQUhI1WT<8DnQ;un;7)!|i*P_hH;H;x&Z{qc9qL zy(v3v)V`UYx0MsuyetOK*Qw}|_R(VSO#e*lha*60o%bJP(M1*FE(Sy6EftRHrm;>* zP3;p21G+8~sH;S>74N-@P+~)#3HO`bX~3miyc- zl#L$hIcc6M{DxEXwZ44ucb#8~OQIn{H`25PpudemFNU-f*aG9I zG|`L?v9+>0B1AJ{oB~$>sWl@DS*UjGV@>TDD*R6?4UPuvF!oI3ru)fmEBe!D+sU); zca(ic@(=E($zcz;*8|0SFY$JsDw0N?+hrPrIy#03j|zqGL5zMme{Wh|Wk z@qIpC+Ozx+D33Pt*MA6>e;LIO{;*WGjN+Z`BSLf-ICSG`qQB_j_5DbUtwa7|NWC4; zKeP{(TYSTH z>GD}_$H8#X{tfT``aEoKAHI1&Q+ZX&zSM`QtgSAN)aesrrjOyUMj2aT zi;vN9x(Cea-%yw}He9pS{2u()PrK!WSZ@8f1-?Js|8viPu2^N%2L|*YA$L)vl;!3y zM)&5PkH)g8eCnfyc$;*^qmFWAPyX4X2)VrHz6XyynLH+hKmKL6e5WUWr{WEHX?Gs` zcnq`fEsuN1fj#-%$072mZv3yuZ_4`v_r3naop}xJPNRVyL|(AJ%s>A11=%-+|MhEU zc~uu4{j^E!q%K(K3zF@$cQjSKTJxWQ)EvB!*7tvs3!UUI@ocL6;~bv#?2+8`bDsYD82OFa{M7Gn$xW~E^h!Xp_^HaBa#1ON`Hx}p z$kf+@)0(7@6Y+QvPZaSa5l<2ER1r@X@k=6}DdJg( z`PaJwdBs2e@{K6&@o#AO_9z;=a|2@Ye$J}rFun`W-12Nf0<8Pnw=@#A$ojLcvh+3wy3XqC;@k+`HZULgq2+ee+Uhl2Z}BVr?j zI3oJBq&QK;T*Ubzo{tzdtEvOfkuegl)FTa>)7wWE?8g95Wk0BL&AER$vRv)A+)>cJ ztru3N@`t>s;}!fhmYt4?Y{o_}*4&r6q52eJ?&ei~Zes!qZ{7hL7qkR#P(3@z@PU2+ zbhK}wLv_{Pxxw?|Nc+G~*0XTd?A{H$5dQ}=IFu|KRMNyU2W4aGxdz2y6Clow>yTP~WctdZGeuU5qnkb}a-`sT&TR2LT0 z;Nj-}eb+f+? ztI>qOhecjbuP8^{Sgc25AF+CjDpXwDS!2tT2*@F)HW?Xw&(V~?k|Q2EiCQiGhD2S$ z;YqSPnjUjlT@}57!<2G6Ok?L#bI7lUYVA9zm(ZEGD$xH%8sbtDi&zn6wmzR=oBkdp zR{g*$f-@PrOsoDy;4qYdqI!$fjjg=wA z{Cg?d)uBk~=E+Qr9@B_)M7-UEeARAt3XgpBKLdwHLP(Vbo~%iT4n++ciU@T>Bb}kN zSikq0a>$c4mDe;;$~;+1`L!mBR~@K5zlqYU4!lCkCd%|WY_NPhOgUbM1$*rcLv6T| zk98P74pV-p!?4PSDUIr~R5>V2$*Rld29BCVEIm?@;E^NV+(TcwI*hHtm7ZR#ffC@w zyaL;*Jdw}wR5T%;AWP~o=)1A#lp|s`9JM22zlh%xai)lmhPqyjsMa1W#mRe7EL^cweCE3e>+MUm@aeMSNYvjRf_O z$j=t}a1pN&m>dy55%J$5?kVB`5w{SWSt37K#FZj`+k_2>BO<;LY1c`_u_As&v?HrV z%T|IFiVDnT5w8((fZ)F-;?beX+x1v%hGPlN@>X8=W^F9-)p$`) zbTynp^@LZ$qTKz+s(J(kOZoNc0zz?Jbwg8J zNWhV*0+Bkvr>o&Ks$fHP`B;MUs^K(h=>2NAgy8*n%ThBO8q^3HJ2k|OsrL~0A(Pqm zBOb3r*;H?C2c#gim8a5GqyA!U}#Nq@Z!ZjwRh%0RIQo!LBm>am##xs0t zvZ**BQj$i%r-;|)67c+f0UizwiNrex>-s@SL9Zr@$1F9OW`Le1pY6^GZ+2?5={Garsy6j`R$WsakLNo$3a{sm9i#q{N%D13 zWa)Gmse1as^3|{je*+lvJ+q1dV-NGa8jc}&e>I#RF`*$i| z2CznhPVcCyCzkl4_f^57oS%CYJe=sdYB-JH`+KYCLhe&#L?G+HMk@t@tfS#eEX0@% zW?QVc!??s>xf;m)>!)LzCbo5RjFf4({n)`j1KCYxiTN0=mVR1VPfG`A>C=x?dQ&H# z$}LTJ4qjQL@?F$Y?-MFKSW6dbX_1!pRrxH^Jq>a4xLP1bOM7bRkDsad9jDZEjh5zU zX-_Tv_M}Qbsin)c^h2%uY%O)wQk_u1B1yYHQ45wHQ_~Gv`hq54qy|?URq3m=bO(L( zkKbu6y{Dx*da8wAQ!O=X=`=0P(b7$nqJC+IhS;yAC$;ptmR4$Mz&=%Ql9py`=|wFy z?N{kDwDgFU-qg}3T3TOgaC@Xwzcg4wWNGOOS_^;D;Ftrd;DuUxL`(nH(w+xZ`f@Ej zucdXxyLOT^Kugza>2)m)I!sS2@f&+s74Wu}ey^o1j%Y2?(%oA6R7;~jRq1(JdQnUL zv<7%x-=>ZZ0|$~mVY)I^e&YJIs%OP%0>*#jMTm_cVd~we+l(IvKA$2XEFYEY#Ax=M)IKs8;CroFY9n*sk(hq%XCCCC>@? zyF?XmU(TJkhjW0%|7=Pi<6@2@-0;@H+OjF1ysJ>S2 z&*#dgKi80to`VCUF4ocsT58t@aZe3yrKJ}&d?QW% zmuI#4AE_bkX%$s!1+HoEX^rk|*;WnzzLqZ5=&x$L za+qncT5+Z(aI029sRo-4?rhJF$p>HV$m+`ni#oHF5uRmB)H1tWmBC}!nmU=CRXC@! zuwH{#$FaJK*H|`@r7E+=GXLJ$8pBF0E!5IYTDnzBse7FNp@bLmb#a``S%yCrJw=&? zZh~BI*B!F~&n7rX**%5ny#PCZrL&dZ<8Z~ZW41DF9Bbrin!~7r1aHm+rfU!bg!4BX z`5XikBH_yIaV&tDl*i*(GqyuHF%BKMJB{h<*C?X0Go@k-Yv_@2l}S55yiL5mN=_P- zi_C)jEVaTYAlPtaT^a=4PGbQ|01&T^N2UT9#WIGuiw3l#GTJYvMxIba*@1v#v=n<2 zjRCz>lb^tu7pkdyiHP|F&)cv?`lg6|7JV^$!7d{z{QYSN2S2 zE#$59m1*hVH)X?QD!{<9FUO-&TB-3J{1y!SzW-whu8j#N4 zR^&?%gbXqlWW_FF(jjI1ROZXQUHlZ&R5YqE1C25x=Tfm)OkQIIZE4-X>iqrRVwBxe zStQF4BGG%KNxhsJB@34*@-*~KhSGc*dOVx-57oObWm1_|#$AjK6EMzSl(G%H4T;J5 z3qZyt$0cV5a9`n8%&a_^#!kt9FHqi}&N^9q*GbYR2uIiB4`w6u=8`mHqa>|C*o5%a ztCI9Dg1dtE7G9U6cM(p#DM?XVB&jRH{H>C-0>K537V08&MVR-2B)y5d@sAJ;c-R$- z&=(;EVHm>8Ur5q6g!nJ9-+A#%JgGofgYYrJQG}lm^6ua$h;S5P@K=&F5+U$A2)YkP zh_D8s)GkR65H6RaqKDZ2KgR#$gJ42vg>V+(Cc+bhhEF7^IYJb|c!c8!U4F%WEB04O z>W?r4VH`pRLMB2s!ZL(a2pnNE!n+6`A^e8$C&H^wp)`W`Z+KRP&<|k{!f=GU2(y2e zq}LGMM;KHoNfQx1LihyX<3A+nQ;R2)&Lgy{!=%Lsmk>Pgm0u{r$M`e+#r2rf#{jp8 zaLk8EzaXR;nN);O(E!6Z03i@A6X7hvWrWNiCT&G1Meq*6RBXtk)u9*>-sq;E&<%e} z5`DxFsl$E~T_=?ygBKU1XgxkB2H$R1L|7(cQOWQ0;tu^#82_X;S(CD}!qcY;6c80C ztKwe5rUgHgiACbXg-1mRIa?t|#brxnP-d9Q(;LDTq$7`xf#%Sv%~bkNl)^g_3hTcV zgS1Ul)WpeCu(|+tC%Dhx)bQbb;)rLrvhHQ(YdKV#ltd(KDr&NiBwR@?T%r(B`W%js zx1YoH0j{hzPRO&XIE$uJiV#>)i!ntoR@TC$3O*?Yy$8W+dr}3T3AnVbz-j;WR1UTw z*YUJjg~MlqT}s7VZiOw3hMPBYh9&DIvLfwiysHTd7cNYn0K4G}Xw4F{vnGZo#)--| z)xwPwm2a(yOI7)H)WWHJyMY@X00pwu|MALw$eT>^quvt;{BZ~T=)dOL0gt2gXnVq) zeh+*|HCzY6-3G2k&*LQvcqwemCpS{&WwN2{sB$Tjy+{k3X%V5#Vf`PvUx zsCmlzS*&T7@Oa_^bgadDF7&>LukxZZy9*+iRv0$G(jkVN_v7ZS4 zqcoh&UhGuj3(GCX{>KNAKZ0CuH&AkGS6K=)xJrifx{@Kfj%1i!CzE)i!IIWRd2crB zRKF7QDI4%AXb`y!nU%_;*=%qp!hZ$u9pGcik@*9`a|J5$OlyX{nH($9oNQUvxia8o zpPY&Y%Dg$OYf~zl1XNYo5dfwU4|vB{@!p)n+WQjkcA(Z%{kxDkvO)>YVm*XnPXWKp zK==n4y)rF}HI}pW%9*LzRzMkL#f?I z0Y;udbO*t`o(aCGO&Ucx4U|4}S@Xukq_e^}9*ATk`T+hsL??Nr8zrwNu9;N#T&f#n z>axQAl5`9Kb2S?<$6p`|OlLEMuNsy?4WZwa>)xS{CfywG3&|wB1m1Yx}}$VE5`u$u@5#C>#Gx zo>A$Vjh#nFWqda4Z=s%xUyYtiL?kCkff)L(?d2%Kj|NIijY&jXEC+^oN+Id>q>yMY zDP(Y!vSMni1dA}&Mr7V2ewgM>O35_%&+y#pjgh4+SueX@*7bFrrRN z-nU7>14MrycosPAozgW54N0kCZw4BK78#X!3s_g55P&qKN`28S@IE2Ri3JQFr)X$z zpvNN+>{HiOs*CAdx4nC&TbgSMwQ)P}k-HEbLC|?7VEHU;FTuz;?jvM5N7q&ABnRq1 z>W$?E{MW%IY;qSFIZ3W*uL_{jej|K+Wy(SpW+~&6^uY%7C2*u;O_-6P2g{j(UNTJ) zVeq6i@F^n@jYimtpmX=efR)pc_4KcAz6SZU0m$&JPv=P52dwh1pLqi=mi7Z{{OcbA zI*0ZJ>;3C{M*=9M4MK*_EDfbe8R#iXo`cnvAA-=SClQ@qqqJSb0u9u>GAHuKHOjC> ztWn@Dj6Q@4;Hd>t6|AgT#2Sp>x*ZeiU2MwMf=>SVemwz?1+JA7ms(dMcppM6;UMOD zm}FFy0liADqF>CKq?2kzC>nVV(Jcg>XVF?rahI;%>(EuMzq#n*WZ4hx(@CDuu99ba zS1~G|f>rd^KghTS!TZW$1!BqWQgXVd6dUa!d9>G;xn#;I%8tb>Qp|^>Lew+_(R2h? zQ4@3Nu2o3MH?r$yDc@ZVaFu*$nTYn54C|}M)M_ff5z%G@S(Go6x9Mdcp`DlHxn9+7 zKk?Dha|{{XWKyk@q%zf!JZGy+w~6T+ME@XodKRMkt)0mCw4rDXMemm?dzP>!CbCla zI*C~0p>v$P8_SM+ zA;_|?7<^c#1}$ZN%88}el#!eg&|+x7-azIdF=DjdrBoZOv~^`V*WYA$xzrbns*k(m z6K#}yu6b3|Df1|D%XCd6Io|6bry-(Y2pI@|LWAAyRclY9q*OHH8#(4%f?_SR$rQ`v zo@9Xu0_7!BUUql)90w8b5wv-p>J_k2mOpW;x4-^&zptbqIY`$OAzBXd463hAi1zA) z*nmRKw;*~CAyelrREX7W&|&J-bOA>}&hTl7emjGl+`g87xD8a=-Sx`X78c=K27pF; z#d7RMR$%_GXUe!7Of_=uF&qO7#Izn<8I{8tjuIXp$ccoUij2Hc3iQB{L32HeffC-q zip*<7hq2dDik9N25G%Kl#RS*d^C3vi3I2HwYu)b<5Tp+Mm8Vz)71l}8Q|#YQd(^@| zKa)%ww3*a=gVJvqd>d(-3gr6`7&!)+PZ9chN?3|=+EdrWrgfzxC1Y!EN;Acv-E=!l zK2$kgzTHmVBQtrO?BgRE<+hu1sd+B-77Ro_-}tasyj1v>e4X?Q)n82~@mypH4_-AwXlA(D4R zy|TKco<-{XR2SB|8=3SaDQ-k21VI*xSLn9M@(qKe&gyh`%xpKw&|cmAbq8By0-_}1 zcR>MV>MJZXn8t4=(H0=eN6@K8Kzo&UUSVC@62oa?xP<6ug!*C@R|tcoWlSUMlnS7z z^d1V;$z@IZABA_rv*o|RE=EudnEAO&esErXsUDJFH1dPJGixqGDX(f>H3AvAldNpb zWdVJqk8ngr7!70?4V_eUdQF`0-Z+cY#1Y^9nmFa(To#m&b{VH%grhLV$*`XR%F6XgEMzSq#6s5?+h>Aqf(h`N`v(7=KC{{*6D_RXJgY#L_4pg-JCd}42 zL~@A~*oZv2zhro#jug@?4J5HCor+B6Cgp>C)=<>B8gS%BM4J(?ySt{`&1e48if|Y4 z9ReMp!X(VBEH}LD;40O|V|!MUj|`vXE)_nNr1ubZ=c`Sv4WlD!@hD@Lvo=DNl-Hoj z2t;WJvS-dUW!rMr&60x~ipvO#feovplj_{}mUOB01@0;Es|imFQnst4&v26nx9*uF zZ6`boT^pux;9a{ccu0PgEWkDD>;NISE<+(H%Liw*pqfO@HqYagH7i((WbeG z79)r@9b3Vgh;zaYV8oeg4>E^dSAJc=I$E|~!4{+xqXRfnzBWuA4uklJ6B&BO=)(G3u9SoGSu!lE+@LM-XR=D98^px=O|jo#c&as86laPulIky%9nz z%8~-LVHg6;5}2jbI<;tl{w|XHNnM!?sW>D(TFHXCZe>jR24S-%t2XSe%F2SQbTkTk zt7^K^+lse}8S1aOUPW)#){Qu11|gs`A$*;b5Xr>44mm5nG2_a?NyqL5Op#(zKc`2@| z*ix62H*tGCff+qBak;Pw!TnA3=J@C;Hr%BQ)c@Ds8Gkobo^kwMic$nI0*-=3BByxT z$sj_3P8o}(XhG1-1JbF(C`=1Ono~F%^LR+c>9nH}0u@rALYi=zv?(l94((Vep>$Az z!-DI!4&7N`uyqVEbLMK80ELGJ9*8x7h_PfMLK zMsA(f^A!oY`ht~ukgwZ?8Hv7NuO6JZg`h2HbT8)b?Tocig1)|BL=Rq)V5%>e8Pccd zqYT**^3Uff1>eLL&K7BviUCfospG2ch@v~!WjZbHD zC)yu-kywI{Ldq2L5X+juPa0D!NX$pOq$x(pwUS9Y+kyV`T_;vDi+r@~4)y&>6O?^I zOSnHa_#oeth-H~Nk0xfH#U#y>CT3+|mnpW4SPd7_+t7c$T4EMrR&5OShvm<%6RabH zD5lQ!ojibO=rqMziB%GdH}#+J!&3~v)us3M$8Hd_GC{kk-PgKUDcX5V?F!rkBQseF zQ^OKs9vVhWu?@r$#9XG>9%41bYD}?qVsT=brr5KmS$bk|(=GWSv0hfo-DXqqEJ_*-NZshW3ycD5M)Gq#G!t8z`hx1`6r4M=1XpD5M)Gr2Bsr(%s|#+itbY zzp7R}$$s9G-(R<=Y|YAbW##kNyjr%jW$JtCORE3y9`zCb&OPdQ|At>sM{#YBI&IjJ zLG#z@6=h0G-Cp(cds~hiR4WFx6dzJshfsJ?w4+UR46_#Lbz#0DtuAbm-_xf02Blp7 zkw+=&fsY=Z~q`{&TdDgR4eR z>oJ>Gj22qU)5p{t|KVd4veA-*Il{Z*`f1*Xs}ubz;_7G#a`1$~iT=xR{WSEr-#`Ai zI!a!dc3kgXeq5i;g$}0Jc3jPu7qx@o9j1d9%?C{#>SUvtHidB~^yMf#p`WY#gnsVk z6Y2(StWNbg;igV~svVu`TXIa9rPhDbuk_hc_t`G-Z70?1!i}eNmUn6GTAI5^)4D4* zk#87D6$ZJKZgw}!c@@d8G@;UWRE=HuH}SVqGI&YNtV1@u@CYix$KjMQ^!4&>4=zDT z;!d~|$xcdO45cJ<#)%mr%Bh{P_EjU)&3iswW= z_!7Cn8?2BAcB59}l2UvYNgGLVZbtd6XbfI5;_eh?BAK|eG9$PQb;>P(VYE;>z>`SY zB;e~`XSwk%cw-9jw^i;77ch(W2i^z&@R*_;Vk4sjdYjATLq*lp+j%S@9T ztbUvVf}e3x*o?F|oK~p6G3{`N;bZVUQoq`XU|$+om|w)Cc~cA5A}3y0iPquc@IOfU zTIRWV=g#AbIS@JwFYG|F)CoBE3EjKkPmrvH57rsJzpO#k${U_4=C;vB_$nGL=Yd*{ z0$w;3dEFd{nTG;+CyXJv`Z%mvp!)!uHFJ4%L3h)kCxRjNk zy#uZybFQr}yr24sZpM;Y3b$5F!GXEhLW(eY(L&)YUv9u={ThC!W)1g0#z~*%-~#Hz zC*k%omIxn!!z*}GRdFKNmt7Ig{VAXEYAU_pd~_KvdqvQZ-WnR;f;frJVG;SqC*ls>C;z8iUbC2<*~{DR=5Mzh~K6t z3(#u%Qpl}rMe=B;h+E04)>n>7a%Bf{YacUAUpiZux1C%P$v@#UCm3s-N z)ac#@$M57SeGCkT?qU`37C0Trt+d1CNZuA4`hAojv9%&6#C$)>*RAe@2UGBb;5&BU;+S7tngVa5bvj!t>vS*%fAaWdN8L z;eK<)Hh2zY%jDqFDDPOj6Mojj!vx=-HfJ+szoI;cZqZk`7Fig~1Am8R6Hme~Q5UyT zOUSqn=$RYI;CzHulX(&T6M68$xj$zG@WQ821TS2Sq>WUG$iGHA{9WEFuoc;f$Kle0 zOd9WmA0X|41}`GH9qtsSqM3WVozC#__cJ<0?EC>DBAGYPYc)*}i;=(w36W^ca zVM4?veZT{UxbQWkNG1pFIIUkm0A4x6h0!Jj<$q_Ml9hmcIj-_^eEvTqaF!Q@Kln8t zC%FPxi>z$bn{y75i)cYTw(e8R0_uoOIeU4Mqh;jB;fAIElhGsP0q zSNR9G2Fb_I34e*?ew!0ilF)Mh_%j}lbP!gdHoUMJb>m}j;|)GGcys1TGFr?3#XTl2 zT#3?np&Ml~X;a$he^N@O6qH-bO)dMJf$5+T-;HmBH_>IhaA=wV@WL#V$w~-qa*P+Q zLiuf%M^Ze~Rg#o=;e6!63wI(9zCRtK zr*XcW!AXb<7o!ATxF03)xr0^Z7?Mwu6zkr72kp59`Oszf^=`~|B=@EUN^(*mg(LjY zoot@seeeLX;-$*>BP1vK7=DU!h^Juv5IxSXEh+p;lXgzwdBb-@$519od*Lg{Ed#H> z+#E)|F)!SLGluJ(3t+k7`4>)117)iVfK0JyQ zz)yyyh8ONLJij2Oj6~^L`TmcYi4;;&Qqi^>^~yIE_;15YW#o6zHNHeh1^0+C7apu3k9HDyt})=!;uM^r&B`ZdZ7H*b}Y{`@(^6EZiDSgnPoa zNJ+#QDUDP{e36<+EYcc@M^ce=L}|!uury>fSQ~O1Yz>LVp2lQjZ)2)4-Kaz}qn2n^ z)Edo=+M)$fd$c&}h?ejpP<|6FA0+E~>r!>;IwhDHv;r*L&(K>wWc#i?=JCdIPCII-t~*)_LkG>ny?Cpe #include #include +#include // IDirect3DDxgiInterfaceAccess is a COM interface for getting the DXGI interface // from a WinRT IDirect3DSurface @@ -201,30 +202,55 @@ bool WgcSession::initializeWindowCrop(HWND hwnd) { if (!GetMonitorInfoW(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &monitorInfo)) return false; monitorBounds_ = monitorInfo.rcMonitor; - RECT windowBounds{}; - if (FAILED(DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &windowBounds, sizeof(windowBounds))) && - !GetWindowRect(hwnd, &windowBounds)) return false; - RECT clipped{}; - if (!IntersectRect(&clipped, &windowBounds, &monitorBounds_)) return false; - return updateWindowCropRect(); + return updateWindowCropRect(true); } -bool WgcSession::updateWindowCropRect() { +bool WgcSession::updateWindowCropRect(bool initializeSize) { RECT windowBounds{}; if (FAILED(DwmGetWindowAttribute(windowHandle_, DWMWA_EXTENDED_FRAME_BOUNDS, &windowBounds, sizeof(windowBounds))) && !GetWindowRect(windowHandle_, &windowBounds)) return false; RECT clipped{}; if (!IntersectRect(&clipped, &windowBounds, &monitorBounds_)) return false; - const LONG width = (clipped.right - clipped.left) & ~1L; - const LONG height = (clipped.bottom - clipped.top) & ~1L; - if (width < 2 || height < 2) return false; - const int nextWidth = static_cast(width); - const int nextHeight = static_cast(height); - if (!cropTexture_ || nextWidth != captureWidth_ || nextHeight != captureHeight_) { + const LONG monitorWidth = monitorBounds_.right - monitorBounds_.left; + const LONG monitorHeight = monitorBounds_.bottom - monitorBounds_.top; + if (monitorWidth <= 0 || monitorHeight <= 0 || framePoolWidth_ < 2 || framePoolHeight_ < 2) return false; + + // WGC textures are in capture-surface pixels, while Win32 monitor/window + // rectangles can be DPI-virtualized. Map both edges into texture space + // instead of assuming those coordinate systems are identical. + const auto mapX = [this, monitorWidth](LONG desktopX) { + const double normalized = static_cast(desktopX - monitorBounds_.left) / + static_cast(monitorWidth); + return std::clamp( + static_cast(std::llround(normalized * framePoolWidth_)), + 0L, + static_cast(framePoolWidth_)); + }; + const auto mapY = [this, monitorHeight](LONG desktopY) { + const double normalized = static_cast(desktopY - monitorBounds_.top) / + static_cast(monitorHeight); + return std::clamp( + static_cast(std::llround(normalized * framePoolHeight_)), + 0L, + static_cast(framePoolHeight_)); + }; + + LONG left = mapX(clipped.left); + LONG top = mapY(clipped.top); + LONG right = mapX(clipped.right); + LONG bottom = mapY(clipped.bottom); + const LONG mappedWidth = (right - left) & ~1L; + const LONG mappedHeight = (bottom - top) & ~1L; + if (mappedWidth < 2 || mappedHeight < 2) return false; + + if (initializeSize) { + captureWidth_ = static_cast(mappedWidth); + captureHeight_ = static_cast(mappedHeight); + D3D11_TEXTURE2D_DESC desc{}; - desc.Width = static_cast(nextWidth); - desc.Height = static_cast(nextHeight); + desc.Width = static_cast(captureWidth_); + desc.Height = static_cast(captureHeight_); desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; @@ -234,13 +260,16 @@ bool WgcSession::updateWindowCropRect() { ComPtr resizedTexture; if (FAILED(d3dDevice_->CreateTexture2D(&desc, nullptr, &resizedTexture))) return false; cropTexture_ = resizedTexture; - captureWidth_ = nextWidth; - captureHeight_ = nextHeight; } - const LONG left = clipped.left - monitorBounds_.left; - const LONG top = clipped.top - monitorBounds_.top; - cropRect_ = {left, top, left + width, top + height}; + if (!cropTexture_) return false; + + // The encoder's dimensions are fixed for the lifetime of the MP4. Keep the + // crop texture fixed too: reallocating it after a resize made the encoder + // pad the changed frame with black bars. + left = std::clamp(left, 0L, static_cast(framePoolWidth_ - captureWidth_)); + top = std::clamp(top, 0L, static_cast(framePoolHeight_ - captureHeight_)); + cropRect_ = {left, top, left + captureWidth_, top + captureHeight_}; return true; } diff --git a/electron/native/wgc-capture/src/wgc_session.h b/electron/native/wgc-capture/src/wgc_session.h index c2786265..3bc0968e 100644 --- a/electron/native/wgc-capture/src/wgc_session.h +++ b/electron/native/wgc-capture/src/wgc_session.h @@ -64,7 +64,7 @@ private: winrt::Windows::Graphics::Capture::GraphicsCaptureItem createCaptureItemForMonitor(HMONITOR monitor); bool initializeWithItem(int fps); bool initializeWindowCrop(HWND hwnd); - bool updateWindowCropRect(); + bool updateWindowCropRect(bool initializeSize = false); bool recreateFramePoolIfNeeded( winrt::Windows::Graphics::SizeInt32 const& contentSize); void onFrameArrived(