Skip to content

Commit 3907553

Browse files
committed
added borderless setting
1 parent 25fd758 commit 3907553

File tree

5 files changed

+52
-23
lines changed

5 files changed

+52
-23
lines changed

Nook/Components/Browser/Window/WindowView.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct WindowView: View {
3030
// Gradient background for the current space (bottom-most layer)
3131
SpaceGradientBackgroundView()
3232
.environmentObject(windowState)
33-
33+
3434
// Attach background context menu to the window background layer
3535
Color.white.opacity(isDark ? 0.3 : 0.4)
3636
.ignoresSafeArea(.all)
@@ -49,10 +49,8 @@ struct WindowView: View {
4949
.environmentObject(browserManager)
5050
.environmentObject(windowState)
5151
.background(Color.clear)
52-
5352
mainLayout
5453
}
55-
5654
// TopBar Command Palette overlay
5755
TopBarCommandPalette()
5856
.environmentObject(browserManager)
@@ -94,7 +92,7 @@ struct WindowView: View {
9492
}
9593
}
9694

97-
95+
9896
// Toast overlays (matches WebsitePopup style/presentation)
9997
VStack {
10098
HStack {
@@ -219,8 +217,8 @@ struct WindowView: View {
219217
sidebarColumn
220218
}
221219
}
222-
.padding(.trailing, windowState.isFullScreen ? 0 : (windowState.isSidebarVisible && browserManager.settingsManager.sidebarPosition == .right ? 0 : aiVisible ? 0 : 8))
223-
.padding(.leading, windowState.isFullScreen ? 0 : (windowState.isSidebarVisible && browserManager.settingsManager.sidebarPosition == .left ? 0 : aiVisible ? 0 : 8))
220+
.padding(.trailing, (windowState.isFullScreen || browserManager.settingsManager.borderless) ? 0 : (windowState.isSidebarVisible && browserManager.settingsManager.sidebarPosition == .right ? 0 : aiVisible ? 0 : 8))
221+
.padding(.leading, (windowState.isFullScreen || browserManager.settingsManager.borderless) ? 0 : (windowState.isSidebarVisible && browserManager.settingsManager.sidebarPosition == .left ? 0 : aiVisible ? 0 : 8))
224222
}
225223

