--- nono/wx/wxmainview.cpp 2026/04/29 17:04:37 1.1.1.4 +++ nono/wx/wxmainview.cpp 2026/04/29 17:04:39 1.1.1.5 @@ -43,8 +43,6 @@ #define DONT_USE_REFRESH 1 #endif -#define TIMERID_PAINTTIMER 1 - static void wxmainview_refresh(); WXMainView *gMainView; @@ -54,7 +52,7 @@ wxBEGIN_EVENT_TABLE(WXMainView, inherite EVT_KEY_DOWN(WXMainView::OnKeyDown) EVT_KEY_UP(WXMainView::OnKeyUp) EVT_MOUSE_EVENTS(WXMainView::OnMouse) - EVT_TIMER(TIMERID_PAINTTIMER, WXMainView::OnTimer) + EVT_TIMER(wxID_ANY, WXMainView::OnTimer) wxEND_EVENT_TABLE() WXMainView::WXMainView(wxWindow *parent) @@ -74,9 +72,12 @@ WXMainView::WXMainView(wxWindow *parent) // 実画面 (ウィンドウの大きさ) DoResize(screen_scale); - paintTimer.SetOwner(this, TIMERID_PAINTTIMER); - paintTimer.Start(16); - paintRequested = true; // first paint request + // 描画を律速するためのタイマー + timer.SetOwner(this); + timer.Start(33); + + // 最初に一度描画 + Refresh(); } WXMainView::~WXMainView() @@ -103,19 +104,24 @@ WXMainView::DoRefresh() RefreshRect(wxRect(0, 0, viewwidth, viewheight), false); #endif - // PAINT イベントを投げる - // XXX んだけど mac だと投げすぎるとシステムイベントを拾えなくなってしまう - paintRequested = true; + // ここは VM Renderer が画面を更新した時に呼ばれるので、本来なら + // ここで単に Refresh() を呼んで再描画を指示すればいいのだが、 + // VM 高速モードになると、VM Renderer が高速で回ってここも高速で + // 呼ばれてしまい、その結果 Refresh() を発行しすぎて Mac では + // システムイベントが拾えなくなってしまう。 + // それを避けるため、ここではフラグを立てるだけにしておいて、 + // こちらで管理している実時間タイマーで Refresh() を律速する。 + paint_request = true; } +// タイマーイベント void WXMainView::OnTimer(wxTimerEvent& event) { - bool req = paintRequested.exchange(false); + bool req = paint_request.exchange(false); if (req) { - // PAINT イベントを投げる - wxPaintEvent *ev = new wxPaintEvent(); - QueueEvent(ev); + // 実際に再描画する + Refresh(); } } @@ -123,20 +129,10 @@ WXMainView::OnTimer(wxTimerEvent& event) void WXMainView::OnPaint(wxPaintEvent& event) { - wxClientDC dc(this); - - DoPaint(dc); -} - -// 描画実行 -void -WXMainView::DoPaint(wxDC& dc) -{ if (viewwidth == 0 || viewheight == 0) return; wxImage image(rendwidth, rendheight, ImageBuf.get(), true); - if (viewwidth != rendwidth || viewheight != rendheight) { // wxIMAGE_QUALITY_NORMAL だと速いが、品質優先。 image.Rescale(viewwidth, viewheight, wxIMAGE_QUALITY_HIGH); @@ -146,6 +142,7 @@ WXMainView::DoPaint(wxDC& dc) wxMemoryDC memDC; memDC.SelectObject(bitmap); + wxPaintDC dc(this); wxRegion region(0, 0, viewwidth, viewheight); wxRegionIterator ri(region); for (; ri; ri++) { @@ -254,7 +251,7 @@ WXMainView::OnMouse(wxMouseEvent& event) bool rb = event.RightIsDown(); bool lb = event.LeftIsDown(); bool mb = event.MiddleIsDown(); - wxPoint pos = event.GetPosition(); + const wxPoint& pos = event.GetPosition(); int dx = 0; int dy = 0;