mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-05-05 15:33:00 +00:00
macos: add float on top feature for terminal windows (#7237)
Closes #5188 **See:** - https://github.com/ghostty-org/ghostty/discussions/5188#discussioncomment-12607781 - https://github.com/ghostty-org/ghostty/discussions/5188#discussioncomment-12984898
This commit is contained in:
commit
a6fd499019
@ -52,6 +52,8 @@ class AppDelegate: NSObject,
|
||||
@IBOutlet private var menuSelectSplitLeft: NSMenuItem?
|
||||
@IBOutlet private var menuSelectSplitRight: NSMenuItem?
|
||||
@IBOutlet private var menuReturnToDefaultSize: NSMenuItem?
|
||||
@IBOutlet private var menuFloatOnTop: NSMenuItem?
|
||||
@IBOutlet private var menuUseAsDefault: NSMenuItem?
|
||||
|
||||
@IBOutlet private var menuIncreaseFontSize: NSMenuItem?
|
||||
@IBOutlet private var menuDecreaseFontSize: NSMenuItem?
|
||||
@ -175,6 +177,12 @@ class AppDelegate: NSObject,
|
||||
handler: localEventHandler)
|
||||
|
||||
// Notifications
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(windowDidBecomeKey),
|
||||
name: NSWindow.didBecomeKeyNotification,
|
||||
object: nil
|
||||
)
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(quickTerminalDidChangeVisibility),
|
||||
@ -497,6 +505,16 @@ class AppDelegate: NSObject,
|
||||
return event
|
||||
}
|
||||
|
||||
@objc private func windowDidBecomeKey(_ notification: Notification) {
|
||||
guard let terminal = notification.object as? TerminalWindow else {
|
||||
// If some other window became key we always turn this off
|
||||
self.menuFloatOnTop?.state = .off
|
||||
return
|
||||
}
|
||||
|
||||
self.menuFloatOnTop?.state = terminal.level == .floating ? .on : .off
|
||||
}
|
||||
|
||||
@objc private func quickTerminalDidChangeVisibility(_ notification: Notification) {
|
||||
guard let quickController = notification.object as? QuickTerminalController else { return }
|
||||
self.menuQuickTerminal?.state = if (quickController.visible) { .on } else { .off }
|
||||
@ -844,6 +862,22 @@ class AppDelegate: NSObject,
|
||||
hiddenState = nil
|
||||
}
|
||||
|
||||
@IBAction func floatOnTop(_ menuItem: NSMenuItem) {
|
||||
menuItem.state = menuItem.state == .on ? .off : .on
|
||||
guard let window = NSApp.keyWindow else { return }
|
||||
window.level = menuItem.state == .on ? .floating : .normal
|
||||
}
|
||||
|
||||
@IBAction func useAsDefault(_ sender: NSMenuItem) {
|
||||
let ud = UserDefaults.standard
|
||||
let key = TerminalWindow.defaultLevelKey
|
||||
if (menuFloatOnTop?.state == .on) {
|
||||
ud.set(NSWindow.Level.floating, forKey: key)
|
||||
} else {
|
||||
ud.removeObject(forKey: key)
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func bringAllToFront(_ sender: Any) {
|
||||
if !NSApp.isActive {
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
@ -899,3 +933,20 @@ class AppDelegate: NSObject,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: NSMenuItemValidation
|
||||
|
||||
extension AppDelegate: NSMenuItemValidation {
|
||||
func validateMenuItem(_ item: NSMenuItem) -> Bool {
|
||||
switch item.action {
|
||||
case #selector(floatOnTop(_:)),
|
||||
#selector(useAsDefault(_:)):
|
||||
// Float on top items only active if the key window is a primary
|
||||
// terminal window (not quick terminal).
|
||||
return NSApp.keyWindow is TerminalWindow
|
||||
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
<outlet property="menuCopy" destination="Jqf-pv-Zcu" id="bKd-1C-oy9"/>
|
||||
<outlet property="menuDecreaseFontSize" destination="kzb-SZ-dOA" id="Y1B-Vh-6Z2"/>
|
||||
<outlet property="menuEqualizeSplits" destination="3gH-VD-vL9" id="SiZ-ce-FOF"/>
|
||||
<outlet property="menuFloatOnTop" destination="uRj-7z-1Nh" id="94n-o9-Jol"/>
|
||||
<outlet property="menuIncreaseFontSize" destination="CIH-ey-Z6x" id="hkc-9C-80E"/>
|
||||
<outlet property="menuMoveSplitDividerDown" destination="Zj7-2W-fdF" id="997-LL-nlN"/>
|
||||
<outlet property="menuMoveSplitDividerLeft" destination="wSR-ny-j1a" id="HCZ-CI-2ob"/>
|
||||
@ -56,6 +57,7 @@
|
||||
<outlet property="menuTerminalInspector" destination="QwP-M5-fvh" id="wJi-Dh-S9f"/>
|
||||
<outlet property="menuToggleFullScreen" destination="8kY-Pi-KaY" id="yQg-6V-OO6"/>
|
||||
<outlet property="menuToggleVisibility" destination="DOX-wA-ilh" id="iBj-Bc-2bq"/>
|
||||
<outlet property="menuUseAsDefault" destination="TrB-O8-g8H" id="af4-Jh-2HU"/>
|
||||
<outlet property="menuZoomSplit" destination="oPd-mn-IEH" id="wTu-jK-egI"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
@ -402,6 +404,19 @@
|
||||
<action selector="returnToDefaultSize:" target="-1" id="Bpt-GO-UU1"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Cm3-gn-vtj"/>
|
||||
<menuItem title="Float on Top" id="uRj-7z-1Nh">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="floatOnTop:" target="bbz-4X-AYv" id="N58-PO-7pj"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use as Default" id="TrB-O8-g8H">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAsDefault:" target="bbz-4X-AYv" id="RHA-Nl-L2U"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="CpM-rI-Sc1"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
|
@ -1,6 +1,9 @@
|
||||
import Cocoa
|
||||
|
||||
class TerminalWindow: NSWindow {
|
||||
/// This is the key in UserDefaults to use for the default `level` value.
|
||||
static let defaultLevelKey: String = "TerminalDefaultLevel"
|
||||
|
||||
@objc dynamic var keyEquivalent: String = ""
|
||||
|
||||
/// This is used to determine if certain elements should be drawn light or dark and should
|
||||
@ -63,6 +66,8 @@ class TerminalWindow: NSWindow {
|
||||
if titlebarTabs {
|
||||
generateToolbar()
|
||||
}
|
||||
|
||||
level = UserDefaults.standard.value(forKey: Self.defaultLevelKey) as? NSWindow.Level ?? .normal
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
Loading…
x
Reference in New Issue
Block a user