Scintilla macOS 10.14+ patch f. vert. scrollbar problem

Mac OSX specific forum
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Scintilla macOS 10.14+ patch f. vert. scrollbar problem

Post by Danilo »

Patch for bug report: ScintillaGadget macOS Version >= v10.14

Code: Select all

;---------------------------------------------------------
; Danilo Krahn, 2021/01/17, PB 5.72 (x64), macOS 11.1
;---------------------------------------------------------

EnableExplicit

;---------------------------------------------------------
; Required Structures & Types
;
Macro NSInteger : i : EndMacro

Structure NSOperatingSystemVersion
    majorVersion.NSInteger
    minorVersion.NSInteger
    patchVersion.NSInteger
EndStructure

Structure NSEdgeInsets
    top.d
    left.d
    bottom.d
    right.d
EndStructure
;
; End Required Structures & Types
;---------------------------------------------------------


;---------------------------------------------------------
; OS Version Info
;
Procedure.i isOperatingSystemAtLeastVersion(majorVersion, minorVersion, patchVersion)
    Protected returnValue
    Protected processInfo = CocoaMessage(0,0,"NSProcessInfo new")
    If processInfo
        Protected v.NSOperatingSystemVersion
        v\majorVersion = majorVersion
        v\minorVersion = minorVersion
        v\patchVersion = patchVersion
        returnValue = CocoaMessage(0,processInfo,"isOperatingSystemAtLeastVersion:@",@v)
        CocoaMessage(0,processInfo,"dealloc")
    EndIf
    ProcedureReturn returnValue
EndProcedure

Procedure.i GetOperatingSystemVersion(*v.NSOperatingSystemVersion)
    If Not *v : ProcedureReturn 0 : EndIf
    Protected processInfo = CocoaMessage(0,0,"NSProcessInfo new")
    If processInfo
        Protected v.NSOperatingSystemVersion
        CocoaMessage(@v,processInfo,"operatingSystemVersion")
        *v\majorVersion = v\majorVersion
        *v\minorVersion = v\minorVersion
        *v\patchVersion = v\patchVersion
        CocoaMessage(0,processInfo,"dealloc")
    Else
        ProcedureReturn 0
    EndIf
    ProcedureReturn 1
EndProcedure
;
; End OS Version Info
;---------------------------------------------------------


;---------------------------------------------------------
; Scintilla macOS patch for PureBasic
;
; original patch:
; - https://sourceforge.net/p/scintilla/code/ci/b428bfb5a7303838f7ac28c941c99e73140cb786/
;
Global NewMap __Scintilla_tile_procs.i()
Global __Scintilla_tile_callback

ProcedureC Scintilla_scrollView_contentView_tile(*self, selector)
    Protected proc = __Scintilla_tile_procs(Hex(*self))
    If Not proc
        ProcedureReturn
    EndIf
    CallCFunctionFast(proc,*self,selector)
   
    If isOperatingSystemAtLeastVersion(10,14,0)
        Protected verticalRulerView, frame.NSRect, thickness.d
        Protected contentView = CocoaMessage(0,*self,"contentView")
        If contentView
            CocoaMessage(@frame,contentView,"frame")
            verticalRulerView = CocoaMessage(0,*self,"verticalRulerView")
            CocoaMessage(@thickness,verticalRulerView,"requiredThickness")
            frame\origin\x = thickness
            frame\size\width - thickness
            CocoaMessage(0,contentView,"setFrame:@",@frame)
        EndIf
    EndIf
EndProcedure

Procedure ScintillaFix(ScintillaID)
    Protected scintilla, *scrollView, *scrollView_Ivar, contentView
    CocoaMessage(@scintilla, ScintillaID, "superclass")
    If scintilla
        *scrollView_Ivar = class_getInstanceVariable_(scintilla,"scrollView")
        If *scrollView_Ivar
            *scrollView = object_getIvar_(ScintillaID,*scrollView_Ivar)
            If *scrollView
                contentView = CocoaMessage(0,*scrollView,"contentView")
                If contentView
                    If isOperatingSystemAtLeastVersion(10,14,0)
                        CocoaMessage(0,contentView,"setAutomaticallyAdjustsContentInsets:",0)
                        Protected insets.NSEdgeInsets
                        CocoaMessage(0,contentView,"setContentInsets:@",@insets)
                        If Not FindMapElement(__Scintilla_tile_procs(),Hex(*scrollView))         ; already patched?
                            If Not __Scintilla_tile_callback                                     ; only 1st time we replace the "tile" method
                                __Scintilla_tile_callback = class_replaceMethod_(object_getClass_(*scrollView), sel_registerName_("tile"), @Scintilla_scrollView_contentView_tile(), "v@:")
                            EndIf
                            __Scintilla_tile_procs(Hex(*scrollView)) = __Scintilla_tile_callback ; add this *scrollview to the map
                        EndIf
                       
                        ;CocoaMessage(0,contentView,"setNeedsDisplay:",1)
                        ;CocoaMessage(0,*scrollView,"setNeedsDisplay:",1)
                    EndIf
                EndIf
            EndIf
        EndIf
    EndIf
