macOS - Window Top Most on Screen

Hey there dear community,
after a long time I’m back working with Xojo on different projects.
One is just a little tinker project - where I try to get a styled Window based on a property to always be top most (like the Window Behavior in Stickies.app) - you may see where this is going already. :wink:
But, I can’t wrap my head around getting the Window to be top most on my current screen, still be visible in Expose, and not be a global floating Window.
My intended behavior is to to have the Window above all other applications, hence top most, when toggled and act as a regular window when off. As I’m happy to use MBS Plugins I thought my current setup would be a good approach - but something is off. I can’t get my Window to be top most, can some one please assist with some neat tricks or tips?

(I searched the forum ahead of this post, and tried some posted function from the past, I even came back to macoslib, that for my current purpose I lag energy to refactor and make compatible with ARMx64 without Errors - haha)

my current setTopMost(enable as Boolean) Function:

#If TargetMacOS
  Var nsw As New NSWindowMBS(Self)
  If nsw Is Nil Then Return
  
  
  // CoreGraphics levels
  Declare Function CGWindowLevelForKey Lib "CoreGraphics" (key As Integer) As Integer
  Const kCGNormalWindowLevelKey   As Integer = 4
  Const kCGFloatingWindowLevelKey As Integer = 5
  
  // CollectionBehavior flags
  Const CB_None              As UInteger = 0
  Const CB_MoveToActiveSpace As UInteger = NSWindowMBS.NSWindowCollectionBehaviorMoveToActiveSpace
  Const CB_JoinAllSpaces     As UInteger = NSWindowMBS.NSWindowCollectionBehaviorCanJoinAllSpaces
  
  If enable Then
    
    // Keep NORMAL level so the window stays in Exposé and is Space-local
    nsw.Level = CGWindowLevelForKey(kCGNormalWindowLevelKey)
    // Ensure it's NOT on all spaces; allow move-to-active-space behavior
    nsw.CollectionBehavior = (nsw.CollectionBehavior And Not CB_JoinAllSpaces) Or CB_MoveToActiveSpace
    // Bring in front now (no “regardless” needed, but okay to use)
    nsw.orderFrontRegardless()
    
    nsw.HidesOnDeactivate = False
    
  Else
    // FULL reset to normal window behavior
    nsw.Level = CGWindowLevelForKey(kCGNormalWindowLevelKey)
    nsw.CollectionBehavior = CB_None
    nsw.HidesOnDeactivate = False
    nsw.OrderFront        // signature takes no parameter
  End If
  
#EndIf

For context, I’m also using a configureWindowChromeSetup Function in the Window.Open Event:

#If TargetMacOS
  Var w As Ptr = Self.Handle
  If w = Nil Then Return
  
  // ---- style mask (keep it titled; add full-size content view) ----
  Declare Function styleMask Lib "AppKit" Selector "styleMask" (win As Ptr) As UInteger
  Declare Sub setStyleMask Lib "AppKit" Selector "setStyleMask:" (win As Ptr, mask As UInteger)
  Const NSWindowStyleMaskTitled As UInteger = 1
  Const NSWindowStyleMaskFullSizeContentView As UInteger = &h00008000 // (1 << 15)
  
  // ---- titlebar appearance ----
  Declare Sub setTitleVisibility Lib "AppKit" Selector "setTitleVisibility:" (win As Ptr, v As Integer)
  Const NSWindowTitleVisibilityHidden As Integer = 1
  Declare Sub setTitlebarAppearsTransparent Lib "AppKit" Selector "setTitlebarAppearsTransparent:" (win As Ptr, flag As Boolean)
  Declare Sub setMovableByWindowBackground Lib "AppKit" Selector "setMovableByWindowBackground:" (win As Ptr, flag As Boolean)
  
  // ---- hide standard buttons (optional) ----
  Declare Function standardWindowButton Lib "AppKit" Selector "standardWindowButton:" (win As Ptr, which As Integer) As Ptr
  Declare Sub setHidden Lib "AppKit" Selector "setHidden:" (view As Ptr, flag As Boolean)
  Const NSWindowCloseButton = 0
  Const NSWindowMiniaturizeButton = 1
  Const NSWindowZoomButton = 2
  
  // apply
  setTitleVisibility(w, NSWindowTitleVisibilityHidden)
  setTitlebarAppearsTransparent(w, True)
  setMovableByWindowBackground(w, True)
  
  Var m As UInteger = styleMask(w)
  m = m Or NSWindowStyleMaskTitled Or NSWindowStyleMaskFullSizeContentView
  setStyleMask(w, m)
  
  Var b As Ptr
  b = standardWindowButton(w, NSWindowCloseButton)
  If b <> Nil Then setHidden(b, True)
  
  b = standardWindowButton(w, NSWindowMiniaturizeButton)
  If b <> Nil Then setHidden(b, True)
  
  b = standardWindowButton(w, NSWindowZoomButton)
  If b <> Nil Then setHidden(b, True)
