[Windows] Per-resize-step Moved/Resized event construction + delivery on the window thread make frameless edge-drag visibly lag behind the frame (content "trails" the border)
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 38/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- dart, flutter
- Domínio
- desktop, performance
Direção de pesquisa
Start with window_manager_windows.cpp at WindowGeometryProc, OnWindowChanged, and OnWindowEvent; trace how WM_WINDOWPOSCHANGED builds and delivers moved and resized events during sizing. Then inspect window_message_dispatcher.cpp for the per-message dispatch cost. Use the described left-edge SetWindowPos probe to compare event counts and per-step time; done means reducing the resize lag while preserving correct geometry events.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
[Windows] 逐步构建/投递 Moved/Resized 事件拖慢窗口线程,导致无边框边缘拖拽"内容追边框" / Per-resize-step Moved/Resized event construction + delivery on the window thread make frameless edge-drag visibly lag behind the frame (content "trails" the border)
本 issue 提供中英双语:中文在前,英文原文在后(
---分隔)。
Bilingual issue: Chinese first, then the original English text below the separator.
中文版
概述
在 Windows 上,注册了 nativeapi 窗口监听器时,交互式拖拽窗口边缘会出现明显的内容追边框(橡皮筋效应):边框跟着鼠标走,而 Flutter 内容晚几帧才到达。在 sizing 模态循环期间,矩形每变化一步都会产生一条 WM_WINDOWPOSCHANGED;每一步里,nativeapi 的几何子类(geometry subclass)对比快照、查询矩形和 DPI(GetSize())、构造一个 WindowMoved/Resized 事件,并通过 NativeCallable + delivery_is_active/delivery_complete 握手投递给 Dart——这一切都发生在窗口线程上,每秒执行数百次。Dart 侧的帧耗时指标看起来健康(我们的 Debug 采集中 rasterP50 ≈ 1.4 ms,而帧管线 span 的 P50 约为 13–16 ms——这里看的是形态,不是绝对值),说明瓶颈在平台线程的调度延迟,而不是渲染负载。
在 Release 保真度下做 A/B 开关(同一二进制、单变量探针,见下文)显示:回归的绝大部分可归因于逐步事件路径,而仅包一层 Window wrapper 时也有一小块可测量的残留。我们在源码和实测中都确认:minimumSize / titleBarStyle 这两个 setter 的处理函数会在应用窗口上安装通用的 WindowMessageDispatcher(整体替换 GWLP_WNDPROC),即使监听器数量为零——因此每条消息都要走一遍 mutex/vector/sort 路径,普通无边框应用也会被收税(见根因第 4 条和量化小节)。
机器相关但在我们的笔记本上保持一致:脚本化的左边缘负载(1500 步一像素的 SetWindowPos)产生了恰好 1500 个 WindowMovedEvent + 1500 个 WindowResizedEvent——每一步 WM_WINDOWPOSCHANGED 构造并投递两个事件,零合并,并使窗口线程每步的 wall time 在裸 Flutter 窗口约 10–13 ms 的基础上增加约 1.3–1.8 ms(约 10–15%)。方法与细节见下文"量化复现"。
环境
- nativeapi / cnativeapi / nativeapi_flutter:0.5.10(pub.dev,截至 2026-11-10 为最新发布版)
- nativeapi-core
mainHEAD 上的window_manager_windows.cpp与 0.5.10 pub 包逐字节一致(我们做过 diff)——下文所有内容也是当前上游行为;两个版本的行号通用。 - Flutter 3.47.6 stable(Windows x64),Dart 3.13
- Windows 11(Build 26300),单 GPU(RTX 4060 Laptop,直连面板)
- 应用:无边框窗口(
titleBarStyle = hidden),普通 Flutter UI
我们如何隔离问题(同一 Release 二进制上的 A/B)
我们构建了一个应用,并在运行时逐项开关 nativeapi 的使用:
| 配置 | 边缘拖拽手感 |
|---|---|
| 完整 nativeapi 使用(注册监听器、隐藏标题栏、设置最小尺寸) | 明显追边框 |
跳过 hideTitleBar()(绕过 frame/命中测试链,监听器仍在) |
仍然追边框 |
不设置 minimumSize |
仍然追边框 |
包装了窗口,但从未调用 addListener() |
接近正常,有轻微残留 |
| 完全不创建 nativeapi Window wrapper(纯 Win32 + Flutter) | 流畅 |
| 旧技术栈(window_manager 0.5.x + bitsdojo,无 nativeapi) | 流畅 |
因此,成本的大部分跟随"事件注册与投递";较小的残留跟随 wrapper 自身的逐消息链(几何子类 + 标题栏/命中测试处理函数)——凡是 wrapper 存在的行都有这部分。
量化复现(独立探针应用,同一二进制,环境变量切换档位)
由于无法可复现地脚本化真实鼠标拖拽,我们驱动拖拽所使用的同一条消息路径:一个独立进程对窗口左边缘发出 SetWindowPos 一像素振荡(x+1/w−1,然后 x−1/w+1)。每一步都会穿过 sizing 消息路径(WM_WINDOWPOSCHANGED),且每次调用都会阻塞到窗口线程处理完毕——因此每步 wall time 就是窗口线程的工作时间。探针应用是一个普通的 flutter create Windows 应用,通过 Window.createWithNativeWindow 绑定 runner 的 HWND;各档位由运行时环境变量切换:
| 档位 | 监听器 | titleBarStyle=hidden |
minimumSize |
含义 |
|---|---|---|---|---|
| B | — | — | — | 裸 Flutter 窗口(基线) |
| A | ✔ | — | — | 仅几何事件链 |
| C | ✔ | ✔ | ✔ | 我们修复前的应用形态 |
| D | — | ✔ | ✔ | 我们修复后的应用形态(事件已退订) |
结果(Release,RTX 4060 笔记本,每档每轮 1500 步,轮次交错;热漂移使后段轮次整体变慢,因此差值按约 ±0.5 ms 计):
- 每步事件数——零合并。 A/C 档记录到 1500 步左边缘拖拽产生
moved = 1500和resized = 1500:每一步WM_WINDOWPOSCHANGED恰好构造并投递两个事件到 Dart(左/右边缘拖拽同时改变位置和尺寸,因此OnWindowChanged的两个分支都会触发)。负载期间持续约 165 事件/秒;某一轮里 3000 个中有 8 个被跳过,说明投递既非无损也无合并。这与代码一致:moved(:834-835)和resized(:837-839)是独立的if,且OnWindowEvent(:892-901)对每个事件重新查询注册表 +GetSize()/GetPosition()。 - 每步窗口线程税。 同轮配对差值:
A−B ≈ +1.3 … +1.8 ms/步,基线B ≈ 9.6 … 13.8 ms/步(约 10–15%);C−B ≈ +1.7 … +2.4。事件链本身占了大头,与主观阶梯表一致。 - 附带发现(行为类,可能是有意为之): 对一个已经可见的窗口设置
titleBarStyle = TitleBarStyle.hidden会清除WS_VISIBLE——窗口保留几何,但IsWindowVisible返回 false,直到我们再次调用show()。我们的应用只是因为遵循"先隐藏 → 改样式 → 再 show"的顺序才躲过了这个问题。
探针应用 + 驱动脚本总共约 150 行;如有需要我们乐意附上或贴出。
根因指针(cnativeapi-0.5.10)
- 几何事件在每一步拖拽中都在窗口线程上构建并投递——边缘拖拽每步两个。
window_manager_windows.cpp:203-217——WindowGeometryProc(由WatchWindowGeometry通过SetWindowSubclass安装,:222-224)拦截WM_WINDOWPOSCHANGED,先调用原过程,然后OnWindowChanged(:778-841)对比快照(:769-775,GetWindowRect+IsIconic+IsZoomed),并独立触发moved(:834-835)和resized(:837-839)——边缘拖拽同时改变 x 和宽度,所以每步两者都触发(实测:1500 步恰好产生 1500+1500 个事件,零合并)。
每个事件还额外通过 C++ getter 重新查询几何(OnWindowEvent,window_manager_windows.cpp:862-906→ 注册表查找 +window->GetSize()/GetPosition()= 矩形 + DPI 计算),构造一个WindowMoved/WindowResized,并通过带native_event_delivery_is_active/native_event_delivery_complete握手的NativeCallable投递(bindings/dart/nativeapi/lib/src/callbacks.dart,deliverEvent;DispatchWindowEvent:1199-1202)。在边缘拖拽期间,WM_WINDOWPOSCHANGED以鼠标采样率到达——每秒数百次这样的构建+跨语言投递,而这条线程同时还必须让 sizing 模态循环和WM_SIZE → MoveWindow(child) → engine present链继续运行。 - 你们自己的代码就记录着这种失败模式。
window_manager_windows.cpp:143-148解释了为什么几何上报采用子类(subclass)而不是EVENT_OBJECT_LOCATIONCHANGEWinEvent 钩子:跨上下文(out-of-context)的 WinEvent"会在线程下一次读取消息时被投递——正好在 Flutter 的 resize 中间,而 Flutter resize 在等待新尺寸的一帧时会泵消息……而从那里被调用的监听器(Dart 监听器是同步的)让每一个 resize 步骤都迟到了。"子类把投递点移到了一个确定的位置;它并没有减少每步的工作本身。 - 遮挡(occlusion)有合并,但 Moved/Resized 没有。
window_manager_windows.cpp:511,546-547——遮挡路径会启动一个 100 ms 定时器,理由是"这些事件是一阵一阵来的(拖拽会让窗口一秒动几十次)"。WindowMoved/WindowResized没有等价的节流:边缘拖拽实测每一步WM_WINDOWPOSCHANGED恰好两个事件。 - 已确认:通用 dispatcher 会被安装到普通应用窗口上——由标准 setter 安装,即使监听器数量为零。
WindowMessageDispatcher::RegisterHandler(hwnd, …)(window_message_dispatcher.cpp:34-52)调用InstallHook(hwnd)(:163-186),也就是SetWindowLongPtr(GWLP_WNDPROC, DispatchWindowProc)替换——而调用者是日常功能:最小/最大尺寸处理函数(window_windows.cpp:1560-1568,WM_GETMINMAXINFO)、always-on-bottom(:1659-1667)、标题栏/命中测试处理函数(:~1700)。因此仅minimumSize/titleBarStyle就让应用窗口的每条消息都走一遍逐消息的mutex快照 + 两次哈希查找 +std::vector分配 +std::sort路径(window_message_dispatcher.cpp:96-161),包括拖拽期间的高频非客户区消息(WM_NCHITTEST、WM_MOUSEMOVE、WM_SIZING)。我们的无监听器 D 档相比基线仍多花约 +1–2 ms/步,这是在 item 1 事件链税(A 档)之外的部分;item 1 占主导,但两者都需要修才能真正消除差距。
最小复现
一个 Flutter Windows 应用:
final window = na.WindowManager.instance.getCurrent()!; // 或包装 runner 的 HWND
final id = window.addListener((e) { /* no-op */ }); // 保持监听器注册
// 无边框:
window.titleBarStyle = na.TitleBarStyle.hidden;
然后以中等、稳定的速度水平拖拽窗口边缘,再与删掉 addListener 一行(或在拖拽前 removeListener)的情况对比。差异可以通过边框与内容的边界很容易看出来;当窗口内是静态高对比布局时最明显(任何内容滞后都会一目了然)。
如果你想要无需人工拖拽的量化采集:上文"量化复现"小节脚本化了同一条消息路径(从第二进程发出 SetWindowPos 左边缘振荡)并统计产生的 Dart 侧事件;我们还建议用 QueryPerformanceCounter 对 WindowGeometryProc 中 WM_WINDOWPOSCHANGED 的处理(入口到返回)以及 Dart 投递握手计时,在一个 10 s 负载上做直方图,对比注册监听器与不注册。
修复建议(任选其一或更好的想法)
- 合并/节流 Moved/Resized 投递——你们对遮挡事件已经这么做了:在突发事件上启动定时器,并始终在
WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE会话边沿发出最新几何。大多数应用需要的是会话边沿 + 节流后的流,而不是每条WM_WINDOWPOSCHANGED一个事件。 - 省掉每个事件额外的 getter 往返——快照里已经持有新的
WINDOWPOS;尺寸/位置可以直接从它推导,而不是重新查询矩形 + DPI。 - Dispatcher 快路径(如果它被安装到应用窗口上——见开放问题 4):提供消息类别白名单或
anyHandlerCares位图,让不关心的消息直接到达原过程,绕过逐消息的 mutex/vector/sort;考虑用SetWindowSubclass取代GWLP_WNDPROC替换。 - 记录几何订阅的逐窗口成本,让宿主应用能决定自己注册什么。
关联
- nativeapi-core #78("Verify: events, input and icon reports from …")——这是一份 Windows 事件路径报告,带有复现结构,正好是该 issue 所要求的形态。
- 同一用户的早期报告:libnativeapi/nativeapi #18(caption 拖拽区域在 SIZEMOVE 模态循环中冻结;已由 0.5.3 的"事件在拥有窗口的线程上投递"修复)——本报告针对的正是那次修复所产生的投递路径的每步成本。
- 历史症状亲属:libnativeapi/nativeapi #17("从 0.2.5 起 resize 落后于指针")——当前
SetWindowSubclass设计正源自那次修复(见根因第 2 条引用的代码注释);本 issue 报告的残留正是那笔交易的另一半。 - 构建探针时还遇到(独立问题,你们的未发布树中已修复——0.5.10 仍没有):事件结构体变成 tree-shake 不可达时,AOT
gen_snapshot报"Class with illegal cid: native_window_event_t"——dart-lang/sdk#50540 workaround,CHANGELOG Unreleased / 你们的 #26,感谢。 - 状态核查(2026-11-10):0.5.10 是最新发布版;nativeapi-core
mainHEAD 仍包含上述确切行为(文件逐字节一致),两个 CHANGELOG 的 Unreleased 中都没有相关条目。
English original
Summary
On Windows, with nativeapi window listeners registered, an interactive edge-resize shows
clear content trailing behind the window frame (rubber-banding): the frame follows the
mouse while the Flutter content arrives frames late. During the sizing modal loop, every
rectangle step produces a WM_WINDOWPOSCHANGED; per step, nativeapi's geometry subclass
diffs a snapshot, queries rect + DPI (GetSize()), constructs a WindowMoved/Resized
event and delivers it to Dart through the NativeCallable +
delivery_is_active/delivery_complete handshake — all on the window thread, hundreds of
times per second. Dart-side frame timings stay healthy (in our Debug captures
rasterP50 ≈ 1.4 ms while frame pipeline span P50 ≈ 13–16 ms — shape, not absolutes),
pointing at platform-thread scheduling latency rather than rendering load.
A/B toggles at Release fidelity (same binary, single-variable probes below) attribute the
bulk of the regression to the per-step event path, with a measurable residual while merely
wrapped. We confirmed in code and in measurement that minimumSize / titleBarStyle
setter handlers install the generic WindowMessageDispatcher (full GWLP_WNDPROC swap)
on the app window even with zero listeners — so the per-message mutex/vector/sort path
taxes every message of a plain frameless app too (see root-cause item 4 and the
quantified section).
Machine-specific but consistent on our laptop: a scripted left-edge load of 1500 one-pixel
SetWindowPos steps produced exactly 1500 WindowMovedEvents + 1500
WindowResizedEvents — two constructed-and-delivered events per WM_WINDOWPOSCHANGED,
zero coalescing, and raised per-step window-thread wall time by ~1.3–1.8 ms on top of a
~10–13 ms bare-Flutter-window step (~10–15 %). Details and method in "Quantified
reproduction" below.
Environment
- nativeapi / cnativeapi / nativeapi_flutter: 0.5.10 (pub.dev; latest published as of
2026-11-10) window_manager_windows.cppon nativeapi-coremainHEAD is byte-for-byte identical
to the 0.5.10 pub package (we diffed it) — everything below is also current-upstream;
line numbers are shared between the two.- Flutter 3.47.6 stable (Windows x64), Dart 3.13
- Windows 11 (Build 26300), single GPU (RTX 4060 Laptop, direct panel)
- App: frameless window (
titleBarStyle = hidden), plain Flutter UI
How we isolated it (A/B on the same Release binary)
We built one app and toggled individual parts of our nativeapi usage at runtime:
| Configuration | Edge-drag feel |
|---|---|
| Full nativeapi usage (listener registered, hidden title bar, min size) | clearly trails |
hideTitleBar() skipped (frame/hit-test chain bypassed, listener still on) |
still trails |
minimumSize not set |
still trails |
Window wrapped, but addListener() never called |
nearly fine, faint residual |
| nativeapi Window wrapper not created at all (plain Win32 + Flutter) | smooth |
| Previous stack (window_manager 0.5.x + bitsdojo, no nativeapi) | smooth |
So the bulk of the cost tracks event registration and delivery; a smaller residual tracks the
wrapper's own per-message chains (geometry subclass + title-bar/hit-test handlers), present in
every row where the wrapper existed.
Quantified reproduction (standalone probe app, same binary, env-toggled arms)
Because we cannot script a real mouse-drag reproducibly, we drive the same message path a
drag uses: a separate process issues SetWindowPos one-pixel oscillations on the window's
left edge (x+1/w−1 then x−1/w+1). Every step crosses the sizing message path
(WM_WINDOWPOSCHANGED) and each call blocks until the window thread has finished handling
it — so wall-time-per-step is window-thread work time. The probe app is a plain
flutter create Windows app that binds its runner HWND via
Window.createWithNativeWindow; arms are runtime env toggles:
| Arm | Listener | titleBarStyle=hidden |
minimumSize |
meaning |
|---|---|---|---|---|
| B | — | — | — | bare Flutter window (baseline) |
| A | ✔ | — | — | geometry event chain only |
| C | ✔ | ✔ | ✔ | our pre-fix app shape |
| D | — | ✔ | ✔ | our post-fix app shape (events unsubscribed) |
Results (Release, RTX 4060 laptop, 1500 steps/arm/round, rounds interleaved; thermal drift
made late rounds uniformly slower, so treat deltas as ~±0.5 ms):
- Event count per step — zero coalescing. Arm A/C runs recorded
moved = 1500andresized = 1500for 1500 left-edge steps: exactly two
constructed + Dart-delivered events perWM_WINDOWPOSCHANGED(a left/right-edge drag
mutates position and size, so both branches ofOnWindowChangedfire). Sustained
~165 events/s during the load; in one run 8 of 3000 were skipped, so delivery is neither
lossless nor coalesced. This matches the code:moved(:834-835) andresized
(:837-839) are independentifs, andOnWindowEvent(:892-901) re-queries the registryGetSize()/GetPosition()per event.
- Per-step window-thread tax. Paired same-round deltas:
A−B ≈ +1.3 … +1.8 ms/step
on top of aB ≈ 9.6 … 13.8 ms/stepbare baseline (~10–15 %);C−B ≈ +1.7 … +2.4.
The event chain alone accounts for most of it, consistent with the subjective ladder. - Side finding (behavioral, maybe intended): applying
titleBarStyle = TitleBarStyle.hiddento an already-visible window cleared
WS_VISIBLE— the window kept its geometry butIsWindowVisiblereturned false until we
calledshow()again. Our app dodged this only because it follows the
hide → set-style → show order.
Probe app + driver are tiny (~150 lines total); happy to attach or post them if useful.
Root-cause pointers (cnativeapi-0.5.10)
- Geometry events are built and delivered per drag step, on the window thread —
two per step on an edge drag.
window_manager_windows.cpp:203-217—WindowGeometryProc(installed via
SetWindowSubclassbyWatchWindowGeometry, :222-224) interceptsWM_WINDOWPOSCHANGED,
calls the original procedure first, thenOnWindowChanged(:778-841) diffs a snapshot
(:769-775,GetWindowRect+IsIconic+IsZoomed) and firesmoved(:834-835) and
resized(:837-839) independently — an edge drag changes both x and width, so both
fire per step (measured: exactly 1500+1500 events for 1500 steps, zero coalescing).
Each event additionally re-queries geometry through the C++ getters
(OnWindowEvent,window_manager_windows.cpp:862-906→ registry lookup +
window->GetSize()/GetPosition()= rect + DPI math), constructs a
WindowMoved/WindowResized, and delivers it viaNativeCallablewith the
native_event_delivery_is_active/native_event_delivery_completehandshake
(bindings/dart/nativeapi/lib/src/callbacks.dart,deliverEvent;
DispatchWindowEvent:1199-1202). During an edge drag,WM_WINDOWPOSCHANGEDarrives at
mouse-sampling rate — hundreds of these builds+crossings per second on the thread that
must also keep the sizing modal loop and theWM_SIZE → MoveWindow(child) → engine presentchain moving. - Your own code documents this failure mode.
window_manager_windows.cpp:143-148explains why geometry reporting is a subclass rather
than anEVENT_OBJECT_LOCATIONCHANGEWinEvent hook: out-of-context WinEvents "are
delivered whenever [the thread] next reads a message — in the middle of Flutter's resize,
which pumps messages while it waits for a frame of the new size … and the listeners called
from there (Dart ones synchronously) made every resize step late." The subclass moves
the delivery point to a well-defined place; it does not reduce the per-step work itself. - Coalescing exists for occlusion, but not for Moved/Resized.
window_manager_windows.cpp:511,546-547— the occlusion path arms a 100 ms timer
because "the events come in bursts (a drag moves a window dozens of times a second)".
WindowMoved/WindowResizedhave no equivalent throttle: measured exactly two events
perWM_WINDOWPOSCHANGEDon an edge drag. - Confirmed: the generic dispatcher is installed on plain app windows — by the
standard setters, even with zero listeners.
WindowMessageDispatcher::RegisterHandler(hwnd, …)
(window_message_dispatcher.cpp:34-52) callsInstallHook(hwnd)(:163-186), a
SetWindowLongPtr(GWLP_WNDPROC, DispatchWindowProc)swap — and the callers are everyday
features: the min/max-size handler (window_windows.cpp:1560-1568,WM_GETMINMAXINFO),
always-on-bottom (:1659-1667), and the title-bar/hit-test handler (:~1700). So
minimumSize/titleBarStylealone put every message of the app window through the
per-messagemutexsnapshot + two hash lookups +std::vectoralloc +std::sortpath
(window_message_dispatcher.cpp:96-161), including the high-rate non-client messages of
a drag (WM_NCHITTEST,WM_MOUSEMOVE,WM_SIZING). Our no-listener arm D still cost
~+1–2 ms/step over baseline, in addition to the item-1 event-chain tax (arm A); item 1
dominates, but both need fixing to fully close the gap.
Minimal reproduction
A Flutter Windows app with:
final window = na.WindowManager.instance.getCurrent()!; // or wrap the runner HWND
final id = window.addListener((e) { /* no-op */ }); // keep listener registered
// frameless:
window.titleBarStyle = na.TitleBarStyle.hidden;
Then drag a window edge horizontally at a moderate, steady pace and compare with the
addListener line removed (or removeListener before dragging). The difference is easy to
see with the frame vs. content boundary; it is most visible while the window contains a
static high-contrast layout (so any content lag is obvious).
If you want quantitative capture without a human drag: the "Quantified reproduction"
section above scripts the same message path (SetWindowPos left-edge oscillation from a
second process) and counts the resulting Dart-side events; we also suggest timing
WM_WINDOWPOSCHANGED handling in WindowGeometryProc (entry to return) and the Dart
delivery handshake with QueryPerformanceCounter, histogrammed over one 10 s load,
listener-registered vs. not.
Suggested fixes (any of, or better ideas)
- Coalesce/throttle Moved/Resized delivery — you already do exactly this for occlusion:
arm a timer on burst events, and always emit atWM_ENTERSIZEMOVE/WM_EXITSIZEMOVE
session edges with latest geometry. Most apps need session edges + a throttled stream,
not one event perWM_WINDOWPOSCHANGED. - Skip the extra getter round-trips per event — the snapshot already holds the new
WINDOWPOS; size/position could be derived from it instead of re-querying rect + DPI. - Dispatcher fast path (if it is installed on app windows — open question 4): a
message-class whitelist oranyHandlerCaresbitmap so non-consumable messages reach the
original procedure without the per-message mutex/vector/sort; considerSetWindowSubclass
instead of theGWLP_WNDPROCswap. - Document the per-window cost of geometry subscriptions so host apps can decide what they
register.
Related
- nativeapi-core #78 ("Verify: events, input and icon reports from …") — this is a Windows
event-path report with a repro structure, in exactly the shape that issue asks for. - Earlier report from the same user: libnativeapi/nativeapi #18 (caption-drag region
freezing during the modal SIZEMOVE loop; fixed by 0.5.3 "events are delivered on the
thread that owns the windows") — this new report is about the per-step cost of the
delivery path that fix produced. - Historical symptom sibling: libnativeapi/nativeapi #17 ("resize lags behind the
pointer starting with 0.2.5") — the currentSetWindowSubclassdesign was born from
that fix (see the code comment quoted in root-cause item 2); the residual this issue
reports is the other half of that trade. - Also hit while building probes (separate, already fixed in your unreleased tree — still
absent from 0.5.10): AOTgen_snapshot"Class with illegal cid: native_window_event_t"
when event struct becomes tree-shake-unreachable — dart-lang/sdk#50540 workaround,
CHANGELOG Unreleased / your #26, thanks for that. - Status check (2026-11-10): 0.5.10 is the latest published; nativeapi-core
mainHEAD
still contains the exact behavior above (byte-identical file), no related entry in either
CHANGELOG's Unreleased.
- Linguagem predominante
- TypeScript
- Estrelas
- 172
- Forks
- 16
- Merge médio
- 40min
- PRs com merge (30d)
- 2
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de libnativeapi/nativeapi
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
libnativeapi/nativeapi#32 ·
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 56/100
libnativeapi/nativeapi#31 · 1 comentário · 2 reações ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 38/100
libnativeapi/nativeapi#29 ·
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 56/100
libnativeapi/nativeapi#28 · 3 comentários ·
-
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 35/100
libnativeapi/nativeapi#27 ·
Todas as issues de libnativeapi/nativeapi
Issues semelhantes
-
Mend: dependency security vulnerability
Dificuldade 1/5 1-3 horas Facilidade para iniciantes 65/100
fdm-monster/fdm-monster#5563 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
be-BOP-io-SA/be-BOP#2849 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 79/100
Mantenedores costumam responder em até 1 dia
-
1️⃣ phase/under-investigation flaky/confirmed flaky/needs-decision type/bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 65/100
growilabs/growi#12246 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
-
🐛 The Rulekeeper - An index run that gives up on the lock ends SucceededTalvez já em andamento @github-actions assumiu hoje. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
SSWConsulting/SSW.Rules#2809 · 1 comentário ·
Mantenedores costumam responder em até 1 dia