Skip to content

Commit

Permalink
Disable arranging or displaying items when menu bar is automatically …
Browse files Browse the repository at this point in the history
…hidden

See #201
  • Loading branch information
jordanbaird committed Jul 3, 2024
1 parent 179bc82 commit 56122f2
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 30 deletions.
31 changes: 30 additions & 1 deletion Ice/IceBar/IceBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,31 @@ class IceBarPanel: NSPanel {
}
.store(in: &c)

if
let appState,
let section = appState.menuBarManager.section(withName: .hidden),
let window = section.controlItem.window
{
window.publisher(for: \.frame)
.debounce(for: 0.1, scheduler: DispatchQueue.main)
.sink { [weak self, weak window] _ in
guard
let self,
// only continue if the menu bar is automatically hidden, as Ice
// can't currently display its menu bar items
appState.menuBarManager.isMenuBarHiddenBySystemUserDefaults,
let info = window.flatMap({ WindowInfo(windowID: CGWindowID($0.windowNumber)) }),
// window being offscreen means the menu bar is currently hidden;
// close the bar, as things will start to look weird if we don't
!info.isOnScreen
else {
return
}
close()
}
.store(in: &c)
}

// update the panel's origin whenever its size changes
publisher(for: \.frame)
.map(\.size)
Expand Down Expand Up @@ -275,8 +300,12 @@ private struct IceBarContentView: View {

@ViewBuilder
private var content: some View {
if imageCache.cacheFailed(for: section) {
if menuBarManager.isMenuBarHiddenBySystemUserDefaults {
Text("Ice cannot display the items of automatically hidden menu bars.")
.padding(.horizontal, 5)
} else if imageCache.cacheFailed(for: section) {
Text("Unable to display menu bar items")
.padding(.horizontal, 5)
} else {
HStack(spacing: 0) {
ForEach(items, id: \.windowID) { item in
Expand Down
17 changes: 17 additions & 0 deletions Ice/MenuBar/MenuBarManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ final class MenuBarManager: ObservableObject {
/// location of the mouse.
@Published private(set) var isMenuBarHiddenBySystem = false

/// A Boolean value that indicates whether the menu bar is hidden by the system
/// according to a value stored in UserDefaults.
@Published private(set) var isMenuBarHiddenBySystemUserDefaults = false

private(set) weak var appState: AppState?

private(set) var sections = [MenuBarSection]()
Expand Down Expand Up @@ -99,6 +103,19 @@ final class MenuBarManager: ObservableObject {
}
.store(in: &c)

Timer.publish(every: 1, on: .main, in: .default)
.autoconnect()
.sink { [weak self] _ in
guard
let self,
let isMenuBarHidden = Defaults.globalDomain["_HIHideMenuBar"] as? Bool
else {
return
}
isMenuBarHiddenBySystemUserDefaults = isMenuBarHidden
}
.store(in: &c)

// handle focusedApp rehide strategy
NSWorkspace.shared.publisher(for: \.frontmostApplication)
.sink { [weak self] _ in
Expand Down
1 change: 1 addition & 0 deletions Ice/MenuBarAppearance/MenuBarAppearanceEditorPanel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ private class MenuBarAppearanceEditorPopover: NSPopover {
self?.performClose(self)
})
)
.environmentObject(appState)
.environmentObject(appState.menuBarManager.appearanceManager)
}
}
Expand Down
15 changes: 0 additions & 15 deletions Ice/MenuBarAppearance/MenuBarAppearanceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import OSLog
final class MenuBarAppearanceManager: ObservableObject {
@Published var configuration: MenuBarAppearanceConfiguration = .defaultConfiguration

@Published private(set) var canChangeAppearance = true

private var cancellables = Set<AnyCancellable>()

private let encoder = JSONEncoder()
Expand Down Expand Up @@ -68,19 +66,6 @@ final class MenuBarAppearanceManager: ObservableObject {
}
.store(in: &c)

Timer.publish(every: 1, on: .main, in: .default)
.autoconnect()
.sink { [weak self] _ in
guard
let self,
let isMenuBarHidden = Defaults.globalDomain["_HIHideMenuBar"] as? Bool
else {
return
}
canChangeAppearance = !isMenuBarHidden
}
.store(in: &c)

$configuration
.encode(encoder: encoder)
.sink { completion in
Expand Down
4 changes: 2 additions & 2 deletions Ice/MenuBarAppearance/MenuBarOverlayPanel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ class MenuBarOverlayPanel: NSPanel {
Logger.overlayPanel.notice("No app state. \(actionMessage)")
return nil
}
guard appState.menuBarManager.appearanceManager.canChangeAppearance else {
Logger.overlayPanel.notice("Appearance manager cannot change appearance. \(actionMessage)")
guard !appState.menuBarManager.isMenuBarHiddenBySystemUserDefaults else {
Logger.overlayPanel.notice("Menu bar is hidden by system according to UserDefaults. \(actionMessage)")
return nil
}
guard !appState.isActiveSpaceFullscreen else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,21 @@ struct MenuBarAppearanceEditor: View {
case popover(closePopover: () -> Void)
}

@EnvironmentObject var appState: AppState
@EnvironmentObject var appearanceManager: MenuBarAppearanceManager

let location: Location

private var footerPadding: CGFloat? {
if !appState.menuBarManager.isMenuBarHiddenBySystemUserDefaults {
return nil
}
if case .popover = location {
return nil
}
return 0
}

var body: some View {
VStack(alignment: .leading, spacing: 0) {
stackHeader
Expand All @@ -35,18 +46,18 @@ struct MenuBarAppearanceEditor: View {

@ViewBuilder
private var stackBody: some View {
if appearanceManager.canChangeAppearance {
mainForm
} else {
if appState.menuBarManager.isMenuBarHiddenBySystemUserDefaults {
cannotEdit
} else {
mainForm
}
}

@ViewBuilder
private var stackFooter: some View {
HStack {
if
appearanceManager.canChangeAppearance,
!appState.menuBarManager.isMenuBarHiddenBySystemUserDefaults,
appearanceManager.configuration != .defaultConfiguration
{
Button("Reset") {
Expand All @@ -58,7 +69,7 @@ struct MenuBarAppearanceEditor: View {
Button("Done", action: closePopover)
}
}
.padding()
.padding(.all, footerPadding)
.controlSize(.large)
}

Expand Down
26 changes: 19 additions & 7 deletions Ice/Settings/SettingsPanes/MenuBarItemsSettingsPane.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ struct MenuBarItemsSettingsPane: View {
@EnvironmentObject var appState: AppState

var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
headerText
layoutBars
Spacer()
if appState.menuBarManager.isMenuBarHiddenBySystemUserDefaults {
cannotArrange
} else {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
headerText
layoutBars
Spacer()
}
.padding()
}
.padding()
.scrollBounceBehavior(.basedOnSize)
}
.scrollBounceBehavior(.basedOnSize)
}

@ViewBuilder
Expand Down Expand Up @@ -45,6 +49,14 @@ struct MenuBarItemsSettingsPane: View {
annotation: "Drag menu bar items to this section if you want them to always be hidden."
)
}
.padding()
}

@ViewBuilder
private var cannotArrange: some View {
Text("Ice cannot arrange the items of automatically hidden menu bars.")
.font(.title3)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
}

@ViewBuilder
Expand Down

0 comments on commit 56122f2

Please sign in to comment.