#EndIf

Cheers
// patric

Hi patric,

i’m using this code, based on community-input. Works for macOS and Windows:

Sub AlwaysOnTop(extends w as DesktopWindow, assigns Value as Boolean)
  //# Sets the window’s window level to floating window level.
  
  #If TargetMacOS Then
    Const NSNormalWindowLevel = 0
    Const NSFloatingWindowLevel = 3
    Const NSModalPanelWindowLevel = 8
    Const NSDockWindowLevel = 20
    Const NSMainMenuWindowLevel = 24
    Const NSPopUpMenuWindowLevel = 101
    Const NSScreenSaverWindowLevel = 1001
    
    Declare Sub NSWindowSetLevel Lib "Cocoa" Selector "setLevel:" (WindowRef As Ptr, Level As Integer)
    If Value Then
      NSWindowSetLevel w.Handle, NSFloatingWindowLevel
    Else
      NSWindowSetLevel w.Handle, NSNormalWindowLevel
    End If
    
    
  #ElseIf TargetWindows
    // #Pragma Unused w
    // #Pragma Unused Value
    If value Then
      w.WinTopMostWindowMBS =True
    Else
      w.WinTopMostWindowMBS=False
    End
  #EndIf
  
End Sub

Hey @Thomas_Kaltschmidt ,

thank you for sharing your snippet, highly appreciated. The issue I face is, that the window, in TopMostMode vanishes when the user invokes the App Expose…

Ah, ok. I think this is the normal behaviour. You can check using the macOS Character Emoji-Picker.

And this is what I actually have a doubt in, because there seem to be behaviors one must be able to set, the Stickies.app is the perfect example of Windows that can stay top most and yet be part of the App Expose, do you know what I mean? :slight_smile:

Perhaps NSWindowMBS.collectionBehavior?

NSWindowCollectionBehaviorStationary says “The window is unaffected by Exposé; it stays visible and stationary” which sounds like what Stickies does.

Update: No, actually, I just looked at Stickies and they just behave like normal windows for me. It seems odd that setting the level is changing the collection behavior without you doing so?

@Patric_Lee_Atrott You want the window to have the floating window level and to be “managed” (participate in Mission Control).

#If TargetMacOS
  Var nsw As NSWindowMBS = Self.NSWindowMBS
  If nsw Is Nil Then Return
  If enable Then
    nsw.Level = NSWindowMBS.NSFloatingWindowLevel
    nsw.collectionBehavior = NSWindowMBS.NSWindowCollectionBehaviorManaged _ // window appears in Mission Control, like Stickies
    Or NSWindowMBS.NSWindowCollectionBehaviorIgnoresCycle _                // window excluded from Cmd-` cycling, like Stickies
    Or NSWindowMBS.NSWindowCollectionBehaviorMoveToActiveSpace
    nsw.orderFrontRegardless()
  Else
    // FULL reset to normal window behavior
    nsw.Level = NSWindowMBS.NSNormalWindowLevel
    nsw.CollectionBehavior = NSWindowMBS.NSWindowCollectionBehaviorDefault
    nsw.OrderFront()
  End If
  nsw.HidesOnDeactivate = False
#EndIf
2 Likes

Thanks @Travis_Hicks , this in deed did the job! Thank you for your explanation and assistance.
Also thanks to @Tim_Parnell for pointing into the direction.
:raising_hands: