Skip to content

Commit

Permalink
Merge pull request #1482 from strategiconquest/additional-macOS-tilin…
Browse files Browse the repository at this point in the history
…g-checks

Handle additional tiling setting in macOS 15.1
  • Loading branch information
rxhanson authored Oct 7, 2024
2 parents 6db3a8a + e5444a7 commit 919f0be
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 41 deletions.
39 changes: 1 addition & 38 deletions Rectangle/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.titleBarManager = TitleBarManager()
self.initializeTodo()
checkForProblematicApps()
checkForBuiltInTiling()
MacTilingDefaults.checkForBuiltInTiling(skipIfAlreadyNotified: true)
}

func checkForConflictingApps() {
Expand Down Expand Up @@ -191,44 +191,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
Defaults.notifiedOfProblemApps.enabled = true
}
}

func checkForBuiltInTiling() {
guard #available(macOS 15, *),
!Defaults.internalTilingNotified.enabled,
!Defaults.windowSnapping.userDisabled
else {
return
}

Defaults.internalTilingNotified.enabled = true
if MacTilingDefaults.tilingByEdgeDrag.enabled || MacTilingDefaults.tilingOptionAccelerator.enabled {
let result = AlertUtil.threeButtonAlert(
question: "Conflict with macOS tiling".localized,
text: "Drag to screen edge tiling is enabled in both Rectangle and macOS.".localized,
buttonOneText: "Disable in macOS".localized,
buttonTwoText: "Disable in Rectangle".localized,
buttonThreeText: "Dismiss".localized)
switch result {
case .alertFirstButtonReturn:
MacTilingDefaults.tilingByEdgeDrag.disable()
MacTilingDefaults.tilingOptionAccelerator.disable()

let result = AlertUtil.twoButtonAlert(
question: "Tiling in macOS has been disabled".localized,
text: "To re-enable it, go to System Settings → Desktop & Dock → Windows".localized,
cancelText: "Open System Settings".localized)
if result == .alertSecondButtonReturn {
MacTilingDefaults.openSystemSettings()
}
case .alertSecondButtonReturn:
Defaults.windowSnapping.enabled = false
Notification.Name.windowSnapping.post(object: false)
default:
break
}
}
}