226224
private var sidebarColumn: some View {
@@ -230,7 +228,7 @@ struct WindowView: View {
230228
if windowState.isSidebarVisible {
231229
// Position to span 14pts into sidebar and 2pts into web content (moved 6pts left)
232230
SidebarResizeView()
233-
231+
234232
.frame(maxHeight: .infinity)
235233
.environmentObject(browserManager)
236234
.environmentObject(windowState)

Nook/Components/Settings/SettingsView.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,22 @@ struct GeneralSettingsView: View {
196196
.foregroundStyle(.secondary)
197197
}
198198
}
199+
200+
Divider().opacity(0.4)
201+
202+
Toggle(
203+
isOn: $browserManager.settingsManager
204+
.borderless
205+
) {
206+
VStack(alignment: .leading, spacing: 2) {
207+
Text("Borderless")
208+
Text(
209+
"Remove the window border for a cleaner look"
210+
)
211+
.font(.caption)
212+
.foregroundStyle(.secondary)
213+
}
214+
}
199215
}
200216

201217
SettingsSectionCard(

Nook/Components/WebsiteView/EmptyWebsiteView.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ struct EmptyWebsiteView: View {
2121
if windowState.isFullScreen {
2222
return 0
2323
}
24+
if browserManager.settingsManager.borderless {
25+
return 0
26+
}
2427
if #available(macOS 26.0, *) {
2528
return 12
2629
} else {

Nook/Components/WebsiteView/WebsiteView.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import AppKit
1313
struct LinkStatusBar: View {
1414
let hoveredLink: String?
1515
let isCommandPressed: Bool
16-
16+
1717
var body: some View {
1818
if let link = hoveredLink, !link.isEmpty {
1919
Text(isCommandPressed ? "Open \(link) in a new tab and focus it" : link)
@@ -73,6 +73,9 @@ struct WebsiteView: View {
7373
if windowState.isFullScreen {
7474
return 0
7575
}
76+
if browserManager.settingsManager.borderless {
77+
return 0
78+
}
7679
if #available(macOS 26.0, *) {
7780
return 12
7881
} else {

Nook/Managers/SettingsManager/SettingsManager.swift

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class SettingsManager {
3434
private let webSearchEngineKey = "settings.webSearchEngine"
3535
private let webSearchMaxResultsKey = "settings.webSearchMaxResults"
3636
private let webSearchContextSizeKey = "settings.webSearchContextSize"
37+
private let borderlessKey = "settings.borderless"
3738
var currentSettingsTab: SettingsTabs = .general
3839

3940
// Stored properties
@@ -62,7 +63,7 @@ class SettingsManager {
6263
userDefaults.set(searchEngine.rawValue, forKey: searchEngineKey)
6364
}
6465
}
65-
66+
6667
var tabUnloadTimeout: TimeInterval {
6768
didSet {
6869
userDefaults.set(tabUnloadTimeout, forKey: tabUnloadTimeoutKey)
@@ -77,19 +78,19 @@ class SettingsManager {
7778
NotificationCenter.default.post(name: .blockCrossSiteTrackingChanged, object: nil, userInfo: ["enabled": blockCrossSiteTracking])
7879
}
7980
}
80-
81+
8182
var askBeforeQuit: Bool {
8283
didSet {
8384
userDefaults.set(askBeforeQuit, forKey: askBeforeQuitKey)
8485
}
8586
}
86-
87+
8788
var sidebarPosition: SidebarPosition {
8889
didSet {
8990
userDefaults.set(sidebarPosition.rawValue, forKey: sidebarPositionKey)
9091
}
9192
}
92-
93+
9394
var topBarAddressView: Bool {
9495
didSet {
9596
userDefaults.set(topBarAddressView, forKey: topBarAddressViewKey)
@@ -126,6 +127,12 @@ class SettingsManager {
126127
}
127128
}
128129

130+
var borderless: Bool {
131+
didSet {
132+
userDefaults.set(borderless, forKey: borderlessKey)
133+
}
134+
}
135+
129136
var aiProvider: AIProvider {
130137
didSet {
131138
userDefaults.set(aiProvider.rawValue, forKey: aiProviderKey)
@@ -205,7 +212,8 @@ class SettingsManager {
205212
webSearchEnabledKey: false,
206213
webSearchEngineKey: "auto",
207214
webSearchMaxResultsKey: 5,
208-
webSearchContextSizeKey: "medium"
215+
webSearchContextSizeKey: "medium",
216+
borderlessKey: false
209217
])
210218

211219
// Initialize properties from UserDefaults
@@ -221,7 +229,7 @@ class SettingsManager {
221229
// Fallback to google if the stored value is somehow invalid
222230
self.searchEngine = .google
223231
}
224-
232+
225233
// Initialize tab unload timeout
226234
self.tabUnloadTimeout = userDefaults.double(forKey: tabUnloadTimeoutKey)
227235
self.blockCrossSiteTracking = userDefaults.bool(forKey: blockXSTKey)
@@ -242,6 +250,7 @@ class SettingsManager {
242250
self.webSearchEngine = userDefaults.string(forKey: webSearchEngineKey) ?? "auto"
243251
self.webSearchMaxResults = userDefaults.integer(forKey: webSearchMaxResultsKey)
244252
self.webSearchContextSize = userDefaults.string(forKey: webSearchContextSizeKey) ?? "medium"
253+
self.borderless = userDefaults.bool(forKey: borderlessKey)
245254
}
246255
}
247256

@@ -251,17 +260,17 @@ public enum AIProvider: String, CaseIterable, Identifiable {
251260
case gemini = "gemini"
252261
case openRouter = "openrouter"
253262
case ollama = "ollama"
254-
263+
255264
public var id: String { rawValue }
256-
265+
257266
var displayName: String {
258267
switch self {
259268
case .gemini: return "Google Gemini"
260269
case .openRouter: return "OpenRouter"
261270
case .ollama: return "Ollama (Local)"
262271
}
263272
}
264-
273+
265274
var isRecommended: Bool {
266275
return false
267276
}
@@ -272,23 +281,23 @@ public enum AIProvider: String, CaseIterable, Identifiable {
272281
public enum GeminiModel: String, CaseIterable, Identifiable {
273282
case flash = "gemini-flash-latest"
274283
case pro = "gemini-2.5-pro"
275-
284+
276285
public var id: String { rawValue }
277-
286+
278287
var displayName: String {
279288
switch self {
280289
case .flash: return "Gemini Flash"
281290
case .pro: return "Gemini 2.5 Pro"
282291
}
283292
}
284-
293+
285294
var description: String {
286295
switch self {
287296
case .flash: return "Fast responses, great for quick questions"
288297
case .pro: return "Most capable model, best for complex analysis"
289298
}
290299
}
291-
300+
292301
var icon: String {
293302
switch self {
294303
case .flash: return "bolt.fill"
@@ -311,9 +320,9 @@ public enum OpenRouterModel: String, CaseIterable, Identifiable {
311320
case gpt5mini = "openai/gpt-5-mini"
312321
case gpt5 = "openai/gpt-5"
313322

314-
323+
315324
public var id: String { rawValue }
316-
325+
317326
var displayName: String {
318327
switch self {
319328
case .deepseekChatV31: return "DeepSeek Chat V3.1 (Free)"

0 commit comments

Comments
 (0)