fix: 🐛 press m & move w/ arrows
This commit is contained in:
parent
5df7f40b3c
commit
aa9d613f50
6 changed files with 327 additions and 8 deletions
|
|
@ -186,7 +186,8 @@ all: minimal_test.html \
|
|||
$(S)/coroutine-pthread/nested_repro_ex.html \
|
||||
$(S)/coroutine-pthread/vcall_repro.html \
|
||||
$(S)/textctrl-reentry/textctrl-reentry_test.html \
|
||||
$(S)/tooltip-lifetime/tooltip-lifetime_test.html
|
||||
$(S)/tooltip-lifetime/tooltip-lifetime_test.html \
|
||||
$(S)/warp-pointer/warp-pointer_test.html
|
||||
|
||||
# Main test app
|
||||
minimal_test.o: minimal_test.cpp
|
||||
|
|
@ -216,6 +217,15 @@ $(S)/tooltip-lifetime/tooltip-lifetime_test.html: $(S)/tooltip-lifetime/tooltip-
|
|||
|
||||
tooltip-lifetime: $(S)/tooltip-lifetime/tooltip-lifetime_test.html
|
||||
|
||||
# wxWindow::WarpPointer must update the cached mouse position (wxGetMousePosition).
|
||||
$(S)/warp-pointer/warp-pointer_test.o: $(S)/warp-pointer/warp-pointer_test.cpp
|
||||
$(CXX) -c $(CXXFLAGS) $< -o $@
|
||||
|
||||
$(S)/warp-pointer/warp-pointer_test.html: $(S)/warp-pointer/warp-pointer_test.o $(WX_CORE_LIB) $(JS_FILES)
|
||||
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
|
||||
|
||||
warp-pointer: $(S)/warp-pointer/warp-pointer_test.html
|
||||
|
||||
# Menu test (no GL)
|
||||
$(S)/menu/menu_test.o: $(S)/menu/menu_test.cpp
|
||||
$(CXX) -c $(CXXFLAGS) $< -o $@
|
||||
|
|
|
|||
93
tests/apps/standalone/warp-pointer/warp-pointer_test.cpp
Normal file
93
tests/apps/standalone/warp-pointer/warp-pointer_test.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// wxWindow::WarpPointer must update the cached mouse position (DOM port).
|
||||
//
|
||||
// Bug (src/wasm/window.cpp): wxWindowWasm::WarpPointer() is a no-op because the
|
||||
// browser cannot move the OS pointer. KiCad nudges the cursor with the arrow
|
||||
// keys by warping the pointer and then reading it back via wxGetMousePosition()
|
||||
// (WX_VIEW_CONTROLS::SetCursorPosition -> WarpMouseCursor -> WarpPointer, then
|
||||
// the interactive-move loop reads GetViewControls()->GetMousePosition()). With
|
||||
// the warp a no-op the cached position never changes, so a selected item never
|
||||
// follows the arrow keys and snaps to the stale cursor on grab.
|
||||
//
|
||||
// The invariant the bug violates: after WarpPointer(x, y), wxGetMousePosition()
|
||||
// must report the screen-space equivalent of (x, y) — exactly what a real OS
|
||||
// pointer warp produces on desktop.
|
||||
//
|
||||
// RED (bug present): wxGetMousePosition() is unchanged by the warp.
|
||||
// GREEN (fixed): wxGetMousePosition() == ClientToScreen({x, y}).
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
static void Report(const char *name, bool pass, const wxString &detail)
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_ASM({
|
||||
var msg = '[REPRO] ' + UTF8ToString($0) + ': ' + ($1 ? 'PASS' : 'FAIL')
|
||||
+ ' - ' + UTF8ToString($2);
|
||||
if ($1) { console.log(msg); } else { console.error(msg); }
|
||||
}, name, pass ? 1 : 0, (const char *)detail.utf8_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
class ReproFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
ReproFrame();
|
||||
|
||||
private:
|
||||
void RunTest();
|
||||
};
|
||||
|
||||
ReproFrame::ReproFrame()
|
||||
: wxFrame(nullptr, wxID_ANY, "wxWindow::WarpPointer repro")
|
||||
{
|
||||
CallAfter(&ReproFrame::RunTest);
|
||||
}
|
||||
|
||||
void ReproFrame::RunTest()
|
||||
{
|
||||
// Two distinct targets so a stale/default cached position cannot accidentally
|
||||
// match. Warp to each, then require wxGetMousePosition() to report the
|
||||
// screen-space equivalent (the same conversion a real OS warp performs).
|
||||
const wxPoint targets[] = { wxPoint(137, 211), wxPoint(56, 92) };
|
||||
|
||||
bool allPass = true;
|
||||
wxString detail;
|
||||
|
||||
for (const wxPoint &client : targets)
|
||||
{
|
||||
WarpPointer(client.x, client.y);
|
||||
|
||||
const wxPoint expected = ClientToScreen(client);
|
||||
const wxPoint actual = wxGetMousePosition();
|
||||
const bool pass = (actual == expected);
|
||||
allPass = allPass && pass;
|
||||
|
||||
detail += wxString::Format("[client=(%d,%d) expected=(%d,%d) actual=(%d,%d) %s] ",
|
||||
client.x, client.y, expected.x, expected.y,
|
||||
actual.x, actual.y, pass ? "ok" : "MISMATCH");
|
||||
}
|
||||
|
||||
Report("warppointer_updates_position", allPass, detail);
|
||||
}
|
||||
|
||||
class ReproApp : public wxApp
|
||||
{
|
||||
public:
|
||||
bool OnInit() override
|
||||
{
|
||||
if (!wxApp::OnInit())
|
||||
return false;
|
||||
|
||||
(new ReproFrame())->Show(true);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
wxIMPLEMENT_APP(ReproApp);
|
||||
Loading…
Reference in a new issue