--- nono/wx/wxmainview.cpp 2026/04/29 17:04:33 1.1.1.3 +++ nono/wx/wxmainview.cpp 2026/04/29 17:04:37 1.1.1.4 @@ -1,19 +1,16 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "wxheader.h" +#include "wxmainview.h" #include "keyboard.h" #include "mystring.h" #include "renderer.h" #include "scheduler.h" -#include "wxmainview.h" #include #include -#if defined(__NetBSD__) -#include // __NetBSD_Version__ -#endif //#define KEYDEBUG 1 //#define MOUSEDEBUG 1 @@ -40,8 +37,9 @@ // Refresh{,Rect}() を呼ばず、再描画矩形を画面全体として運用する。 // ちょっと無駄なだけなので (動かないことに比べれば) 気にしない。 // -// 今のところ NetBSD 5.0 以上(と Linux (CentOS 6.3/x86_64)) が該当する。 -#if defined(__NetBSD__) && __NetBSD_Version__ >= 500000000 +// 今のところ NetBSD (5.0 以降) と OpenBSD(/amd64)(-6.7) +// (と Linux (CentOS 6.3/x86_64)) が該当する。 +#if defined(__NetBSD__) || defined(__OpenBSD__) #define DONT_USE_REFRESH 1 #endif @@ -68,10 +66,10 @@ WXMainView::WXMainView(wxWindow *parent) // レンダラバッファは常に仮想画面サイズ int buflen = rendwidth * rendheight * 3; - ImageBuf = new uint8_t[buflen]; - memset(ImageBuf, 0x70, buflen); + ImageBuf.reset(new uint8_t[buflen]); + memset(&ImageBuf[0], 0x70, buflen); // レンダラに通知 - gRenderer->SetBuf(ImageBuf, wxmainview_refresh); + gRenderer->SetBuf(ImageBuf.get(), wxmainview_refresh); // 実画面 (ウィンドウの大きさ) DoResize(screen_scale); @@ -83,7 +81,6 @@ WXMainView::WXMainView(wxWindow *parent) WXMainView::~WXMainView() { - delete[] ImageBuf; } // リフレッシュ要求コールバック。 @@ -138,7 +135,7 @@ WXMainView::DoPaint(wxDC& dc) if (viewwidth == 0 || viewheight == 0) return; - wxImage image(rendwidth, rendheight, ImageBuf, true); + wxImage image(rendwidth, rendheight, ImageBuf.get(), true); if (viewwidth != rendwidth || viewheight != rendheight) { // wxIMAGE_QUALITY_NORMAL だと速いが、品質優先。 @@ -209,6 +206,8 @@ WXMainView::SetMouseMode(bool mode) // マウスカーソル OFF ::wxSetCursor(wxCursor(wxCURSOR_BLANK)); + CaptureMouse(); + // このウィンドウから外れないように移動を検出し続けるため、 // マウスカーソルをウィンドウ中央に移す。 // ウィンドウとメニューバーが分離してる wxOSX のために必要。 @@ -217,8 +216,11 @@ WXMainView::SetMouseMode(bool mode) // マウスモードを OFF にする DMPRINTF("SetMouseMode OFF\n"); + ReleaseMouse(); + // 分かりやすさのため、マウスカーソルを中央へ戻してから復帰 - MyWarpPointer(GetClientSize() / 2); + wxSize pt = GetClientSize() / 2; + WarpPointer(pt.x, pt.y); // マウスカーソル ON ::wxSetCursor(wxNullCursor); @@ -267,7 +269,7 @@ WXMainView::OnMouse(wxMouseEvent& event) dstr += " Dragging"; if (motion_by_warp_pointer) dstr += " MotionByWarp"; - if (event.IsButton()) { + if (lb || mb || rb) { dstr += string_format(" Button(%c%c%c)", (lb ? 'L' : '-'), (mb ? 'M' : '-'), @@ -328,6 +330,26 @@ WXMainView::OnMouse(wxMouseEvent& event) event.Skip(); } +// アクティベートイベント。 +// この(トップレベル)ウィンドウにフォーカスが当たるか外れるかで飛んでくる。 +// 実際には WXMainFrame 宛てに飛んできたイベントをこちらに転送してある。 +// マウスモード中にこのウィンドウからフォーカスが外れたら (例えば ALT+TAB の +// ようなウィンドウを切り替える操作)、マウスモードを解除するため。 +void +WXMainView::OnActivate(wxActivateEvent& event) +{ + // フォーカスが外れる際にマウスモード中ならマウスモードを解除 + if (event.GetActive() == false) { + DMPRINTF("OnActivate FocusOut\n"); + if (mousemode) { + SetMouseMode(false); + } + } else { + DMPRINTF("OnActivate FocusIn\n"); + } +} + + // // キー入力 //