From 174a032126ecc89bbe5ed76fcc2cb311a560dd9f Mon Sep 17 00:00:00 2001 From: cxl Date: Sat, 12 Sep 2020 08:14:41 +0000 Subject: [PATCH] CtrlCore: Fixed mouse event handling popup related issues in MacOS git-svn-id: svn://ultimatepp.org/upp/trunk@15019 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlCore/CocoApp.mm | 2 +- uppsrc/CtrlCore/CocoCtrl.h | 1 + uppsrc/CtrlCore/CocoMM.h | 10 +++++++++- uppsrc/CtrlCore/CocoProc.mm | 32 +++++++++++++++++++++++++++++++- uppsrc/CtrlCore/CocoWin.mm | 13 +++++-------- 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/uppsrc/CtrlCore/CocoApp.mm b/uppsrc/CtrlCore/CocoApp.mm index 8a3a010b9..db0ddbd18 100644 --- a/uppsrc/CtrlCore/CocoApp.mm +++ b/uppsrc/CtrlCore/CocoApp.mm @@ -32,7 +32,7 @@ void SyncPopupFocus(NSWindow *win) Ctrl *q = Ctrl::GetFocusCtrl(); if(q) { q = q->GetTopCtrl(); - if(q->IsPopUp() && q->GetNSWindow() != win) { + if(q->IsPopUp() && q->GetNSWindow() != win && q->IsCocoActive()) { q = q->GetOwner(); if(q) q->SetFocus(); } diff --git a/uppsrc/CtrlCore/CocoCtrl.h b/uppsrc/CtrlCore/CocoCtrl.h index 1658c62fc..230480e7d 100644 --- a/uppsrc/CtrlCore/CocoCtrl.h +++ b/uppsrc/CtrlCore/CocoCtrl.h @@ -25,6 +25,7 @@ public: void *GetNSWindow() const; void *GetNSView() const; + bool IsCocoActive() const; void RegisterCocoaDropFormats(); diff --git a/uppsrc/CtrlCore/CocoMM.h b/uppsrc/CtrlCore/CocoMM.h index 8d4e0a5c7..5cdb4ad2c 100644 --- a/uppsrc/CtrlCore/CocoMM.h +++ b/uppsrc/CtrlCore/CocoMM.h @@ -80,12 +80,20 @@ struct RectCG { } @end +@interface CocoWindow : NSWindow +{ + @public + Upp::Ptr ctrl; + bool active; +} +@end + struct Upp::MMCtrl { static void SyncRect(CocoView *view); }; struct Upp::CocoTop { - NSWindow *window = NULL; + CocoWindow *window = NULL; CocoView *view = NULL; Ptr owner; }; diff --git a/uppsrc/CtrlCore/CocoProc.mm b/uppsrc/CtrlCore/CocoProc.mm index 4e394e36c..256de3dbe 100644 --- a/uppsrc/CtrlCore/CocoProc.mm +++ b/uppsrc/CtrlCore/CocoProc.mm @@ -125,6 +125,36 @@ struct MMImp { Rect r = view->ctrl->GetRect(); Upp::Point p(DPI(np.x), DPI(np.y)); coco_mouse_pos = p + r.TopLeft(); + + if(event == Ctrl::MOUSEMOVE) { + static Point coco_mouse_pos_old(-10000, -10000); + if(coco_mouse_pos_old == coco_mouse_pos) { // duplicate for another window, ignore + sCurrentMouseEvent__ = NULL; + return false; + } + coco_mouse_pos_old = coco_mouse_pos; + + if(coco_capture) + coco_capture->DispatchMouse(event, coco_mouse_pos - coco_capture->GetScreenRect().TopLeft(), 120 * sgn(zd)); + else { + Vector t = Ctrl::GetTopCtrls(); // Find window that contains the mouse, from the top + for(NSNumber *num in [NSWindow windowNumbersWithOptions:0]) { // All app windows + NSWindow *win = [NSApp windowWithWindowNumber:[num integerValue]]; + if(win) { + int q = FindMatch(t, [&](Ctrl *t) { return t->GetNSWindow() == win; }); + if(q >= 0) { + Ctrl *w = t[q]; + Rect r = w->GetRect(); // same as ScreenRect + if(w->IsEnabled() && r.Contains(coco_mouse_pos)) { + w->DispatchMouse(event, coco_mouse_pos - r.TopLeft(), 120 * sgn(zd)); + break; + } + } + } + } + } + } + else if(view->ctrl->IsEnabled() && (view->ctrl->HasWndCapture() || r.Contains(coco_mouse_pos))) view->ctrl->DispatchMouse(event, p, 120 * sgn(zd)); sCurrentMouseEvent__ = NULL; @@ -413,4 +443,4 @@ struct MMImp { @end -#endif \ No newline at end of file +#endif diff --git a/uppsrc/CtrlCore/CocoWin.mm b/uppsrc/CtrlCore/CocoWin.mm index b847b9d9b..ee921ce94 100644 --- a/uppsrc/CtrlCore/CocoWin.mm +++ b/uppsrc/CtrlCore/CocoWin.mm @@ -4,14 +4,6 @@ #define LLOG(x) -@interface CocoWindow : NSWindow -{ - @public - Upp::Ptr ctrl; - bool active; -} -@end - @implementation CocoWindow - (void)becomeKeyWindow { @@ -362,6 +354,11 @@ void TopWindow::Overlap(bool effect) [top->coco->window deminiaturize:top->coco->window]; } +bool Ctrl::IsCocoActive() const +{ + return top && top->coco && top->coco->window && top->coco->window->active; +} + } #endif