Skip to content

Commit fb2cb72

Browse files
authored
Merge pull request #62 from Gabko14/fix/window-stays-open-when-pinned
fix: keep window open when pinned
2 parents d2fefbe + 1ee57f8 commit fb2cb72

17 files changed

Lines changed: 1132 additions & 22 deletions

Ghostly.xcodeproj/project.pbxproj

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@
270270
mainGroup = C836C54C25A0171500BEB83F;
271271
packageReferences = (
272272
KBSH000525E0000000000005 /* XCRemoteSwiftPackageReference "KeyboardShortcuts" */,
273-
MBEA000225E0000000000002 /* XCRemoteSwiftPackageReference "MenuBarExtraAccess" */,
273+
MBEA000225E0000000000002 /* XCLocalSwiftPackageReference "LocalPackages/MenuBarExtraAccess" */,
274274
);
275275
productRefGroup = C836C55625A0171500BEB83F /* Products */;
276276
projectDirPath = "";
@@ -609,16 +609,15 @@
609609
minimumVersion = 2.0.0;
610610
};
611611
};
612-
MBEA000225E0000000000002 /* XCRemoteSwiftPackageReference "MenuBarExtraAccess" */ = {
613-
isa = XCRemoteSwiftPackageReference;
614-
repositoryURL = "https://github.com/orchetect/MenuBarExtraAccess";
615-
requirement = {
616-
kind = upToNextMajorVersion;
617-
minimumVersion = 1.0.0;
618-
};
619-
};
620612
/* End XCRemoteSwiftPackageReference section */
621613

614+
/* Begin XCLocalSwiftPackageReference section */
615+
MBEA000225E0000000000002 /* XCLocalSwiftPackageReference "LocalPackages/MenuBarExtraAccess" */ = {
616+
isa = XCLocalSwiftPackageReference;
617+
relativePath = LocalPackages/MenuBarExtraAccess;
618+
};
619+
/* End XCLocalSwiftPackageReference section */
620+
622621
/* Begin XCSwiftPackageProductDependency section */
623622
KBSH000025E0000000000000 /* KeyboardShortcuts */ = {
624623
isa = XCSwiftPackageProductDependency;
@@ -632,7 +631,7 @@
632631
};
633632
MBEA000025E0000000000000 /* MenuBarExtraAccess */ = {
634633
isa = XCSwiftPackageProductDependency;
635-
package = MBEA000225E0000000000002 /* XCRemoteSwiftPackageReference "MenuBarExtraAccess" */;
634+
package = MBEA000225E0000000000002 /* XCLocalSwiftPackageReference "LocalPackages/MenuBarExtraAccess" */;
636635
productName = MenuBarExtraAccess;
637636
};
638637
/* End XCSwiftPackageProductDependency section */

Ghostly.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 0 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Ghostly/AppState.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ final class AppState {
1616
updateTabShortcuts(enabled: isMenuPresented)
1717
}
1818
}
19+
var isPinned: Bool = UserDefaults.standard.bool(forKey: "isPinned") {
20+
didSet { UserDefaults.standard.set(isPinned, forKey: "isPinned") }
21+
}
1922
let settingsManager = SettingsManager()
2023
var isSettingsOpen: Bool {
2124
get { settingsManager.isSettingsOpen }

Ghostly/GhostlyApp.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct GhostlyApp: App {
2424
}
2525
}
2626
.menuBarExtraStyle(.window)
27-
.menuBarExtraAccess(isPresented: $appState.isMenuPresented) { statusItem in
27+
.menuBarExtraAccess(isPresented: $appState.isMenuPresented, staysOpen: $appState.isPinned) { statusItem in
2828
statusItemContextMenuController.configure(statusItem: statusItem, appState: appState)
2929
}
3030
}

Ghostly/Views/ContentView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct ContentView: View {
5050
).ignoresSafeArea()
5151

5252
VStack(alignment: .leading, spacing: 0) {
53-
HeaderView(settingsManager: settingsManager)
53+
HeaderView(appState: appState)
5454

5555
if tabManager.tabs.count > 1 {
5656
TabBarView(tabManager: tabManager)

Ghostly/Views/HeaderView.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import SwiftUI
99

1010
struct HeaderView: View {
11-
var settingsManager: SettingsManager
11+
@Bindable var appState: AppState
1212
@State private var isHovered = false
1313

14+
private var settingsManager: SettingsManager { appState.settingsManager }
15+
1416
var body: some View {
1517
VStack(spacing: 0) {
1618
HStack {
@@ -35,6 +37,20 @@ struct HeaderView: View {
3537

3638
Spacer()
3739

40+
// Pin button — keeps window open when focus moves to another app
41+
Button {
42+
appState.isPinned.toggle()
43+
} label: {
44+
Image(systemName: appState.isPinned ? "pin.fill" : "pin")
45+
.font(.system(size: 12))
46+
.foregroundStyle(appState.isPinned ? Color.catLavender : Color.catOverlay.opacity(0.7))
47+
.rotationEffect(.degrees(45))
48+
}
49+
.buttonStyle(.plain)
50+
.frame(width: 28, height: 28)
51+
.help(appState.isPinned ? "Unpin (window will close when focus is lost)" : "Pin (keep window open when switching apps)")
52+
.accessibilityIdentifier("pinButton")
53+
3854
// Menu button
3955
DropdownMenuView(settingsManager: settingsManager)
4056
.frame(width: 28, height: 28)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// swift-tools-version: 5.7
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "MenuBarExtraAccess",
7+
platforms: [.macOS(.v10_15)],
8+
products: [
9+
.library(name: "MenuBarExtraAccess", targets: ["MenuBarExtraAccess"])
10+
],
11+
targets: [
12+
.target(
13+
name: "MenuBarExtraAccess",
14+
swiftSettings: [
15+
// un-comment to enable debug logging
16+
// .define("MENUBAREXTRAACCESS_DEBUG_LOGGING=1")
17+
]
18+
)
19+
]
20+
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// MenuBarExtra Window Introspection.swift
3+
// MenuBarExtraAccess • https://github.com/orchetect/MenuBarExtraAccess
4+
// © 2023 Steffan Andrews • Licensed under MIT License
5+
//
6+
7+
#if os(macOS)
8+
9+
import SwiftUI
10+
11+
@MainActor // required for Xcode 15 builds
12+
extension View {
13+
/// Provides introspection on the underlying window presented by `MenuBarExtra`.
14+
/// Add this view modifier to the top level of the View that occupies the `MenuBarExtra` content.
15+
/// If more than one MenuBarExtra are used in the app, provide the sequential index number of the `MenuBarExtra`.
16+
public func introspectMenuBarExtraWindow(
17+
index: Int = 0,
18+
_ block: @escaping (_ window: NSWindow) -> Void
19+
) -> some View {
20+
self
21+
.onAppear {
22+
guard let window = MenuBarExtraUtils.window(for: .index(index)) else {
23+
#if MENUBAREXTRAACCESS_DEBUG_LOGGING
24+
print("Cannot call introspection block for status item because its window could not be found.")
25+
#endif
26+
27+
return
28+
}
29+
30+
block(window)
31+
}
32+
}
33+
}
34+
35+
#endif

0 commit comments

Comments
 (0)