toggleTabBar - next in line for working macOS Tabs

I’ve solved most of the “problems” of using macOS Tabs in XOJO, they work pretty well actually. I’m trying to now turn on and off programmatically, the menu item “Show Tab Bar” that macOS inserts into the view menu. I think the following API holds the answer yet at a loss how to adapt the below for XOJO.

@IBAction func toggleTabBar(_ sender: Any?)

Anyone made this function work yet in XOJO?

All leads appreciated!

You mean this https://developer.apple.com/documentation/appkit/nswindow/1644517-toggletabbar?language=objc

I would think that what you want is to tell the OS whether or not your app supports tabs as opposed to showing or hiding the tabs themselves:

https://developer.apple.com/documentation/appkit/nswindow/1646657-allowsautomaticwindowtabbing?language=objc

‘The’ only issue I was aware about what that Xojo doesnt know that the current window has been turned into a tab. So no resizing occurs, and anything at the bottom of the dialog is lost.
What problems have you found and solved.?
How?

Tabbing is enabled by default, if you don’t want it, you have to disable it. Also by default it’s a half baked solution, which either requires more work to make it work correctly, or a single line of code to disable it

So which option did almost all 3rd Party Developers take?

I like and want to use tabs and created a superclass that works very well. Tab bar shows/hides while maintaining proper control alignment, I can add or remove via the tab bar as well as the “Show all Tabs” (tab overview) menu option functions as well. All good.

I used setAllowsAutomaticWindowTabbing to enable the system. Taking inspiration from others in the forum I used addTabbedWindow to add windows to the tab group. Poof, tabs appear but with the “sizing problem” you mention, Jeff.

Using AppKit tabGroup, isTabBarVisible and isOverviewVisible I worked around the “missing resize” event by monitoring isTabBarVisible via the Paint event. Then it was straight forward to add “TabBarHidden” and “TabBarShown” events to the superclass to know when a window needs to resize.

In the superclass events I add or remove the height of tab bar as required in response to tab bar show/hide. No need to manually reposition controls in my case since they are locked, for example, to the bottom of the window and a tickle of the window forces a resize so locking does its job. Anything unique/one-off I handle in the subclass window via TabBarShown/Hidden events.

This led to the current “problem” which is: if no tab bar is showing AND one has not made the window a tab yet AND you add a new tab via the tab overview (“Show all Tabs”) the tab bar operates differently – missing the “+” on the right hand side. An edge case for sure, and may be a wild goose chase as I could of course just make all windows “tabs” upon open – even if there is only one.

I imagine this is because we’re unable to detect the creation of the first tab window via the overview.

Finally we arrive at my question – was trying to get insight into that mechanism and why tabs as described (tab bar not showing, window not added to tab group yet, tab added via overview) functions incorrectly. May well be diminishing returns at this point too.

Has anyone else gotten a working tab superclass going? Mine works and I’m sure there are nuances and improvements that could well be made!

Thanks Greg, I’ve got the tabs all working well – XOJO control locking works so no need for manual control adjustments and solves the so-called “missing resize problem”. The question I asked was unclear and didn’t describe the problem, which is that adding the 1st tabbed window via the tab overview creates a tab bar without the “+” on the right hand side. I was trying to get underneath that. Appreciate your help!

1 Like

Yes Sam, that’s it. Appreciate your tab inspirations too!

1 Like

Well, I fudged it.

In my ‘create a new document’ generator, I use this pseudocode.
Essentially, when I open a new window, I just give the tyres a kick and force a resize

if <my customer wants to ALLOW tabs in my app> then  // this is my app's preferences

numberofopendocs as integer = MygetopenDocWindows() //just count them
If  numberofopendocs =1 then
//nothing to do
else
dim olh as integer
for x as integer = 0 to numberofopendocs -1   //this assumes all windows are documents
     
   if  window(x) isa documentWindow then
 olh = window(x).height
window(x).height = window(x).height -10
window(x).height = olh
 end if 
next

end if


end if
1 Like

Ah okay… This is part of the half baked solution I was referring to. You need to handle an event in the window delegate, not the window. The code for this, including the Window Delegate is available in a XDC I wrote many years ago, or the latest version of the code is included in the App Kit, which is part of the Omegabundle.

Public Sub NSWindow_newWindowForTab(NSWindowInstance as integer)
  // Part of the NSWindowDelegate interface.
  
  #if targetMacOS then
    Dim n as textEditor = app.newDocumentWindow
    NSWindowAddTabbedWindowOrdered( NSWindowInstance, n.handle, NSWindowOrderingMode.above )
    n.showWhenReady
  #endif
End Sub
1 Like

Putting the following code into a PushButton works.

declare sub NSWindowToggleTabBar lib "AppKit" selector "toggleTabBar:" ( NSWindowInstance as integer, sender as integer )
NSWindowToggleTabBar( self.handle, me.handle )

Brilliant! This is exactly what I needed. Now, my tabs are complete. (For now :slight_smile:)

1 Like