Sierra: show tab bar

Now that I’m running in Sierra - my apps are automatically having a “Show Tab Bar” item added to the top of the View menu.

Any idea how I use it or lose it?

You can opt out on a window by window basis OR opt the entire app out

BUT you need to check if you are on Sierra first (which is not included here) as if you call this on a non-Sierra system you’ll have issues

Public Enum AutoTabbingMode
WindowTabbingModeAutomatic = 0
WindowTabbingModePreferred = 1
WindowTabbingModeDisallowed = 2
End Enum

Public Sub DisableSierraAutoTabsForWindow(extends w as Window, assigns tabMode as AutoTabbingMode)
  #if TargetMacOS
    // enum is from NSWindow.h
    // typedef NS_ENUM(NSInteger, NSWindowTabbingMode) {
    //     NSWindowTabbingModeAutomatic, // The system automatically prefers to tab this window when appropriate
    //     NSWindowTabbingModePreferred, // The window explicitly should prefer to tab when shown
    //     NSWindowTabbingModeDisallowed // The window explicitly should not prefer to tab when shown
    // }  NS_ENUM_AVAILABLE_MAC(10_12);
    Declare Sub setTabbingMode Lib "Cocoa" Selector "setTabbingMode:" (obj as Integer, m as Integer)
    setTabbingMode (w.handle, Integer(tabMode))
End Sub

Public Sub AppAutoTabbing(optIn as boolean)
  #if TargetMacOS
    declare function objc_getClass lib "libobjc.dylib" ( name as CString ) as ptr
    dim nsWindowClass as ptr = objc_getClass( "NSWindow" ) 
    declare sub AllowTabGrouping lib "AppKit"selector "setAllowsAutomaticWindowTabbing:" ( classPtr as Ptr , enableDisable as Boolean ) 
    AllowTabGrouping( nsWindowClass, optIn )
End Sub

Whats not present right now is knowing that the CONTENT areas of a window has grown or shrunk
Tabs steal space from the content area so the window remains the same size but the overall content area shrinks so you cant hook into the resizing or resized events to know when this changes

Or, if you’re using MBS plugins, disable it in the whole app with this in App.Open:

#if targetmacOS then if SystemInformationMBS.isSierra(true) then NSWindowMBS.allowsAutomaticWindowTabbing = false end if #endif

@Sam Rowlands on determining which macOS without plugins:

Thanks All - that should fix it for the moment.

I posted the per window & entire app versions :stuck_out_tongue:

If you decide to fully support Sierra’s tabs; you can find the code in the latest xDevMag.

[quote=296303:@Norman Palardy]Whats not present right now is knowing that the CONTENT areas of a window has grown or shrunk
Tabs steal space from the content area so the window remains the same size but the overall content area shrinks so you cant hook into the resizing or resized events to know when this changes[/quote]

That is where RubberViews comes handy.

Thank you for posting the declares, Norman :slight_smile:

Sam - issue 14.6 bounced into my email within 5 mins of your post - but nothing there about Sierra’s tabs. :frowning:

Found it, issue 14.5. Great.

My bad, sorry. Glad that you found it however.

Something interesting…
I took a backup and installed Sierra. (Gulp… still waiting to find the problems)

But my apps DONT show tabs for new document windows.
Is there some user setting that turns these on?
Is it anything to do with not allowing full screen mode?

There’s a preferences setting
System Preferences > Dock > Prefer tabs when opening documents
It defaults to “when in full screen only”
Switch the setting to “Always” and you’ll see it

We can check the size in the activate event.

dim w as NSWindowMBS = me.NSWindowMBS dim fr as NSRectMBS = w.frame dim cr as NSRectMBS = w.contentRectForFrameRect(fr)

The contentrect becomes smaller by the size of the tabs.
Unfortunately, controls that are aligned bottom don’t move when this changes, which means handling the bottom alignment in code.
But it should be possible…

… I read in another post that Xojo doesnt ‘get’ the messages from this tabbing which it normally reacts to to send on a resized event.

The window does get an activated event.
Is there a way we can

  • send a message ,
  • using xojo code/declares
  • during the activated event,
  • to the activated window ,
  • which looks like a system ‘resized’ message of the kind that Xojo does react to?

(I appreciate Im thinking about this in Win32 ‘SendMessage’ terms because Im not familiar with Mac AppKit etc under the hood)

Indeed there is an issue with the way Xojo reports self.height, which is not right when tabs are used. And the resized event does not fire either.

I got a way to get the actual height : the Paint event g.height reports the accurate height. And the nice thing is that there is no need for declares, plugins, or conditional compilation.

45751 - Self.Height reports inaccurate height in Windows under macOS tabbed navigation
Status: Needs Review Rank: Not Ranked Product: Xojo Category: N/A

Michel Bujardet Today at 10:52 AM
OS: OS X 10.12.2

Xojo: Xojo 2016r3

Steps: - Switch tabbed navigation to “always” in macOS Sierra Dock preferences

  • Open two windows in an app
  • Read self.height in the Activate event : it remains for instance 400 instead of 376.

Self.height should report the accurate effective height of the window when tabs become active.

It would seem logical that the Resized event fires.

Use the Paint event g.height property to get the actual height.


Thats neater than MBS or declares.
Unfortunately we still then have the issue of controls close to the bottom of the window that are bottom aligned (eg a status bar)
The window changes size, and Xojo doesnt move the controls.
We can tell that the window size doesnt match the graphics size any longer.

How do we ‘kick’ Xojo to move the aligned controls properly?

Not even present RubberViews could help, since the reported height is wrong.

The solution I find now is this in the Paint event :

if g.height < originalHeight then self.height = originalHeight + (originalHeight - g.height) return end if

originalHeight is a window property set to self.Height in Open

That increases the height of the window as necessary to keep it as high as when no tab is present.

Ideally, I would like to have Xojo do it automatically.

Thats a good start.
It will be a problem in that form if the user manually reduces the height of the window, will it not?

Indeed that would be a problem. There are other issues around user employing tabs. If say, you have a window 600 x 400 and the second window is supposed to be much smaller, it will end up as big as the first window. Likewise if the second window is much bigger, it will shrink to the size of the first window.

I tend to believe Norman’s declare is the best solution, since it will simply keep the present situation. Otherwise, the app must be conceived to deal with the tabbed navigation.

As someone rightly said, Apple is reinventing MDI windows. What a mess.