DesktopListbox Accessing the Backend (XOJListboxController)

Hey everyone, I’ve been fighting with DesktopListboxes a bit over the weekend and wondered if anyone knows of a way to access a pointer/reference to the ListboxController.

It seems to have its own frame, which is resulting in some issues with how I want to implement my SplitView/StackView. Using an automask or constraints via Declares on the Listbox itself makes the listbox visually appear in the correct place after adding it into my view - however the controller remains in the original location. (So to click the cell you want you have to click where the listbox used to be…)

I’ve swizzled the setFrame method and got it all working nicely when the window is an implicit instance, but it gets complicated awful quickly when you start implementing multiple tabs/windows (as the method/delegate for it has to directly reference the Window.Listbox.Handle due to how shared methods can’t really access self.)

(Obviously I can just do the math and manually size it on window resize but I’d really prefer not to do that here)

Thanks!

What’s a ListboxController ?

It’s the backend part of the DesktopListbox that manages the users selection and (I assume) the Listbox’s data. Sorry it’s a bit of an awkward question there’s probably a better place for me to post it on the forum!

Humph. Never heard of it and there’s no mention on the DesktopListbox doc page.

I’ve seen reference to a XOJListboxView before, in other people’s Declare code, but not XOJListboxController. Don’t know if that makes a difference, but thought I’d mention it.

It’s stashed far far away from the documentation I’m sad to say… I’m deep in objc/macOS declare territory here…

Yeah from what I can see the XOJListboxController gets initiated with a frame when the XOJListboxView is created. There is a reference to it as subpane in the framework too. It may just be that its considered a private part of the framework and therefore inaccessible… I really don’t fancy writing a plugin or an NSTableView tho so thought I’d try my luck asking!

What are you trying to do?

For anyone who finds themselves stuck here from the future.

Declare Function objc_getClass Lib "Cocoa" (name As CString) As Ptr
dim cls as ptr = objc_getClass("XOJWindowController")

Declare Function sel_registerName Lib "Cocoa" (name As CString) As Ptr
Dim getPaneController As Ptr = sel_registerName("paneControllerForResponder:")
Declare Function class_getInstanceMethod Lib "Cocoa" (cls As Ptr, sel As Ptr) As Ptr
Dim method As Ptr = class_getInstanceMethod(cls, getPaneController)

declare function getDelegate lib "Cocoa" selector "delegate" (obj as ptr) as ptr
dim windowDelegate as ptr = getDelegate(Window1.Handle)

Declare Function objc_msgSend Lib "Cocoa" (receiver As Ptr, sel As Ptr, target as ptr) as ptr
dim controller as ptr = objc_msgSend(windowDelegate, getPaneController, Listbox1.Handle)