Skip to content

Commit

Permalink
v1.0.16 (#91)
Browse files Browse the repository at this point in the history
* Introducing the usage of custom keybinds set by user to switch windows (#88)

* generate appcast script

* Create draft_release.yml

* Update draft_release.yml

* Update draft_release.yml

* Update draft_release.yml

* Update draft_release.yml

* Update draft_release.yml

* Update draft_release.yml

* Adding Setting pane to toggle window switcher

* Addition of segmented picker

* Initial Segmented Picker implementation

* HotFix: Application was crashing when new user would launch

* fallback assignment

* Enabling usage of custom user keybinds

* Deprecate use of UserDefaults in favor of Defaults

* Remove: draft_release.yml

---------

Co-authored-by: Ethan Bills <ethanjacksonbills@gmail.com>
Co-authored-by: ejbills <74191134+ejbills@users.noreply.github.com>

* fix window view

* fix window title

---------

Co-authored-by: Hasan Sultan <52581466+hasansultan92@users.noreply.github.com>
  • Loading branch information
ejbills and hasansultan92 authored Jul 8, 2024
1 parent 8734678 commit 7c5761e
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 48 deletions.
8 changes: 4 additions & 4 deletions DockDoor.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1.0.15;
CURRENT_PROJECT_VERSION = 1.0.16;
DEVELOPMENT_ASSET_PATHS = "\"DockDoor/Preview Content\"";
DEVELOPMENT_TEAM = 2Q775S63Q3;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -469,7 +469,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.0;
MARKETING_VERSION = 1.0.15;
MARKETING_VERSION = 1.0.16;
PRODUCT_BUNDLE_IDENTIFIER = com.ethanbills.DockDoor;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand All @@ -486,7 +486,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1.0.15;
CURRENT_PROJECT_VERSION = 1.0.16;
DEVELOPMENT_ASSET_PATHS = "\"DockDoor/Preview Content\"";
DEVELOPMENT_TEAM = 2Q775S63Q3;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -501,7 +501,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.0;
MARKETING_VERSION = 1.0.15;
MARKETING_VERSION = 1.0.16;
PRODUCT_BUNDLE_IDENTIFIER = com.ethanbills.DockDoor;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion DockDoor/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
} else {
dockObserver = DockObserver.shared
appClosureObserver = AppClosureObserver.shared
if Defaults[.showWindowSwitcher] {
if Defaults[.enableWindowSwitcher] {
keybindHelper = KeybindHelper.shared
}
}
Expand Down
85 changes: 52 additions & 33 deletions DockDoor/Utilities/KeybindHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,29 @@

import AppKit
import Carbon
import Defaults

struct UserKeyBind: Codable, Defaults.Serializable {
var keyCode: UInt16
var modifierFlags: Int
}

class KeybindHelper {
static let shared = KeybindHelper()

private var isControlKeyPressed = false
private var isModifierKeyPressed = false
private var isShiftKeyPressed = false
private var eventTap: CFMachPort?
private var runLoopSource: CFRunLoopSource?

private var modifierValue: Int = 0

private init() {
setupEventTap()
}

deinit {
removeEventTap()
}

private func setupEventTap() {
let eventMask = (1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.keyUp.rawValue) | (1 << CGEventType.flagsChanged.rawValue)

Expand All @@ -47,7 +53,7 @@ class KeybindHelper {
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
CGEvent.tapEnable(tap: eventTap, enable: true)
}

private func removeEventTap() {
if let eventTap = eventTap, let runLoopSource = runLoopSource {
CGEvent.tapEnable(tap: eventTap, enable: false)
Expand All @@ -56,55 +62,68 @@ class KeybindHelper {
self.runLoopSource = nil
}
}

private func handleEvent(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent) -> Unmanaged<CGEvent>? {
let keyCode = event.getIntegerValueField(.keyboardEventKeycode)
let keyBoardShortcutSaved: UserKeyBind = Defaults[.UserKeybind] // UserDefaults.standard.getKeybind()!
let shiftKeyCurrentlyPressed = event.flags.contains(.maskShift)
var userDefinedKeyCurrentlyPressed = false

switch type {
case .flagsChanged:
let modifierFlags = event.flags
let controlKeyCurrentlyPressed = modifierFlags.contains(.maskControl)
let shiftKeyCurrentlyPressed = modifierFlags.contains(.maskShift)

if controlKeyCurrentlyPressed != isControlKeyPressed {
isControlKeyPressed = controlKeyCurrentlyPressed
}

// Update the state of Shift key
if shiftKeyCurrentlyPressed != isShiftKeyPressed {
isShiftKeyPressed = shiftKeyCurrentlyPressed
if ((type == .flagsChanged) && (!Defaults[.defaultCMDTABKeybind])){
// New Keybind that the user has enforced, includes the modifier keys
if event.flags.contains(.maskControl) {
modifierValue = Defaults[.Int64maskControl]
userDefinedKeyCurrentlyPressed = true
}

if !isControlKeyPressed { // If Ctrl was released
HoverWindow.shared.hideWindow() // Hide the HoverWindow
HoverWindow.shared.selectAndBringToFrontCurrentWindow()
else if event.flags.contains(.maskAlternate) {
modifierValue = Defaults[.Int64maskAlternate]
userDefinedKeyCurrentlyPressed = true
}

case .keyDown:
if isControlKeyPressed && keyCode == 48 { // Tab key
handleModifierEvent(modifierKeyPressed: userDefinedKeyCurrentlyPressed, shiftKeyPressed: shiftKeyCurrentlyPressed)
}

else if ((type == .flagsChanged) && (Defaults[.defaultCMDTABKeybind])){
// Default MacOS CMD + TAB keybind replaced
handleModifierEvent(modifierKeyPressed: event.flags.contains(.maskCommand), shiftKeyPressed: shiftKeyCurrentlyPressed)
}

else if (type == .keyDown){
if (isModifierKeyPressed && keyCode == keyBoardShortcutSaved.keyCode && modifierValue == keyBoardShortcutSaved.modifierFlags) || (Defaults[.defaultCMDTABKeybind] && keyCode == 48) { // Tab key
if HoverWindow.shared.isVisible { // Check if HoverWindow is already shown
HoverWindow.shared.cycleWindows(goBackwards: isShiftKeyPressed) // Cycle windows based on Shift key state
} else {
showHoverWindow() // Initialize HoverWindow if it's not open
}
return nil // Suppress the Tab key event
}

default:
break
}

return Unmanaged.passUnretained(event)
}


private func handleModifierEvent(modifierKeyPressed : Bool, shiftKeyPressed : Bool){
if modifierKeyPressed != isModifierKeyPressed {
isModifierKeyPressed = modifierKeyPressed
}
// Update the state of Shift key
if shiftKeyPressed != isShiftKeyPressed {
isShiftKeyPressed = shiftKeyPressed
}

if !isModifierKeyPressed {
HoverWindow.shared.hideWindow() // Hide the HoverWindow
HoverWindow.shared.selectAndBringToFrontCurrentWindow()
}
}

private func showHoverWindow() {
Task { [weak self] in
do {
guard let self = self else { return }
let windows = try await WindowUtil.activeWindows(for: "")
await MainActor.run { [weak self] in
guard let self = self else { return }
if self.isControlKeyPressed {
if self.isModifierKeyPressed {
HoverWindow.shared.showWindow(appName: "Alt-Tab", windows: windows, overrideDelay: true, onWindowTap: { HoverWindow.shared.hideWindow() })
}
}
Expand Down
65 changes: 65 additions & 0 deletions DockDoor/Utilities/Misc Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Cocoa
import Defaults
import Carbon

func quitApp() {
// Terminate the current application
Expand Down Expand Up @@ -41,3 +42,67 @@ func measureString(_ string: String, fontSize: CGFloat, fontWeight: NSFont.Weigh
let size = attributedString.size()
return size
}

struct modifierConverter {
static func toString(_ modifierIntValue: Int) -> String {
if modifierIntValue == Defaults[.Int64maskCommand] {
return ""
}
else if modifierIntValue == Defaults[.Int64maskAlternate] {
return ""
}
else if modifierIntValue == Defaults[.Int64maskControl] {
return ""
}
else {
return " "
}
}
}

struct KeyCodeConverter {
static func toString(_ keyCode: UInt16) -> String {
switch keyCode {
case 48:
return "" // Tab symbol
case 51:
return "" // Delete symbol
case 53:
return "" // Escape symbol
case 36:
return "↩︎" // Return symbol
default:

let source = TISCopyCurrentKeyboardInputSource().takeUnretainedValue()
let layoutData = TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData)

guard let data = layoutData else {
return "?"
}

let layout = unsafeBitCast(data, to: CFData.self)
let keyboardLayout = unsafeBitCast(CFDataGetBytePtr(layout), to: UnsafePointer<UCKeyboardLayout>.self)

var keysDown: UInt32 = 0
var chars = [UniChar](repeating: 0, count: 4)
var realLength: Int = 0

let result = UCKeyTranslate(keyboardLayout,
keyCode,
UInt16(kUCKeyActionDisplay),
0,
UInt32(LMGetKbdType()),
UInt32(kUCKeyTranslateNoDeadKeysBit),
&keysDown,
chars.count,
&realLength,
&chars)

if result == noErr {
return String(utf16CodeUnits: chars, count: realLength)
} else {
return "?"
}
}
}
}
4 changes: 2 additions & 2 deletions DockDoor/Views/Hover Window/WindowPreview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ struct WindowPreview: View {
let stringMeasurementWidth = measureString(windowTitle, fontSize: 12).width + 5
let width = maxLabelWidth > stringMeasurementWidth ? stringMeasurementWidth : maxLabelWidth

TheMarquee(width: width, secsBeforeLooping: 3, speedPtsPerSec: 20, nonMovingAlignment: .leading) {
TheMarquee(width: width, secsBeforeLooping: 1, speedPtsPerSec: 20, nonMovingAlignment: .leading) {
Text(windowInfo.windowName ?? "Hidden window")
.font(.system(size: 12, weight: .medium))
.foregroundStyle(.primary)
}
.padding(4)
.dockStyle(cornerRadius: 6)
.background(RoundedRectangle(cornerRadius: 6, style: .continuous).fill(.ultraThinMaterial))
.padding(4)
}
}
Expand Down
Loading

0 comments on commit 7c5761e

Please sign in to comment.