EndProcedure
;
; End Scintilla macOS patch
;---------------------------------------------------------


;---------------------------------------------------------
; Example
;
ProcedureC ScintillaCallback(Gadget, *scinotify.SCNotification)
    ProcedureReturn 0
EndProcedure

Define v.NSOperatingSystemVersion
If GetOperatingSystemVersion(@v)
    Debug "macOS Version: " + v\majorVersion +
                        "." + v\minorVersion +
                        "." + v\patchVersion
EndIf

If OpenWindow(0, 0, 0, 800, 600, "ScintillaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
    If InitScintilla()
        ScintillaGadget(0, 10,  10, 780, 280, @ScintillaCallback())
        ScintillaGadget(1, 10, 300, 780, 290, @ScintillaCallback())
       
        ScintillaFix(GadgetID(0))
        ScintillaFix(GadgetID(1))
       
        Define g, i, line$, *utf8
        For g = 0 To 1
            For i = 1 To 200
                line$ = "Scintilla("+g+") Text on line "+RSet(Str(i),3)+"....................................yes!"+Chr(10)
                *utf8=UTF8(line$)
                ScintillaSendMessage(g, #SCI_APPENDTEXT, Len(line$), *utf8)
                FreeMemory(*utf8)
            Next
       
            ScintillaSendMessage(g, #SCI_SETMARGINWIDTHN, 0, 40+g*20)
            ScintillaSendMessage(g, #SCI_STYLESETBACK, #STYLE_LINENUMBER, RGB($80+g*$40,$80+g*$40,$80))
            ScintillaSendMessage(g, #SCI_SETMARGINWIDTHN, 1, 5)
        Next
     
        Repeat
            Select WaitWindowEvent()
                Case #PB_Event_SizeWindow
                    ResizeGadget(0,10, 10,WindowWidth(0)-20,WindowHeight(0)*0.5-20)
                    ResizeGadget(1,10,WindowHeight(0)*0.5,WindowWidth(0)-20,WindowHeight(0)*0.5-10)
                Case #PB_Event_CloseWindow
                    Break
            EndSelect
        ForEver
    EndIf
EndIf
;
; End Example
;---------------------------------------------------------
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Scintilla macOS 10.14+ patch f. vert. scrollbar problem

Post by mk-soft »

Super, :D
and great respect from me for your knowledge of Cocoa.

I didn't get it right, although I was already a little on the right track.
I didn't know how to get to the right scrollView and the initialization of the scrollView.
Also the redirection of the method "tile" is ingenious and to call the original method in this and to carry out the necessary adjustments.

It is quite time-consuming to change the initialisation of gadgets afterwards.

Thank you very much.

I hope that Fred will finally put in the fix.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Scintilla macOS 10.14+ patch f. vert. scrollbar problem

Post by Danilo »

mk-soft wrote:I didn't know how to get to the right scrollView and the initialization of the scrollView.
Looking at the Scintilla sources for v3.7.x did help to find the right variables and structure (ScintillaView.h / ScintillaView.mm).
mk-soft wrote:Also the redirection of the method "tile" is ingenious and to call the original method in this and to carry out the necessary adjustments.
Yeah, it's basically what "[super tile]" in the patch does, call the old behaviour.

I couldn't figure out yet how to use "super" in PB. There is a function objc_msgSendSuper(receiver, selector, ...),
so we probably would need an additional CocoaMessageSuper() to call the super class, if we create a new class.

In this case we replaced the method directly, so we need to call the old method directly and not "super".
mk-soft wrote:It is quite time-consuming to change the initialisation of gadgets afterwards.
You can change the 2 properties at any time, not required to do it on initialization:

Code: Select all

// Objective-C
scrollView.contentView.automaticallyAdjustsContentInsets = NO;
scrollView.contentView.contentInsets = NSEdgeInsetsMake(0., 0., 0., 0.);
mk-soft wrote:Thank you very much.

I hope that Fred will finally put in the fix.
Many people are waiting for a fix and can't update their applications. :(

After updating to 64-bit only macOS 11.1 few days ago I asked
Ryan for a new version of his nice Mollusk IDE, so he could
update it for the open-source wonkey project.
He told me about the Scintilla problem in PB then... :|

Greetings...
Post Reply