Skip to content

Commit

Permalink
Merge pull request #1083 from decodism/master-2
Browse files Browse the repository at this point in the history
Fix initial Todo shortcuts display
  • Loading branch information
rxhanson authored Feb 27, 2023
2 parents e0cd29c + 6404348 commit 4dda4fd
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 198 deletions.
11 changes: 3 additions & 8 deletions Rectangle/AccessibilityElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class AccessibilityElement {
return childElements?.filter { $0.role == role }
}

fileprivate var windowId: CGWindowID? {
var windowId: CGWindowID? {
wrappedElement.getWindowId()
}

Expand Down Expand Up @@ -193,7 +193,7 @@ class AccessibilityElement {
applicationElement?.getElementValue(.focusedWindow)
}

private var windowElements: [AccessibilityElement]? {
var windowElements: [AccessibilityElement]? {
applicationElement?.getElementsValue(.windows)
}

Expand Down Expand Up @@ -292,11 +292,6 @@ extension AccessibilityElement {
return nil
}

static func getTodoWindowElement() -> AccessibilityElement? {
guard let bundleIdentifier = Defaults.todoApplication.value else { return nil }
return AccessibilityElement(bundleIdentifier)?.windowElements?.first
}

static func getWindowElement(_ windowId: CGWindowID) -> AccessibilityElement? {
guard let pid = WindowUtil.getWindowList([windowId]).first?.pid else { return nil }
return AccessibilityElement(pid).windowElements?.first { $0.windowId == windowId }
Expand All @@ -322,7 +317,7 @@ class StageWindowAccessibilityElement: AccessibilityElement {
return .init(origin: info.frame.origin, size: frame.size)
}

override fileprivate var windowId: CGWindowID? {
override var windowId: CGWindowID? {
_windowId
}
}
Expand Down
21 changes: 6 additions & 15 deletions Rectangle/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -398,12 +398,9 @@ extension AppDelegate: NSMenuDelegate {
extension AppDelegate {
func initializeTodo(_ bringToFront: Bool = true) {
self.showHideTodoMenuItems()
guard Defaults.todo.userEnabled else { return }
TodoManager.registerToggleShortcut()
TodoManager.registerReflowShortcut()
if Defaults.todoMode.enabled {
TodoManager.moveAll(bringToFront)
}
TodoManager.registerUnregisterToggleShortcut()
TodoManager.registerUnregisterReflowShortcut()
TodoManager.moveAllIfNeeded(bringToFront)
}

enum TodoItem {
Expand Down Expand Up @@ -459,19 +456,13 @@ extension AppDelegate {
}

@objc func toggleTodoMode(_ sender: NSMenuItem) {
if sender.state == .off {
Defaults.todoMode.enabled = true
TodoManager.moveAll()
} else {
Defaults.todoMode.enabled = false
}
let enabled = sender.state == .off
TodoManager.setTodoMode(enabled)
}

@objc func setTodoApp(_ sender: NSMenuItem) {
applicationToggle.setTodoApp()
if Defaults.todoMode.enabled {
TodoManager.moveAll()
}
TodoManager.moveAllIfNeeded()
}

@objc func todoReflow(_ sender: NSMenuItem) {
Expand Down
290 changes: 151 additions & 139 deletions Rectangle/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions Rectangle/PrefsWindow/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class SettingsViewController: NSViewController {
@IBOutlet weak var gapLabel: NSTextField!
@IBOutlet weak var cursorAcrossCheckbox: NSButton!
@IBOutlet weak var todoCheckbox: NSButton!
@IBOutlet weak var todoView: NSStackView!
@IBOutlet weak var todoAppWidthField: AutoSaveFloatField!
@IBOutlet weak var todoAppSidePopUpButton: NSPopUpButton!
@IBOutlet weak var toggleTodoShortcutView: MASShortcutView!
Expand Down Expand Up @@ -93,6 +94,7 @@ class SettingsViewController: NSViewController {
@IBAction func toggleTodoMode(_ sender: NSButton) {
let newSetting: Bool = sender.state == .on
Defaults.todo.enabled = newSetting
showHideTodoModeSettings()
Notification.Name.todoMenuToggled.post()
}

Expand All @@ -113,8 +115,7 @@ class SettingsViewController: NSViewController {

Defaults.todoSidebarSide.value = side

guard Defaults.todo.userEnabled && Defaults.todoMode.enabled else { return }
TodoManager.moveAll(false)
TodoManager.moveAllIfNeeded(false)
}

@IBAction func stageSliderChanged(_ sender: NSSlider) {
Expand Down Expand Up @@ -205,12 +206,18 @@ class SettingsViewController: NSViewController {
todoAppWidthField.delegate = self
todoAppWidthField.defaults = Defaults.todoSidebarWidth
todoAppWidthField.defaultsSetAction = {
guard Defaults.todo.userEnabled && Defaults.todoMode.enabled else { return }
TodoManager.moveAll(false)
TodoManager.moveAllIfNeeded(false)
}
todoAppSidePopUpButton.selectItem(withTag: Defaults.todoSidebarSide.value.rawValue)
TodoManager.initToggleShortcut()
TodoManager.initReflowShortcut()
toggleTodoShortcutView.setAssociatedUserDefaultsKey(TodoManager.toggleDefaultsKey, withTransformerName: MASDictionaryTransformerName)
reflowTodoShortcutView.setAssociatedUserDefaultsKey(TodoManager.reflowDefaultsKey, withTransformerName: MASDictionaryTransformerName)
showHideTodoModeSettings()
}

private func showHideTodoModeSettings() {
todoView.isHidden = !Defaults.todo.userEnabled
}

func initializeToggles() {
Expand Down
4 changes: 2 additions & 2 deletions Rectangle/Snapping/SnappingManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ class SnappingManager {
func getBoxRect(hotSpot: SnapArea, currentWindow: Window) -> CGRect? {
if let calculation = WindowCalculationFactory.calculationsByAction[hotSpot.action] {

let ignoreTodo = TodoManager.isTodoWindow(id: currentWindow.id)
let ignoreTodo = TodoManager.isTodoWindow(currentWindow.id)
let rectCalcParams = RectCalculationParameters(window: currentWindow, visibleFrameOfScreen: hotSpot.screen.adjustedVisibleFrame(ignoreTodo), action: hotSpot.action, lastAction: nil)
let rectResult = calculation.calculateRect(rectCalcParams)

Expand All @@ -368,7 +368,7 @@ class SnappingManager {
guard let directional = directionalLocationOfCursor(loc: loc, screen: screen)
else { continue }

if let windowId = windowId, Defaults.todo.userEnabled && Defaults.todoMode.enabled && TodoManager.isTodoWindow(id: windowId) {
if let windowId = windowId, Defaults.todo.userEnabled && Defaults.todoMode.enabled && TodoManager.isTodoWindow(windowId) {
if Defaults.todoSidebarSide.value == .left && directional == .l {
return SnapArea(screen: screen, directional: directional, action: .leftTodo)
}
Expand Down
119 changes: 90 additions & 29 deletions Rectangle/TodoMode/TodoManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ import Cocoa
import MASShortcut

class TodoManager {
private static var todoWindowId: CGWindowID?

static var todoScreen : NSScreen?
static let toggleDefaultsKey = "toggleTodo"
static let reflowDefaultsKey = "reflowTodo"
static let defaultsKeys = [toggleDefaultsKey, reflowDefaultsKey]

static func registerToggleShortcut() {

static func setTodoMode(_ enabled: Bool, _ bringToFront: Bool = true) {
Defaults.todoMode.enabled = enabled
registerUnregisterReflowShortcut()
moveAllIfNeeded(bringToFront)
}

static func initToggleShortcut() {
if UserDefaults.standard.dictionary(forKey: toggleDefaultsKey) == nil {
guard let dictTransformer = ValueTransformer(forName: NSValueTransformerName(rawValue: MASDictionaryTransformerName)) else { return }

Expand All @@ -25,18 +32,9 @@ class TodoManager {
let toggleShortcutDict = dictTransformer.reverseTransformedValue(toggleShortcut)
UserDefaults.standard.set(toggleShortcutDict, forKey: toggleDefaultsKey)
}

MASShortcutBinder.shared()?.bindShortcut(withDefaultsKey: toggleDefaultsKey, toAction: {
guard Defaults.todo.userEnabled else { return }
Defaults.todoMode.enabled.toggle()
if Defaults.todoMode.enabled {
TodoManager.moveAll()
}
})
}

static func registerReflowShortcut() {

static func initReflowShortcut() {
if UserDefaults.standard.dictionary(forKey: reflowDefaultsKey) == nil {
guard let dictTransformer = ValueTransformer(forName: NSValueTransformerName(rawValue: MASDictionaryTransformerName)) else { return }

Expand All @@ -45,34 +43,92 @@ class TodoManager {
let reflowShortcutDict = dictTransformer.reverseTransformedValue(reflowShortcut)
UserDefaults.standard.set(reflowShortcutDict, forKey: reflowDefaultsKey)
}

}

private static func registerToggleShortcut() {
MASShortcutBinder.shared()?.bindShortcut(withDefaultsKey: toggleDefaultsKey, toAction: {
let enabled = !Defaults.todoMode.enabled
setTodoMode(enabled)
})
}

private static func registerReflowShortcut() {
MASShortcutBinder.shared()?.bindShortcut(withDefaultsKey: reflowDefaultsKey, toAction: {
guard Defaults.todo.userEnabled && Defaults.todoMode.enabled else { return }
TodoManager.moveAll()
moveAll()
})
}

private static func unregisterToggleShortcut() {
MASShortcutBinder.shared()?.breakBinding(withDefaultsKey: toggleDefaultsKey)
}

private static func unregisterReflowShortcut() {
MASShortcutBinder.shared()?.breakBinding(withDefaultsKey: reflowDefaultsKey)
}

static func registerUnregisterToggleShortcut() {
if Defaults.todo.userEnabled {
registerToggleShortcut()
} else {
unregisterToggleShortcut()
}
}

static func registerUnregisterReflowShortcut() {
if Defaults.todo.userEnabled && Defaults.todoMode.enabled {
registerReflowShortcut()
} else {
unregisterReflowShortcut()
}
}

static func getToggleKeyDisplay() -> (String?, NSEvent.ModifierFlags)? {
guard let masShortcut = MASShortcutBinder.shared()?.value(forKey: toggleDefaultsKey) as? MASShortcut else { return nil }
return (masShortcut.keyCodeStringForKeyEquivalent, masShortcut.modifierFlags)
guard
let shortcutDict = UserDefaults.standard.dictionary(forKey: toggleDefaultsKey),
let dictTransformer = ValueTransformer(forName: NSValueTransformerName(rawValue: MASDictionaryTransformerName)),
let shortcut = dictTransformer.transformedValue(shortcutDict) as? MASShortcut
else {
return nil
}
return (shortcut.keyCodeStringForKeyEquivalent, shortcut.modifierFlags)
}

static func getReflowKeyDisplay() -> (String?, NSEvent.ModifierFlags)? {
guard let masShortcut = MASShortcutBinder.shared()?.value(forKey: reflowDefaultsKey) as? MASShortcut else { return nil }
return (masShortcut.keyCodeStringForKeyEquivalent, masShortcut.modifierFlags)
guard
let shortcutDict = UserDefaults.standard.dictionary(forKey: reflowDefaultsKey),
let dictTransformer = ValueTransformer(forName: NSValueTransformerName(rawValue: MASDictionaryTransformerName)),
let shortcut = dictTransformer.transformedValue(shortcutDict) as? MASShortcut
else {
return nil
}
return (shortcut.keyCodeStringForKeyEquivalent, shortcut.modifierFlags)
}

static func isTodoWindow(_ w: AccessibilityElement) -> Bool {
guard let todoWindow = AccessibilityElement.getTodoWindowElement() else { return false }
return isTodoWindow(w, todoWindow: todoWindow)
private static func getTodoWindowElement() -> AccessibilityElement? {
guard let bundleId = Defaults.todoApplication.value, let windowElements = AccessibilityElement(bundleId)?.windowElements else {
todoWindowId = nil
return nil
}
if let windowId = todoWindowId, !(windowElements.contains { $0.windowId == windowId }) {
todoWindowId = nil
}
if todoWindowId == nil {
todoWindowId = windowElements.first?.windowId
}
if let windowId = todoWindowId, let windowElement = (windowElements.first { $0.windowId == windowId }) {
return windowElement
}
todoWindowId = nil
return nil
}

static func isTodoWindow(id: CGWindowID) -> Bool {
AccessibilityElement.getTodoWindowElement()?.getWindowId() == id
static func isTodoWindow(_ windowElement: AccessibilityElement) -> Bool {
guard let windowId = windowElement.windowId else { return false }
return isTodoWindow(windowId)
}

private static func isTodoWindow(_ w: AccessibilityElement, todoWindow: AccessibilityElement) -> Bool {
return w.getWindowId() == todoWindow.getWindowId()
static func isTodoWindow(_ windowId: CGWindowID) -> Bool {
return getTodoWindowElement()?.windowId == windowId
}

static func moveAll(_ bringToFront: Bool = true) {
Expand All @@ -82,7 +138,7 @@ class TodoManager {
// Avoid footprint window
let windows = AccessibilityElement.getAllWindowElements().filter { $0.pid != pid }

if let todoWindow = AccessibilityElement.getTodoWindowElement() {
if let todoWindow = getTodoWindowElement() {
if let screen = TodoManager.todoScreen {
let sd = ScreenDetection()
var adjustedVisibleFrame = screen.adjustedVisibleFrame()
Expand Down Expand Up @@ -120,8 +176,13 @@ class TodoManager {
}
}

static func moveAllIfNeeded(_ bringToFront: Bool = true) {
guard Defaults.todo.userEnabled && Defaults.todoMode.enabled else { return }
moveAll(bringToFront)
}

private static func refreshTodoScreen() {
let todoWindow = AccessibilityElement.getTodoWindowElement()
let todoWindow = getTodoWindowElement()
let screens = ScreenDetection().detectScreens(using: todoWindow)
TodoManager.todoScreen = screens?.currentScreen
}
Expand Down
2 changes: 1 addition & 1 deletion Rectangle/WindowManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class WindowManager {
}
}

let ignoreTodo = TodoManager.isTodoWindow(id: windowId)
let ignoreTodo = TodoManager.isTodoWindow(windowId)

if frontmostWindowElement.isSheet == true
|| currentWindowRect.isNull
Expand Down

0 comments on commit 4dda4fd

Please sign in to comment.