Re: [Lazarus] Modal Window Crashes on Mac OS X 10.15 Beta (Catalina)

2019-06-12 Thread Dmitry Boyarintsev via lazarus
On Wed, Jun 12, 2019 at 11:48 AM Zoë Peterson via lazarus <
lazarus@lists.lazarus-ide.org> wrote:

> "Swizzling" is the name for replacing the Objective C method pointers
> using method_exchangeImplementations.  It's not the same as overriding it.
>

Quite an interesting technique. I'm quite confident it's being heavily used
for Javascript.
(I guess it's somewhat natural for reflective languages to use it)

Though I'd consider going that low level as a last resort, rather than a
permanent solution.

thanks,
Dmitry
-- 
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] Modal Window Crashes on Mac OS X 10.15 Beta (Catalina)

2019-06-12 Thread Zoë Peterson via lazarus
There is an alternate way to swizzle documented here, which the author 
claims has less side effects.  I assume it would be possible to do this 
variant with Objective Pascal, but for a proof of concept it shouldn't 
be necessary:


https://blog.newrelic.com/engineering/right-way-to-swizzle/
--
Zoë Peterson
Scooter Software

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] Modal Window Crashes on Mac OS X 10.15 Beta (Catalina)

2019-06-12 Thread Zoë Peterson via lazarus

On 6/11/2019 11:56 PM, Dmitry Boyarintsev via lazarus wrote:

If it's a problem to check isRunning every time through
nextEventMatchingMask, and alternative with the same behavior would be
to swizzle in the runloop variant before calling inherited run and
switching it back once we get into it.

Switching back? how is it possible?


"Swizzling" is the name for replacing the Objective C method pointers 
using method_exchangeImplementations.  It's not the same as overriding it.


There's a writeup of it here:

https://trinhngocthuyen.github.io/tech/method-swizzling-what-why-and-how/

So, rather than overriding nextEventMatchingMask directly, ours is 
called something like runLoop_nextEventMatchingMask. 
TCocoaWidgetSet.AppRun swaps the function pointers, soour version is 
only called after we get to that point, and when we get into that 
function, we swap them back and call the original implementation like 
normal.  Our version only gets called once.



We cannot be sure at what particular event, the hijacking would occur.
Today, there was a bug report, about crash in the hijacking approach
https://forum.lazarus.freepascal.org/index.php/topic,44930.msg323420.html#msg323420 

The application written caused nextEventMatchMask to be called even 
prior to Application.Init.


The above approach takes care of that, since our version is never used 
until we actually swap the method pointers.  It removes the need to 
maintain an "isRun" variable too.


--
Zoë Peterson
Scooter Software


--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] Modal Window Crashes on Mac OS X 10.15 Beta (Catalina)

2019-06-12 Thread Dmitry Boyarintsev via lazarus
On Wed, Jun 12, 2019 at 5:17 AM Marc Weustink via lazarus <
lazarus@lists.lazarus-ide.org> wrote:

> BTW, did we report this issue (of the running variable not set) to
> Apple? Or is the below piece of code the way we should set it ourselves ?


I didn't bug report the issue to Apple.
The code provide can be called by LCL

thanks,
Dmitry
-- 
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] Modal Window Crashes on Mac OS X 10.15 Beta (Catalina)

2019-06-12 Thread Marc Weustink via lazarus

Dmitry Boyarintsev via lazarus wrote:
On Tue, Jun 11, 2019 at 10:06 AM David Jenkins via lazarus 
mailto:lazarus@lists.lazarus-ide.org>> 
wrote:


I looked at the assembly for NSApplication.run, there are a lot of
things being called and set before the call to
nextEventMatching...   The .isRunning variable being one of them -
which is read only and can't be set.  It can be overridden (and is
one of the suggested overrides) but unfortunately there are times,
in other parts of the code, that they look directly at the ._running
variable where the value of .isRunning is stored instead of calling
.isRunning (look at NSApplication._setMainWindow).  Which sets up a
mismatch between what an overridden .isRunning method would return
and what ._running is set to.


Let's back-up a little bit.

Can we actually try to set the value for the instance variable?
1) it's absolutely legal in Objective-C terms 
(object_getInstanceVariable, object_setInstanceVariable).
2) its' absolutely legal in KVC term. (I can presume that KVC is pretty 
much based on top of objc-run time. And this is how the entire 
Swift<->ObjC binding works)


BTW, did we report this issue (of the running variable not set) to 
Apple? Or is the below piece of code the way we should set it ourselves ?



Can anyone try and modify TCocoaApplication.run to look like this. (If 
you're using trunk, you'll need to have {$define COCOALOOPOVERRIDE} 
defines in cocoadefines.inc}


procedure TCocoaApplication.run;
begin
   
self.setValue_forKey(NSNumber.numberWithBool(true),NSSTR('_running')); 
// setting instance variable through KVC

   isrun:=true;
   aloop();
end;



Marc


--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus