From 96b08a4b1d35f2b29d98c9d3395f737a81ac91b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=A2=A6=E5=A9=89?= Date: Thu, 27 Aug 2026 16:45:09 +0800 Subject: [PATCH 1/4] Add 28/36/44px frames to the mode icons for intermediate DPI scales At 175%/225%/275% display scaling SM_CXSMICON is 28/36/44, but the CN/EN/CAPS/JA mode icons had no native frames for those sizes, so LoadImage returned a resampled bitmap and the Win11 taskbar input indicator looked blurry (issue #50). Add the missing frames (32bpp, Lanczos downscale from the 48px frame). Frames for existing sizes are kept byte-identical, so there is no change at 100/125/150/200/250/300% scaling. Refs #50 --- image/cap-dark.ico | Bin 26054 -> 43038 bytes image/cap-light.ico | Bin 26054 -> 43038 bytes image/cn-dark.ico | Bin 26054 -> 43038 bytes image/cn-light.ico | Bin 26054 -> 43038 bytes image/en-dark.ico | Bin 26054 -> 43038 bytes image/en-light.ico | Bin 26054 -> 43038 bytes image/jp-dark.ico | Bin 43006 -> 59990 bytes image/jp-light.ico | Bin 43006 -> 59990 bytes 8 files changed, 0 insertions(+), 0 deletions(-) diff --git a/image/cap-dark.ico b/image/cap-dark.ico index 5766983a906e875bc0b1df5d6d17cc0777200148..fa1cc086f79489e07d5d39d7998eaabf042876e4 100644 GIT binary patch literal 43038 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 delta 138 zcmbPtf$7+3#(D+@Mg}$p0Ra%Lz>vYhz>vnkz#t+5;qPE$U^oX9laPS$J2)8_+PE1Q z6cix*6+nG_q6`cg8c_XG3=G>;85j%&gkM#91OmG`e1O@S)D!dkDogjoP6?V{`sQ@ zgWF#;7@T(6XnuKOKl#$Z;LI~e^Ba~1gP*!Q`O-sDr=yWR!(fm;KJt(ehx5@#q6c3N zuMW3{KOKIlBRLU+tHNF3d&5*7&c#$LzlVpL!W`YO>~h9*JJg+!aa)*G(8bVKOw|<& z4+!-z33}lJVyb6#;i2J<@R24x(6R9WF?GE9gw5gG!k3x!K*z=h#MD|XQ*?M<#t(*% z3YR;Q>DUU(5o(>u1^sl?fIZ)L=B5F^$x)b-o<%iW&MVLZf$bq_c`b8G6nEO&G-(dl(tH>%55jM%yd z>t3L*>xx|GXjkMq-l{8hCXPNLdr3$8SPT2iv7vF(uF3FoYZ{rdXw+VGO_w>y&Q*!s^8IqLfA z*NSQIYoYV?vGBT%WIDD!=~}^_b_@iE;T)p`Q1K7lv?lxI3gnG9CP4SbC%T!M;>_x#XsC($L<9WI8xASHyUzU zJL_F*QZ<~-p9vlBEb!smy8?ze>suzjiHa_D}`6sQ9nA5_qgkKDQI~0RtIyOGzQ0p`4 z{EFEWzB#-pJUJ|o>Dc&;L!IAowpRDtOuiTXLZc+pvCYCS#=(9v2}j59Kf@1%*&&A{ z)3Hs0oN_zIv-XEq#OK!V$sNgb(@^_^{La}l=;d$2-wl7SlcybXT!uO8`keOu!S}H6 zitukblIf;FPWe3>wuiIuFXC`dNAfIek3&6o+V2yS;#_Z^>PVgiIqR7=&ps^QvpbS! zLC$%vpIN!a+3Wi84BHXf%Qp&g$yv{N*R#2r^(?c-_7K-Dl55>vn|$eAC)>kG&-Z$V zsAuto@rAR)+P__AWICvIt?Rq4lhRk;a>g~sWanDGNN0r0;kn_y_pt0LW8TB!F?>#aC}SP#e~(;ykkP!3sm6JI zT+3KF)KKf0AsD|9%6m)r*Ws0+7$aR_tzmW%pS4mH$LQ*G;^C;IyfYN@HVKCFvlyT728nrgc)oSXi7Ml}TeBwOb) zc9<5&reA0Ndn;nzaj+AQ$lD@N=%sI8{+ug_`M z{{v(H)6VZ#GtL4ZImL(_hova%`sZt3qnm^m#=!5Rq2oIx+1K+;Z5Of;Xe)wWIDFxa30k0&wKtW=j$UlPTzM5WIDEa(4K#B^IZRx z_gN9{2tOMh-;qqmHV>BKRM)@yv+n;kr`|sjihDsvG9BAIP+v`PxJdoD58vs=dM{Uh-s`4fjmL!V=}2A_>Z0|(GF(p&V%8g{rrOTmqSs$S4hrq{cULlbS9;t* zWn3&+Ej88tP-qRV2kts#i>en4-}Kyv%e zFwLi~b2-JSp|+Z8gHbQmgUxl}xd`=+Oy6=|AIE`pt<{=W?U>eZ*w)?4M{V7G)=^tl z*SLA-SvkOeS4^_q`?#`c_g37wd5x=Ec5lV@zdM(9Z@F`6b*<7!vT5S;!hOF}oG|fs ziY;-wApB%lYxSMT=Z7s`nTfrrT`w{nTMMyr^nJ~pvm--j{nXZjUi1XU%fj2key(4M zuJC{eJHozC&Dr=AemO$f`r}{4R(}sxqi@%Xo@(8yw=YKbn(&hFCE>%v7LUs072!&c zbZjk-%S4Wq9xuxLyl_(pYVcE2Z9V8$Pjybs>3<~rK|>GKqjO!?o8Au<=*5~>=~3(o_4u}Mb2u;fzC9Exhg{R37d`3io=}`;z%)3XH-~(`8qPYN zxa-0T4mX5i{GMlB zP6?MLkc|&tF=FMIg_Sr|Up3OrgWrgg7;EpGtdndp(nHP;VWidxMpjA5i{$4@8^AZ6!pBjE^_;uWckv)KXjh>idh7U_SDb)swmXH zHS|~BKIqu^@V&orb_&+J+3$}jPNz3MeAf&6rSCF}zE2#Hn5#lPd^S8WESwa9j*SoB zMW7cw>8;k_C5t5Je1AUUz2W!6pXqc4G94SAMWL5kdn2xdi{g|7+!%`gv+#i($#iUd z7R5>es;?U9)`Qn1NRDrXXLTggv8@Ly397zoq+1WpO^|=nC(lJ4$#mz2>%mHbs;?U9 z)`O!G^r29mFLxx)klj`ZEa$OnO?;+<+a-KtfdVF?; zm6J@jUg$+ndOI@o-DOj_UU(LHFRuQ`2lIT=i=OnhQFu-geXk>Vqi}u_`7XTZ^SfW) zZ(%R&NIn?oMNfJ=nCHjA^e`>Z+!w_b%&7;xSUJz#?B}CnYtilveg7-tcx30?`qlMT>(=HQFYnze_h3uLRpaKpJBQ<@ zy(`A88Fw4g^4M|ZqD@2n%3%L-=V0?tU*qav%W&Qw^UqL+`u>=IraIKu`2E2-!+C$) zGq`xDuW|2S?{MCYTQUxhXYVE5I6BTjcicI&sW>Cnv%>A+zP~e_Hu3LF@fv>5a4mm6 zygRhM-sN8#dVg;5)J$#;`{%djYhJC+w&dv|iRJ*m4^{7`pgJUr-Ki{3c8SVFe9@zDyx9U^RdcP#x)9JsJ(Yl=x zE{7+Dl`rCcI3}~D31k}wx#S!dH?CIsFDFJ%deft0(6ioMQ|6AXf6k*iO;4&t_M{HsLPJ^z=H>wSAY3B}5xcRA%= z6i-cnXTrSKg8Toop_+Gv&kxrNv2w^Ir`+>EuX@(|&7pYjER&x5G3|%n&rA%yJ=`2F z3Nh~pE03J>K#zJAcXKzAJrkC~dGPc&-5QGfTG;;%8r4jQ5i5sWa?S%iw$Cr|xEiv} zgZ6JsVx7xHA*O1-KeC+jK#!|o#nwp2HZLxWW4*V2EVA`HC6r?t`S2B^wj6TJ3%OTA zu`TJ?=EbRTyeX99p75*T>YU^&Mywoi%?mxQhGJXNvCWH3aeQOg=2(v`hg|bQkE>z7 z)*|pVF zII{8Ki(=(i1pWPU(dSpc)~`iT{ahFMh`vKJe^6vTbok_coKchAF zWVZIXA@&E2{&VyXrZmJ>YyXbO>v?WZNxyE>^AmYjsJG9BuJbWV*7ilwlpC z-u0?yy<0DNJqO2~_o(N>6XR9CE!`5?yzrz5bn5VFZJ90vJ?d4i>Ycov=U2k^!MSX| zo7v|J)=LfK!*{({N}ygVUyZBLu^kNB?`Cz4yUzbtsLrH&W09JATn(%58tK>$2F`8! z-R#FR|B0~nrbWJEP3q&m>|f3HyV<)k$6BL#zhlWW36uIi*z3RQJv~A_V{ea)`ln+% zSm?jK{_7q-*!`#adT<2ar)te>T;w}e_^G-A18({%%yxHqWL^+V5tIe#dHa&62JE31R!ZpA|EY-81%M9S`PtJFb>q z^{n^ThF=OV51p5d#4$;R8wow?RnK~_{pZV(59a+R;r9#ls8{z@^-i{@E{BIYmeXLn z|KFXt{=XTX5gzK$qh9r__s@6oy%}E?9_rAeUiGi{OTv2A{Qvm(>l4%eheF4Lj?MXT zjk!-Q5Bqzo-!J@j!)LWeI=24b6Y9C?S=Ns;r}sUf_CPh&)&skqYTfmzXT8H?Li0Ug z9Y>A!DSK@T=dkRP#{RWek((ksR*M4~gw~XTD6C_s1N~IrQJ(v|`-5 zXVc2X>g23kOkZPkd(96RS2m6GHSXLzn)k=mEhBx6ySI+!{qfGFk$$u;wNA6vv+QRK zM*oAZPsv#SPV3K)%49tLb<|%8b5z6M@1NMYEoc0jkiKZX90I?4!m=6tmUUS8xUg(; zs{z|X*ZOzEzX;zQZVTa|;hRJE!8P4zP7h0=?|tH~4L=youG`m|5Hc#N%6?HekNub4VU4rNnAtv<@``{>t0>t5H#xZ^J!AHHJ5LggCG zMxVnwOge&32 z9m#ZTeE34ek}IbgYVm9Dzf6ayb$D22yFz}`$cHafEV=5{@r^rw{Gj4q8~NVwvhW$< zk9H)}vGIY58O_$_Z;nE(<*Z zYw(8f_VDyjP9)Q@@qvmN%?|u@&o6cAalX~By~A<*dgp5()72hSzHEicsfJqqR_d7o zWgE>#pLISSk*Vj({|UW=BAJd2%6BvyeO692)Y6~(2Ff;?t$mh$M^yaJ4xik~bWlE{ z+1h96)et-B{#%O}ohxzww2S!<8DHPYbZq0+GU|POTobwOznu(0^)i~ReU{!n{HgGc zj^t^3bIkj4?u_jCoP$3KVchzUENlJ$W)$L(43mzHt#YcN)-+%Kg^K%!QQX~;3}qY5 zCV#5+xNxa+sdbwaQTB`DfKa;8?7+{mtD%-_bR*s;RI1$Mf@4QD>V9bVYscKi@ii}2 zeCca!?QtLax4CM+zQ5lGx2Kmq;djHo2;UuU3*n)meO+(vAEP-vI4AZEar3_K#&!6v z{gsS+L+=Dn3}HFk==XVf?>BhyI4yimSl?^5A2+f5v9Y*so%4G`=i${MxNZ&)-xAW> zyV{YSoge&e$d1;v^1VOuQ6b39&Zef?dVq(8|1}hgmFG_)gX{N*(0#$)_G3=Z&JW%Y z(pMiw^N)u|hafjy)gtRbFMk-C=Nt0y9pt$gpB>g}R-KcgW3%K%b9yL0$LYPMe2nLZ zr-lW&)ewJKsJ0&TV!a##{SOLi*SV{8bsUb-`-^L#jyK|PZjYhwv-RU^-uIDHe4%{k z$!gd2WS!6&gIxC)s+QW-$Ezd1DePY_ZBM6XV(;m%Me8$379&=UJ}RHudeF-xl$tk<*r9yHh?PSwsNAF3{-0&5aewP5$H$_yp7sft8_m`}^`Muxgr0@9kJLIx zweQ+~ROD}l^8Q>1?fo*+tbLYkdsJe?$^ql@tE~sU@W}duC^X( zFSHj;>Zgvu-xdEVbR1WOFApycFY1wwjSpWj^*71N71a(G*pjSpWj6(4awwEa{cZ;8jG`)j}8 zOkAh$3B|rW1hon!v+?08W)iBO_Wt63#H4^mU$H+Oom$@tA05`Q*Z7#u#)mId>}WRr zQxAHnW2$ky_gYSS+~-2|exq~VoDqSJjSpX#)lb!~aTGQCv-194T-Ef>=NTXmJ|v`L z;{z2ln$7-vbzI&M9^1K2>#^408S%X>bYK2h7iS>TvGIY58O`?ptXgX8K`)L4=Xw9B zb#Sh|pNsqBu=H>0bZmS|A8{;d?b`RB+Jm0cMU>Cj1W}g#mm=%uYvIY^BRZLm4a#>k zJMgpYYTF<5BHlP}Kefh7iP_b~Z_oJiolM6Ds1r8_gE`^!?xW z>1p40W@UVA9B@(8`BGaCda1Qu;RqK0EARPbYOY$5P}=54E12 zjn=<>jOT}^h6TCR5U-}%deF0iL9f%uPyd|VUGHCD`y$VY_0S4}oO=tWO@Yw^5HR>R6w<6Y667ZzM= zzY~^y+{n(aa886f!g0QIUkKfspq83_-__{!2zuWY@^SpWGhQ8D7rrX2_xFfH_)X0* zUmNl(n$xqlI3|-z!w-a4h2?J)b3s_gr_0tq+m~ncYAtH5A|4cK zZQJ#26FR=?S#NsO>qo;o!dHbbDSl+Ve?O}iz3EY}+rsn0+6NrhIM81h{#p2}&Y|*k z)47I z3|#Z`qI|{5A(xzTF9O%~Joq*`wIH_g$T<(H#}~xeGxP~v(6ri1 z@wqW{uYM{#J%q|NnvMS~A2DL(kW0=fGs#zg``uXS6+8PVseI5f8w5(cB)2|I_fuP+Y}|@3ZWD zuMEY?A=f16K_0Ps)1zKd{8eGq9M^B@{z3e_kBHk9o*T}KbK@vRtQ>Md;j0Xtws*_S>$n_<672%Dp8qZw&Qkz3vL{4Daq_^CBIad9AHjIiPZm zW^12qzwPzA$o?Q(okQ>Yb-!L8`6t6?g?>}?JU}uX8y{;UroJmwuBgUh-2Sl0{wrzK zI4SanLu>rS@G;>eIQRBizGB2eWn{H(Qa_uqNq+Dw&$?l(g{;ID_k-ja^3{KOR6 zT&0^d_K$6m*m|x$CCP6J_448H;UQGNWI8rJe8oWJ7|o`CF4Eh$Om(bB#rTd;FW(E# z525Xsj*SmrF;F>1v-v+yjq5p~@3AoNvDEr(PfYdm`p9+PM;yv@bv)ZCgNhx^CVy5h zdefs`{XU`Ir6J6ltJY^*Vr~fabaVK~u-2DM$Hs>*RP1Or`LlY_n;!Klmwn~~p*&c} z6>%!c*Kc+9aJhcDi6GOl@sU@|JSboOdedX&BEL60EUX?P&IEsWR`|8Bj{CupvFfn# zfr=T;CVy7H{PiYxt%<&`4%rszw|tLGTs z)_T1p@*Q2yf1eTMr(=Wi9nGeHPU^R=i}m*Fo{;;r@N=Pjf7_8v$Hu4bpNKOtuHWj_ zI$Rr;k8u%H&;Kz&?KvaUE!wNvZ7+JOyl;*C`S3*{EV2fph_x8+IJbt@0m*c5FnRT+ z$G3(@gbxedJL^TA5BJnZ!deS59hA>#w%DiM^r+X3LapCRld$?FL)k{NgZtc;@bkiB zyEN-vhl)EsdEU^G3}qY5=KriXy`2|s3qKm(5xy#fja-XS#`S+zFM89XUY$Gl#`{D2 zV?6^Rt_#*g9jx_PPa?5;(Uab4FT1CcugN&i@6~Y|_95RmvX8?!U%GLiuU`AVSKktw z-aivAhfwQ0ZjI!jH}+ZjnD#;K()axmVj=*|lZ^8QX(_HiS7)fab8 zct<$Sm+lLpX91|CX5V);y7~rCbxyIr@CiLre|*<{^KE^ cS}Xlj%#O(Q+~TVyn;!I{C%yeW?uQlle}}QvdH?_b delta 138 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 LuBuIJI#uBRja5tF delta 138 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 Na~=Dae#2+r{{s-7;XD8U delta 138 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 H_4UgE7!(qn diff --git a/image/jp-light.ico b/image/jp-light.ico index b5ebf82dec84c6503ff97a2ba1e521044f085fee..20d25b00a0ec62d6d40f25a0d8606fafdf499613 100644 GIT binary patch literal 59990 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 H_4UgE7!(qn From 50eb0b4b438efc5d9b5661b9cbcfa949a91bf6b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=A2=A6=E5=A9=89?= Date: Thu, 27 Aug 2026 17:42:44 +0800 Subject: [PATCH 2/4] Size the taskbar indicator icon by the monitor's effective DPI --- src/LanguageBar/LanguageBar.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/LanguageBar/LanguageBar.cpp b/src/LanguageBar/LanguageBar.cpp index 3709b04f..8e3b5a0f 100644 --- a/src/LanguageBar/LanguageBar.cpp +++ b/src/LanguageBar/LanguageBar.cpp @@ -524,9 +524,31 @@ STDAPI CLangBarItemButton::GetIcon(_Out_ HICON *phIcon) DWORD status = 0; GetStatus(&status); - // Use the system small-icon size so HiDPI taskbars get 20/24/32px assets - // instead of upscaling a forced 16x16 (which looks blurry). - int desiredSize = GetSystemMetrics(SM_CXSMICON); + // GetIcon is invoked on the *focused application's* TSF thread, and + // GetSystemMetrics(SM_CXSMICON) follows the process's *system* DPI, which + // Windows keeps lagging behind the per-monitor scale until sign-out and + // caches per process start (e.g. 20px at registry 120% even while the + // monitor really runs at 175% and the taskbar slot is 28px). The shell + // draws the returned HICON scaled into that slot, so a 20px icon gets + // upscaled to 28px and looks blurry (desktop focus only appeared sharp + // while explorer happened to have started at 175% and thus asked 28px). + // Query the primary monitor's *effective* DPI (awareness-independent) and + // size the icon to the real physical small-icon slot. + int desiredSize = 16; + HMONITOR mon = MonitorFromPoint({0, 0}, MONITOR_DEFAULTTOPRIMARY); + UINT dpiX = 0, dpiY = 0; + using GetDpiForMonitorFn = HRESULT(WINAPI *)(HMONITOR, int, UINT *, UINT *); + static const auto fnGetDpiForMonitor = reinterpret_cast( + GetProcAddress(GetModuleHandleW(L"shcore.dll"), "GetDpiForMonitor")); + if (mon && fnGetDpiForMonitor && + SUCCEEDED(fnGetDpiForMonitor(mon, 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY)) && dpiX > 0) + { + desiredSize = MulDiv(16, static_cast(dpiX), 96); + } + else + { + desiredSize = GetSystemMetrics(SM_CXSMICON); + } if (desiredSize <= 0) { desiredSize = 16; From 2dabb2d723752b9bd9f91e8bf182544690ad2ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=A2=A6=E5=A9=89?= Date: Thu, 27 Aug 2026 18:17:51 +0800 Subject: [PATCH 3/4] Lazily load shcore.dll for the effective-DPI query Processes that never loaded shcore.dll would silently fall back to SM_CXSMICON and keep the old sizing. Resolve the entry point via GetModuleHandleW first, with LoadLibraryW as a fallback, so the monitor-DPI query works in every host. Refs #50 --- src/LanguageBar/LanguageBar.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/LanguageBar/LanguageBar.cpp b/src/LanguageBar/LanguageBar.cpp index 8e3b5a0f..110e477a 100644 --- a/src/LanguageBar/LanguageBar.cpp +++ b/src/LanguageBar/LanguageBar.cpp @@ -538,8 +538,19 @@ STDAPI CLangBarItemButton::GetIcon(_Out_ HICON *phIcon) HMONITOR mon = MonitorFromPoint({0, 0}, MONITOR_DEFAULTTOPRIMARY); UINT dpiX = 0, dpiY = 0; using GetDpiForMonitorFn = HRESULT(WINAPI *)(HMONITOR, int, UINT *, UINT *); - static const auto fnGetDpiForMonitor = reinterpret_cast( - GetProcAddress(GetModuleHandleW(L"shcore.dll"), "GetDpiForMonitor")); + // shcore.dll ships with Windows 8.1+ and is usually already loaded by the + // host; resolve it on demand so processes that never touched DPI APIs + // still get the real slot size instead of dropping to SM_CXSMICON. + static const auto fnGetDpiForMonitor = + []() -> GetDpiForMonitorFn + { + HMODULE shcore = GetModuleHandleW(L"shcore.dll"); + if (!shcore) + { + shcore = LoadLibraryW(L"shcore.dll"); // system DLL; freed at process exit + } + return shcore ? reinterpret_cast(GetProcAddress(shcore, "GetDpiForMonitor")) : nullptr; + }(); if (mon && fnGetDpiForMonitor && SUCCEEDED(fnGetDpiForMonitor(mon, 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY)) && dpiX > 0) { From e6870930a61c2fcf14f5bdf7875360bb2014ef2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9F=B3=E6=A2=A6=E5=A9=89?= Date: Thu, 27 Aug 2026 18:55:41 +0800 Subject: [PATCH 4/4] Fix icon sizing on hosts without per-monitor awareness GetIcon runs on the focused application's TSF thread and GetDpiForMonitor scales its answer to the caller's DPI awareness (PROCESS_DPI_UNAWARE -> 96, PROCESS_SYSTEM_DPI_AWARE -> system DPI, per PROCESS_DPI_AWARENESS docs). Wrap the query in SetThreadDpiAwarenessContext(PER_MONITOR_AWARE_V2) and restore it afterwards so hosts that are not per-monitor aware still pick the real taskbar slot size; GetSystemMetrics(SM_CXSMICON) remains the legacy fallback when these APIs are unavailable (Windows 8.0 / pre-1607). Cache the lazily resolved shcore/user32 entry points in std::atomic members instead of function-local statics: this project builds with /Zc:threadSafeInit-, under which magic statics are not thread-safe, while GetIcon can be reached from several TSF threads of a host. Failed lookups are not cached and simply retried on the next call. Refs #50 --- src/LanguageBar/LanguageBar.cpp | 128 ++++++++++++++++++++++++-------- 1 file changed, 98 insertions(+), 30 deletions(-) diff --git a/src/LanguageBar/LanguageBar.cpp b/src/LanguageBar/LanguageBar.cpp index 110e477a..d7d3933e 100644 --- a/src/LanguageBar/LanguageBar.cpp +++ b/src/LanguageBar/LanguageBar.cpp @@ -15,6 +15,8 @@ #include "Ipc.h" #include "fmt/xchar.h" +#include + namespace { // Taskbar/system tray follows SystemUsesLightTheme (0 = dark). @@ -55,6 +57,59 @@ DWORD ResolveThemeIconIndex(DWORD lightIconIndex) } return lightIconIndex; } + +// Design size of the mode icons for language bar / taskbar indicators (at 96 DPI). +constexpr int kSmallIconDesignSize = 16; + +// Avoids relying on USER_DEFAULT_SCREEN_DPI, which older Windows SDK headers +// targeted by this project may not provide. +constexpr int kUserDefaultScreenDpi = 96; + +using GetDpiForMonitorFn = HRESULT(WINAPI *)(HMONITOR, int /*MONITOR_DPI_TYPE*/, UINT *, UINT *); +using SetThreadDpiAwarenessCtxFn = HANDLE(WINAPI *)(HANDLE); + +// Entry points are resolved lazily and cached in these atomics instead of +// function-local statics: the project compiles with /Zc:threadSafeInit-, under +// which magic statics are NOT thread-safe, while GetIcon can be reached from +// several TSF threads of the host process. Failed lookups are not cached - they +// are cheap enough to retry on the next call. +std::atomic s_getDpiForMonitor{nullptr}; +std::atomic s_setThreadDpiAwarenessCtx{nullptr}; + +template +T ResolveOnce(std::atomic &slot, T (*resolver)()) +{ + T resolved = slot.load(std::memory_order_acquire); + if (resolved == nullptr) + { + resolved = resolver(); + if (resolved != nullptr) + { + slot.store(resolved, std::memory_order_release); + } + } + return resolved; +} + +GetDpiForMonitorFn ResolveGetDpiForMonitor() +{ + // shcore.dll ships with Windows 8.1+; most hosts already have it mapped. + HMODULE shcore = ::GetModuleHandleW(L"shcore.dll"); + if (!shcore) + { + shcore = ::LoadLibraryW(L"shcore.dll"); // system DLL; intentionally kept until process exit + } + return shcore ? reinterpret_cast(::GetProcAddress(shcore, "GetDpiForMonitor")) : nullptr; +} + +SetThreadDpiAwarenessCtxFn ResolveSetThreadDpiAwarenessContext() +{ + // user32.dll is always mapped inside any host of this DLL. + HMODULE user32 = ::GetModuleHandleW(L"user32.dll"); + return user32 ? reinterpret_cast( + ::GetProcAddress(user32, "SetThreadDpiAwarenessContext")) // Win10 1607+ + : nullptr; +} } // namespace //+--------------------------------------------------------------------------- @@ -524,45 +579,58 @@ STDAPI CLangBarItemButton::GetIcon(_Out_ HICON *phIcon) DWORD status = 0; GetStatus(&status); - // GetIcon is invoked on the *focused application's* TSF thread, and - // GetSystemMetrics(SM_CXSMICON) follows the process's *system* DPI, which - // Windows keeps lagging behind the per-monitor scale until sign-out and - // caches per process start (e.g. 20px at registry 120% even while the - // monitor really runs at 175% and the taskbar slot is 28px). The shell - // draws the returned HICON scaled into that slot, so a 20px icon gets - // upscaled to 28px and looks blurry (desktop focus only appeared sharp - // while explorer happened to have started at 175% and thus asked 28px). - // Query the primary monitor's *effective* DPI (awareness-independent) and - // size the icon to the real physical small-icon slot. - int desiredSize = 16; - HMONITOR mon = MonitorFromPoint({0, 0}, MONITOR_DEFAULTTOPRIMARY); - UINT dpiX = 0, dpiY = 0; - using GetDpiForMonitorFn = HRESULT(WINAPI *)(HMONITOR, int, UINT *, UINT *); - // shcore.dll ships with Windows 8.1+ and is usually already loaded by the - // host; resolve it on demand so processes that never touched DPI APIs - // still get the real slot size instead of dropping to SM_CXSMICON. - static const auto fnGetDpiForMonitor = - []() -> GetDpiForMonitorFn + // GetIcon runs on the *focused application's* TSF thread, so sizing must + // not depend on that process's DPI awareness. The taskbar lays the input + // indicator out in physical pixels of its monitor (e.g. a 28px slot at + // 175%), while GetSystemMetrics(SM_CXSMICON) reports the system-DPI + // snapshot cached when the host started (e.g. 20px). The shell then has to + // upscale our returned icon into the larger slot, which is the blur of + // issue #50 (focus-dependent only because explorer happens to start at the + // correct scale). + // + // Query the primary monitor's effective DPI instead. Per MS docs, + // GetDpiForMonitor scales its answer to the caller's DPI awareness + // (PROCESS_DPI_UNAWARE -> 96, PROCESS_SYSTEM_DPI_AWARE -> system DPI, + // PROCESS_PER_MONITOR_DPI_AWARE -> the real value), so temporarily flip + // this thread to PER_MONITOR_AWARE_V2 around the query; otherwise unaware + // or system-aware hosts would still end up with the wrong size. Hosts + // lacking these APIs fall back to the legacy SM_CXSMICON path unchanged. + int desiredSize = kSmallIconDesignSize; + bool sizedByMonitorDpi = false; + if (HMONITOR mon = ::MonitorFromPoint({0, 0}, MONITOR_DEFAULTTOPRIMARY)) { - HMODULE shcore = GetModuleHandleW(L"shcore.dll"); - if (!shcore) + SetThreadDpiAwarenessCtxFn setCtx = + ResolveOnce(s_setThreadDpiAwarenessCtx, &ResolveSetThreadDpiAwarenessContext); + HANDLE prevCtx = nullptr; + if (setCtx) { - shcore = LoadLibraryW(L"shcore.dll"); // system DLL; freed at process exit + // (HANDLE)(INT_PTR)-4 == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2; + // spelled out via casts to avoid requiring WINVER >= Win10 targets. + prevCtx = setCtx(reinterpret_cast(static_cast(-4))); + } + + UINT dpiX = 0; + UINT dpiY = 0; + GetDpiForMonitorFn getDpi = ResolveOnce(s_getDpiForMonitor, &ResolveGetDpiForMonitor); + if (getDpi && SUCCEEDED(getDpi(mon, 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY)) && dpiX > 0) + { + desiredSize = MulDiv(kSmallIconDesignSize, static_cast(dpiX), kUserDefaultScreenDpi); + sizedByMonitorDpi = true; + } + + if (prevCtx) + { + setCtx(prevCtx); // restore the caller's thread awareness } - return shcore ? reinterpret_cast(GetProcAddress(shcore, "GetDpiForMonitor")) : nullptr; - }(); - if (mon && fnGetDpiForMonitor && - SUCCEEDED(fnGetDpiForMonitor(mon, 0 /* MDT_EFFECTIVE_DPI */, &dpiX, &dpiY)) && dpiX > 0) - { - desiredSize = MulDiv(16, static_cast(dpiX), 96); } - else + if (!sizedByMonitorDpi) { + // No shcore/awareness-switch available: exactly the legacy behavior. desiredSize = GetSystemMetrics(SM_CXSMICON); } if (desiredSize <= 0) { - desiredSize = 16; + desiredSize = kSmallIconDesignSize; } // UAC/secure desktop historically expects at least 24x24. if (_isSecureMode && desiredSize < 24)