From a7d1972fc12e573acadf0ef7e88701820217d594 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 2 Oct 2018 15:40:41 +0000 Subject: [PATCH] CtrlCore: Cocoa: Now using NSTrackingArea, focus and other bugs git-svn-id: svn://ultimatepp.org/upp/trunk@12328 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlCore/Coco.h | 2 +- uppsrc/CtrlCore/CocoApp.mm | 54 ++++++++++++++++++----------------- uppsrc/CtrlCore/CocoCreate.mm | 14 ++++----- uppsrc/CtrlCore/CocoDraw.mm | 3 +- uppsrc/CtrlCore/CocoImage.mm | 2 +- uppsrc/CtrlCore/CocoProc.mm | 24 +++++++++++++--- uppsrc/CtrlCore/CocoTop.h | 2 ++ uppsrc/CtrlCore/Ctrl.cpp | 2 +- uppsrc/CtrlCore/CtrlKbd.cpp | 4 +-- uppsrc/CtrlCore/TopWindow.cpp | 5 +++- uppsrc/CtrlCore/cocotodo.txt | 13 +++++++-- uppsrc/CtrlLib/EditField.cpp | 2 +- 12 files changed, 79 insertions(+), 48 deletions(-) diff --git a/uppsrc/CtrlCore/Coco.h b/uppsrc/CtrlCore/Coco.h index a1665113d..c58dae1f5 100644 --- a/uppsrc/CtrlCore/Coco.h +++ b/uppsrc/CtrlCore/Coco.h @@ -39,7 +39,7 @@ private: Vector clip; Color fill = Null; - + void Push(); void Pop(); diff --git a/uppsrc/CtrlCore/CocoApp.mm b/uppsrc/CtrlCore/CocoApp.mm index 465aa8a33..54ac550e4 100644 --- a/uppsrc/CtrlCore/CocoApp.mm +++ b/uppsrc/CtrlCore/CocoApp.mm @@ -10,26 +10,6 @@ int Ctrl::WndCaretTime; bool Ctrl::WndCaretVisible; static NSAutoreleasePool *main_coco_pool; -static NSEvent *current_event; - -static NSEvent *GetNextEvent(NSDate *until) -{ - if(!current_event) { - current_event = [NSApp nextEventMatchingMask:NSEventMaskAny - untilDate:until - inMode:NSDefaultRunLoopMode dequeue:YES]; - [current_event retain]; - } - return current_event; -} - -static void ReleaseCurrentEvent() -{ - if(current_event) { - [current_event release]; - current_event = nil; - } -} void SyncPopupFocus(NSWindow *win) { @@ -97,12 +77,6 @@ void CocoInit(int argc, const char **argv, const char **envptr) Ctrl::Csizeinit(); } -void CocoExit() -{ - ReleaseCurrentEvent(); - [main_coco_pool release]; -} - int Ctrl::GetKbdDelay() { GuiLock __; @@ -115,6 +89,34 @@ int Ctrl::GetKbdSpeed() return int(1000 * NSEvent.keyRepeatInterval); } +static NSEvent *current_event; + +static NSEvent *GetNextEvent(NSDate *until) +{ + if(!current_event) { + current_event = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:until + inMode:NSDefaultRunLoopMode + dequeue:YES]; + [current_event retain]; + } + return current_event; +} + +static void ReleaseCurrentEvent() +{ + if(current_event) { + [current_event release]; + current_event = nil; + } +} + +void CocoExit() +{ + ReleaseCurrentEvent(); + [main_coco_pool release]; +} + bool Ctrl::IsWaitingEvent() { return GetNextEvent(nil); diff --git a/uppsrc/CtrlCore/CocoCreate.mm b/uppsrc/CtrlCore/CocoCreate.mm index 1d2572625..2ac9aa648 100644 --- a/uppsrc/CtrlCore/CocoCreate.mm +++ b/uppsrc/CtrlCore/CocoCreate.mm @@ -106,7 +106,7 @@ void Ctrl::Create(Ctrl *owner, dword style, bool active) top = new Top; top->coco = new CocoTop; top->coco->owner = owner; - + NSRect frame = DesktopRect(GetRect()); CocoWindow *window = [[CocoWindow alloc] initWithContentRect:frame styleMask: style backing:NSBackingStoreBuffered defer:false]; @@ -117,6 +117,8 @@ void Ctrl::Create(Ctrl *owner, dword style, bool active) window->ctrl = this; window->active = active; window.backgroundColor = [NSColor clearColor]; + + isopen = true; CocoView *view = [[[CocoView alloc] initWithFrame:frame] autorelease]; view->ctrl = this; @@ -125,10 +127,9 @@ void Ctrl::Create(Ctrl *owner, dword style, bool active) [window setDelegate:view]; [window setAcceptsMouseMovedEvents:YES]; [window makeFirstResponder:view]; - [window makeKeyAndOrderFront:view]; + [window makeKeyAndOrderFront:window]; MMCtrl::SyncRect(view); - isopen = true; mmtopctrl.Add(this); RegisterCocoaDropFormats(); @@ -177,6 +178,7 @@ void Ctrl::WndScrollView(const Rect& r, int dx, int dy) bool Ctrl::IsWndOpen() const { GuiLock __; +// DLOG("IsWndOpen " << Upp::Name(this) << ": " << (bool)top); return top; } @@ -224,17 +226,15 @@ void TopWindow::Open(Ctrl *owner) SetRect((center == 1 ? owner->GetRect() : owner ? owner->GetWorkArea() : GetPrimaryWorkArea()) .CenterRect(GetRect().GetSize())); + placefocus = true; Create(owner, GetMMStyle(), true); - ActivateWnd(); SyncCaption(); SyncSizeHints(); - PlaceFocus(); if(state == MAXIMIZED) Maximize(); if(state == MINIMIZED) Minimize(); -// if(top) -// top->placefocus = true; + // Note: window is activated and PlaceFocus invoked by event, later } void TopWindow::Open() diff --git a/uppsrc/CtrlCore/CocoDraw.mm b/uppsrc/CtrlCore/CocoDraw.mm index 8d3f452a7..98f4ffe66 100644 --- a/uppsrc/CtrlCore/CocoDraw.mm +++ b/uppsrc/CtrlCore/CocoDraw.mm @@ -57,7 +57,8 @@ void SystemDraw::Pop() offset.Drop(); if(clip.GetCount()) clip.Drop(); - CGContextRestoreGState(cgHandle); + if(cgHandle) + CGContextRestoreGState(cgHandle); fill = Null; } diff --git a/uppsrc/CtrlCore/CocoImage.mm b/uppsrc/CtrlCore/CocoImage.mm index 10b132512..dc9a0aa9b 100644 --- a/uppsrc/CtrlCore/CocoImage.mm +++ b/uppsrc/CtrlCore/CocoImage.mm @@ -171,7 +171,6 @@ void Ctrl::SetMouseCursor(const Image& img) { if(GetDragAndDropSource()) return; - int64 h = img.GetAuxData(); if(h) { [GetNSCursor(h) set]; @@ -242,6 +241,7 @@ Draw& ImageDraw::Alpha() ImageDraw::~ImageDraw() { CGContextRelease(cgHandle); + handle = NULL; // avoid releasing invalid handle in ~SystemDraw } Image ImageDraw::GetStraight() diff --git a/uppsrc/CtrlCore/CocoProc.mm b/uppsrc/CtrlCore/CocoProc.mm index 45460d84a..b6e373c70 100644 --- a/uppsrc/CtrlCore/CocoProc.mm +++ b/uppsrc/CtrlCore/CocoProc.mm @@ -168,11 +168,11 @@ struct MMImp { { LLOG("Become key " << Upp::Name(ctrl)); ctrl->ActivateWnd(); -/* auto tw = dynamic_cast(ctrl); - if(tw && ctrl->top && ctrl->top->placefocus) { + auto tw = dynamic_cast(ctrl); + if(tw && tw->placefocus) { tw->PlaceFocus(); - ctrl->top->placefocus = false; - }*/ + tw->placefocus = false; + } } static void ResignKey(Upp::Ctrl *ctrl) @@ -341,6 +341,22 @@ struct MMImp { return Upp::MMImp::DnD(ctrl, sender, true) != NSDragOperationNone; } +- (void)updateTrackingAreas +{ + for(NSTrackingArea *t in [self trackingAreas]) + [self removeTrackingArea:t]; + + Upp::Size sz = ctrl->GetScreenRect().GetSize(); + NSTrackingArea *ta = [[NSTrackingArea alloc] + initWithRect:NSMakeRect(0, 0, sz.cx, sz.cy) + options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways| + NSTrackingInVisibleRect|NSTrackingMouseMoved|NSTrackingCursorUpdate + owner:self + userInfo:nil]; + [self addTrackingArea:ta]; + [ta release]; +} + @end #endif \ No newline at end of file diff --git a/uppsrc/CtrlCore/CocoTop.h b/uppsrc/CtrlCore/CocoTop.h index d98c7105e..bf87ffc01 100644 --- a/uppsrc/CtrlCore/CocoTop.h +++ b/uppsrc/CtrlCore/CocoTop.h @@ -1,6 +1,8 @@ //$ class TopWindow { protected: friend struct MMImp; + + bool placefocus; dword GetMMStyle() const; diff --git a/uppsrc/CtrlCore/Ctrl.cpp b/uppsrc/CtrlCore/Ctrl.cpp index d173e2629..9040dbc44 100644 --- a/uppsrc/CtrlCore/Ctrl.cpp +++ b/uppsrc/CtrlCore/Ctrl.cpp @@ -272,7 +272,7 @@ bool Ctrl::IsOpen() const { GuiLock __; const Ctrl *q = GetTopCtrl(); - return q->IsWndOpen() && q->isopen; + return q->isopen && q->IsWndOpen(); } void Ctrl::Show(bool ashow) { diff --git a/uppsrc/CtrlCore/CtrlKbd.cpp b/uppsrc/CtrlCore/CtrlKbd.cpp index 8d2375fee..5486a2423 100644 --- a/uppsrc/CtrlCore/CtrlKbd.cpp +++ b/uppsrc/CtrlCore/CtrlKbd.cpp @@ -2,7 +2,7 @@ namespace Upp { -#define LLOG(x) // DLOG(x) +#define LLOG(x) // DLOG(x) Ptr Ctrl::focusCtrl; Ptr Ctrl::focusCtrlWnd; @@ -228,7 +228,7 @@ bool Ctrl::SetFocus0(bool activate) { GuiLock __; USRLOG(" SETFOCUS " << Desc(this)); - LLOG("Ctrl::SetFocus " << Desc(this)); + LLOG("Ctrl::SetFocus " << Desc(this) << ", activate: " << activate); LLOG("focusCtrlWnd " << UPP::Name(focusCtrlWnd)); LLOG("Ctrl::SetFocus0 -> deferredSetFocus = NULL; was: " << UPP::Name(defferedSetFocus)); defferedSetFocus = NULL; diff --git a/uppsrc/CtrlCore/TopWindow.cpp b/uppsrc/CtrlCore/TopWindow.cpp index 329177229..959ce2aed 100644 --- a/uppsrc/CtrlCore/TopWindow.cpp +++ b/uppsrc/CtrlCore/TopWindow.cpp @@ -23,7 +23,9 @@ void TopWindow::ActiveFocus0(Ctrl& ctrl) { if(IsChild()) return; activefocus = &ctrl; - if(IsForeground()) ctrl.SetWantFocus(); + LLOG("ActiveFocus0"); + if(IsForeground()) + ctrl.SetWantFocus(); } void TopWindow::Activate() @@ -55,6 +57,7 @@ void TopWindow::Deactivate() void TopWindow::PlaceFocus() { + LLOG("PlaceFocus " << Upp::Name(this)); if(activefocus) activefocus->SetFocus(); else diff --git a/uppsrc/CtrlCore/cocotodo.txt b/uppsrc/CtrlCore/cocotodo.txt index 90990edfa..36695328e 100644 --- a/uppsrc/CtrlCore/cocotodo.txt +++ b/uppsrc/CtrlCore/cocotodo.txt @@ -1,9 +1,9 @@ sooner: -- fix modifier keys (read before each event) -- Ctrl key gets stuck +- modal disabled window can be closed + +- Uword cursor is blinking even in background -- initial focus in uword - icondes - rightclick on image in the list, then move mouse over color ramp - weird focus issue happens * Mac menu @@ -65,6 +65,13 @@ later: done: + +[uword] CGContextRestoreGState: invalid context + +- fix modifier keys (read before each event) +- Ctrl key gets stuck + +- initial focus in uword - after mouse up, cursor changes to arrow - IconDes could show hotspots always * cursor trouble osscilation diff --git a/uppsrc/CtrlLib/EditField.cpp b/uppsrc/CtrlLib/EditField.cpp index 0a1029847..fa3c55578 100644 --- a/uppsrc/CtrlLib/EditField.cpp +++ b/uppsrc/CtrlLib/EditField.cpp @@ -396,7 +396,7 @@ Rect EditField::GetCaretRect(int pos) const { return RectC(GetCaret(pos) - sc + 2 * !no_internal_margin - font.GetRightSpace('o') + font.GetLeftSpace('o'), GetTy(), - 1, min(GetSize().cy - 2 * GetTy(), font.GetCy())); + DPI(1), min(GetSize().cy - 2 * GetTy(), font.GetCy())); } void EditField::SyncCaret()