Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions Loop/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -21098,6 +21098,10 @@
}
}
},
"Supports macOS Tahoe’s Liquid Glass effects" : {
"comment" : "A tooltip that appears when hovering over the icon, explaining its function.",
"isCommentAutoGenerated" : true
},
"Sync Wallpaper" : {
"localizations" : {
"ar" : {
Expand Down Expand Up @@ -21784,10 +21788,6 @@
}
}
},
"This icon supports macOS Tahoe's new\nLiquid Glass icon format." : {
"comment" : "A tooltip that appears when the user hovers over a locked icon, explaining that it supports macOS Tahoe's new Liquid Glass icon format.",
"isCommentAutoGenerated" : true
},
"To save power, window animations are\nunavailable in Low Power Mode." : {
"localizations" : {
"ar" : {
Expand Down Expand Up @@ -25308,6 +25308,17 @@
}
}
},
"Window Direction/Name: Minimize Others" : {
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Minimize Others"
}
}
}
},
"Window Direction/Name: Move Down" : {
"localizations" : {
"ar" : {
Expand Down
4 changes: 4 additions & 0 deletions Loop/Window Management/WindowAction+Image.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extension WindowAction {
Image(systemName: "eye.slash.fill")
case .minimize:
Image(systemName: "arrow.down.right.and.arrow.up.left")
case .minimizeOthers:
Image(systemName: "arrow.down.right.and.arrow.up.left")
case .maximizeHeight:
Image(systemName: "arrow.up.and.down")
case .maximizeWidth:
Expand Down Expand Up @@ -58,6 +60,8 @@ extension WindowAction {
Image(systemName: "eye.slash")
case .minimize:
Image(systemName: "arrow.down.right.and.arrow.up.left")
case .minimizeOthers:
Image(systemName: "arrow.down.right.and.arrow.up.left")
default:
nil
}
Expand Down
2 changes: 2 additions & 0 deletions Loop/Window Management/WindowDirection+LocalizedString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ extension WindowDirection {
.init(localized: .init("Window Direction/Name: Hide", defaultValue: "Hide"))
case .minimize:
.init(localized: .init("Window Direction/Name: Minimize", defaultValue: "Minimize"))
case .minimizeOthers:
.init(localized: .init("Window Direction/Name: Minimize Others", defaultValue: "Minimize Others"))
case .macOSCenter:
.init(localized: .init("Window Direction/Name: macOS Center", defaultValue: "macOS Center"))
case .center:
Expand Down
6 changes: 3 additions & 3 deletions Loop/Window Management/WindowDirection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ enum WindowDirection: String, CaseIterable, Identifiable, Codable {
// General Actions
case noAction = "NoAction", maximize = "Maximize", almostMaximize = "AlmostMaximize", fullscreen = "Fullscreen"
case maximizeHeight = "MaximizeHeight", maximizeWidth = "MaximizeWidth"
case undo = "Undo", initialFrame = "InitialFrame", hide = "Hide", minimize = "Minimize"
case undo = "Undo", initialFrame = "InitialFrame", hide = "Hide", minimize = "Minimize", minimizeOthers = "MinimizeOthers"
case macOSCenter = "MacOSCenter", center = "Center"

// Halves
Expand Down Expand Up @@ -59,7 +59,7 @@ enum WindowDirection: String, CaseIterable, Identifiable, Codable {
case custom = "Custom", cycle = "Cycle"

// These are used in the menubar resize submenu & keybind configuration
static var general: [WindowDirection] { [.fullscreen, .maximize, .almostMaximize, .maximizeHeight, .maximizeWidth, .center, .macOSCenter, .minimize, .hide] }
static var general: [WindowDirection] { [.fullscreen, .maximize, .almostMaximize, .maximizeHeight, .maximizeWidth, .center, .macOSCenter, .minimize, .minimizeOthers, .hide] }
static var halves: [WindowDirection] { [.topHalf, .verticalCenterHalf, .bottomHalf, .leftHalf, .horizontalCenterHalf, .rightHalf] }
static var quarters: [WindowDirection] { [.topLeftQuarter, .topRightQuarter, .bottomLeftQuarter, .bottomRightQuarter] }
static var horizontalThirds: [WindowDirection] { [.rightThird, .rightTwoThirds, .horizontalCenterThird, .leftTwoThirds, .leftThird] }
Expand All @@ -82,7 +82,7 @@ enum WindowDirection: String, CaseIterable, Identifiable, Codable {
var isCustomizable: Bool { [.custom, .stash].contains(self) }

var hasRadialMenuAngle: Bool {
let noAngleActions: [WindowDirection] = [.noAction, .minimize, .hide, .initialFrame, .undo, .cycle]
let noAngleActions: [WindowDirection] = [.noAction, .minimize, .minimizeOthers, .hide, .initialFrame, .undo, .cycle]
return !(noAngleActions.contains(self) || willChangeScreen || willAdjustSize || willShrink || willGrow || willMove || willMaximize || willCenter)
}

Expand Down
26 changes: 26 additions & 0 deletions Loop/Window Management/WindowEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ enum WindowEngine {
return
}

if action.direction == .minimizeOthers {
minimizeOtherWindows(exceptWindow: window)
return
}

// Note that this is only really useful when "Resize window under cursor" is enabled
if Defaults[.focusWindowOnResize] {
window.activate()
Expand Down Expand Up @@ -301,4 +306,25 @@ enum WindowEngine {

window.position = windowFrame.origin
}

/// Minimizes all windows except the current one
private static func minimizeOtherWindows(exceptWindow: Window) {
let allWindows = windowList
let windowsToMinimize = allWindows.filter { otherWindow in
// Don't minimize the current window
guard otherWindow.cgWindowID != exceptWindow.cgWindowID else { return false }

// Only minimize windows that are not already minimized or hidden
guard !otherWindow.minimized, !otherWindow.isWindowHidden else { return false }

return true
}

print("Minimizing \(windowsToMinimize.count) other windows")

// Minimize all other windows
for window in windowsToMinimize {
window.minimized = true
}
}
}