private func showWelcomeWindow() {
let welcomeWindowController = NSStoryboard(name: "Main", bundle: nil)
.instantiateController(withIdentifier: "WelcomeWindowController") as? NSWindowController
Expand Down
9 changes: 7 additions & 2 deletions Rectangle/PrefsWindow/SnapAreaViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class SnapAreaViewController: NSViewController {
let newSetting: Bool = sender.state == .on
Defaults.windowSnapping.enabled = newSetting
Notification.Name.windowSnapping.post(object: newSetting)
if newSetting {
MacTilingDefaults.checkForBuiltInTiling(skipIfAlreadyNotified: false)
}
}

@IBAction func toggleUnsnapRestore(_ sender: NSButton) {
Expand Down Expand Up @@ -102,14 +105,16 @@ class SnapAreaViewController: NSViewController {
Notification.Name.appWillBecomeActive.onPost() { [weak self] _ in
self?.showHidePortrait()
}
Notification.Name.windowSnapping.onPost { [weak self] _ in
self?.windowSnappingCheckbox.state = Defaults.windowSnapping.userDisabled ? .off : .on
}
NotificationCenter.default.addObserver(forName: NSApplication.didChangeScreenParametersNotification, object: nil, queue: nil) { [weak self] _ in
self?.showHidePortrait()
}
}

func showHidePortrait() {
let hasPortraitDisplay = NSScreen.screens.contains(where: {!$0.frame.isLandscape})
portraitStackView.isHidden = !hasPortraitDisplay
portraitStackView.isHidden = !NSScreen.portraitDisplayConnected
}

func loadSnapAreas() {
Expand Down
3 changes: 3 additions & 0 deletions Rectangle/ScreenDetection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,8 @@ extension NSScreen {
return newFrame
}

static var portraitDisplayConnected: Bool {
NSScreen.screens.contains(where: {!$0.frame.isLandscape})
}
}

14 changes: 14 additions & 0 deletions Rectangle/Snapping/SnapAreaModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ class SnapAreaModel {
var portrait: [Directional:SnapAreaConfig] {
Defaults.portraitSnapAreas.typedValue ?? SnapAreaModel.defaultPortrait
}

var isTopConfigured: Bool {
if let landscapeTop = landscape[.t] {
if landscapeTop.action != nil || landscapeTop.compound != nil {
return true
}
}
if NSScreen.portraitDisplayConnected, let portraitTop = portrait[.t] {
if portraitTop.action != nil || portraitTop.compound != nil {
return true
}
}
return false
}

func setConfig(type: DisplayOrientation, directional: Directional, snapAreaConfig: SnapAreaConfig?) {
switch type {
Expand Down
76 changes: 76 additions & 0 deletions Rectangle/Utilities/MacTilingDefaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum MacTilingDefaults: String {
case tilingByEdgeDrag = "EnableTilingByEdgeDrag"
case tilingOptionAccelerator = "EnableTilingOptionAccelerator"
case tiledWindowMargins = "EnableTiledWindowMargins"
case topTilingByEdgeDrag = "EnableTopTilingByEdgeDrag"

var enabled: Bool {
guard #available(macOS 15, *), let defaults = UserDefaults(suiteName: "com.apple.WindowManager")
Expand All @@ -39,4 +40,79 @@ enum MacTilingDefaults: String {
static func openSystemSettings() {
NSWorkspace.shared.open(URL(string:"x-apple.systempreferences:com.apple.preference.Desktop-Settings.extension")!)
}

static func checkForBuiltInTiling(skipIfAlreadyNotified: Bool) {
guard #available(macOS 15, *), !Defaults.windowSnapping.userDisabled
else { return }

let isStandardTilingConflicting = (tilingByEdgeDrag.enabled || tilingOptionAccelerator.enabled)

let isTopTilingConflicting = topTilingByEdgeDrag.enabled && SnapAreaModel.instance.isTopConfigured

let shouldSkipStandardCheck = skipIfAlreadyNotified && Defaults.internalTilingNotified.enabled

if isStandardTilingConflicting && !shouldSkipStandardCheck {
resolveStandardTilingConflict()
} else if isTopTilingConflicting {
resolveTopTilingConflict()
}
Defaults.internalTilingNotified.enabled = true
}

private static func resolveTopTilingConflict() {
Logger.log("Automatically disabling macOS top edge tiling to resolve conflict with macOS.")

topTilingByEdgeDrag.disable()

if !Defaults.internalTilingNotified.enabled {
// First time running Rectangle & only has drag to top enabled in macOS
let result = AlertUtil.twoButtonAlert(
question: "Top screen edge tiling in macOS is now disabled".localized,
text: "To adjust macOS tiling, go to System Settings → Desktop & Dock → Windows".localized,
cancelText: "Open System Settings".localized)
if result == .alertSecondButtonReturn {
openSystemSettings()
}
}
}

private static func resolveStandardTilingConflict() {
let result = AlertUtil.threeButtonAlert(
question: "Conflict with macOS tiling".localized,
text: "Drag to screen edge tiling is enabled in both Rectangle and macOS.".localized,
buttonOneText: "Disable in macOS".localized,
buttonTwoText: "Disable in Rectangle".localized,
buttonThreeText: "Dismiss".localized)
switch result {
case .alertFirstButtonReturn:
disableMacTiling()

let result = AlertUtil.twoButtonAlert(
question: "Tiling in macOS has been disabled".localized,
text: "To re-enable it, go to System Settings → Desktop & Dock → Windows".localized,
cancelText: "Open System Settings".localized)
if result == .alertSecondButtonReturn {
openSystemSettings()
}
case .alertSecondButtonReturn:
Defaults.windowSnapping.enabled = false
Notification.Name.windowSnapping.post(object: false)

let result = AlertUtil.twoButtonAlert(
question: "Tiling in Rectangle has been disabled".localized,
text: "To adjust macOS tiling, go to System Settings → Desktop & Dock → Windows".localized,
cancelText: "Open System Settings".localized)
if result == .alertSecondButtonReturn {
openSystemSettings()
}
default:
break
}
}

private static func disableMacTiling() {
tilingByEdgeDrag.disable()
tilingOptionAccelerator.disable()
topTilingByEdgeDrag.disable()
}
}
11 changes: 10 additions & 1 deletion Rectangle/mul.lproj/Main.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -39929,6 +39929,9 @@
}
}
},
"Tiling in Rectangle has been disabled" : {
"extractionState" : "manual"
},
"tlD-Oa-oAM.title" : {
"comment" : "Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"tlD-Oa-oAM\";",
"extractionState" : "manual",
Expand Down Expand Up @@ -40061,6 +40064,9 @@
}
}
},
"To adjust macOS tiling, go to System Settings → Desktop & Dock → Windows" : {
"extractionState" : "manual"
},
"To let Rectangle manage the title bar double click functionality, you need to disable the corresponding macOS setting." : {
"localizations" : {
"ar" : {
Expand Down Expand Up @@ -40262,6 +40268,9 @@
}
}
},
"Top screen edge tiling in macOS is now disabled" : {
"extractionState" : "manual"
},
"Top sixths from corners; maximize" : {
"localizations" : {
"ar" : {
Expand Down Expand Up @@ -48838,4 +48847,4 @@
}
},
"version" : "1.0"
}
}

0 comments on commit 919f0be

Please sign in to comment.