fix: focusing alt-tab own windows with alt-tab had jank (closes #501)
This commit is contained in:
1 parent
30625662a2
commit
c927920070
5 files changed
+40
-25
No files matched your search
+16
-12
@@ -136,18 +136,22 @@ class Window {
|
||||
}
|
||||
|
||||
func focus() {
|
||||
// macOS bug: when switching to a System Preferences window in another space, it switches to that space,
|
||||
// but quickly switches back to another window in that space
|
||||
// You can reproduce this buggy behaviour by clicking on the dock icon, proving it's an OS bug
|
||||
BackgroundWork.accessibilityCommandsQueue.asyncWithCap { [weak self] in
|
||||
guard let self = self else { return }
|
||||
var elementConnection = UInt32(0)
|
||||
CGSGetWindowOwner(cgsMainConnectionId, self.cgWindowId, &elementConnection)
|
||||
var psn = ProcessSerialNumber()
|
||||
CGSGetConnectionPSN(elementConnection, &psn)
|
||||
_SLPSSetFrontProcessWithOptions(&psn, self.cgWindowId, .userGenerated)
|
||||
self.makeKeyWindow(psn)
|
||||
self.axUiElement.focusWindow()
|
||||
if application.runningApplication.processIdentifier == ProcessInfo.processInfo.processIdentifier {
|
||||
App.app.showSecondaryWindow(App.app.window(withWindowNumber: Int(cgWindowId)))
|
||||
} else {
|
||||
// macOS bug: when switching to a System Preferences window in another space, it switches to that space,
|
||||
// but quickly switches back to another window in that space
|
||||
// You can reproduce this buggy behaviour by clicking on the dock icon, proving it's an OS bug
|
||||
BackgroundWork.accessibilityCommandsQueue.asyncWithCap { [weak self] in
|
||||
guard let self = self else { return }
|
||||
var elementConnection = UInt32(0)
|
||||
CGSGetWindowOwner(cgsMainConnectionId, self.cgWindowId, &elementConnection)
|
||||
var psn = ProcessSerialNumber()
|
||||
CGSGetConnectionPSN(elementConnection, &psn)
|
||||
_SLPSSetFrontProcessWithOptions(&psn, self.cgWindowId, .userGenerated)
|
||||
self.makeKeyWindow(psn)
|
||||
self.axUiElement.focusWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,9 +123,7 @@ private func windowCreated(_ element: AXUIElement, _ pid: pid_t) throws {
|
||||
}
|
||||
|
||||
private func focusedWindowChanged(_ element: AXUIElement, _ pid: pid_t) throws {
|
||||
if let wid = try element.cgWindowId(),
|
||||
pid != ProcessInfo.processInfo.processIdentifier ||
|
||||
(App.app.preferencesWindow.isKeyWindow || App.app.feedbackWindow?.isKeyWindow ?? false) {
|
||||
if let wid = try element.cgWindowId() {
|
||||
let axTitle = try element.title()
|
||||
let subrole = try element.subrole()
|
||||
let role = try element.role()
|
||||
|
||||
+19
-10
@@ -14,7 +14,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
static var app: App!
|
||||
var thumbnailsPanel: ThumbnailsPanel!
|
||||
var preferencesWindow: PreferencesWindow!
|
||||
var feedbackWindow: FeedbackWindow?
|
||||
var feedbackWindow: FeedbackWindow!
|
||||
var isFirstSummon = true
|
||||
var appIsBeingUsed = false
|
||||
var shortcutsShouldBeDisabled = false
|
||||
@@ -51,6 +51,7 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
Spaces.initialDiscovery()
|
||||
Applications.initialDiscovery()
|
||||
self.preferencesWindow = PreferencesWindow()
|
||||
self.feedbackWindow = FeedbackWindow()
|
||||
KeyboardEvents.observe()
|
||||
MouseEvents.observe()
|
||||
// TODO: undeterministic; events in the queue may still be processing; good enough for now
|
||||
@@ -107,7 +108,16 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
appIsBeingUsed = false
|
||||
isFirstSummon = true
|
||||
MouseEvents.toggle(false)
|
||||
hideThumbnailPanelWithoutChangingKeyWindow()
|
||||
}
|
||||
|
||||
// we don't want another window to become key when the thumbnailPanel is hidden
|
||||
func hideThumbnailPanelWithoutChangingKeyWindow() {
|
||||
preferencesWindow.canBecomeKey_ = false
|
||||
feedbackWindow.canBecomeKey_ = false
|
||||
thumbnailsPanel.orderOut(nil)
|
||||
preferencesWindow.canBecomeKey_ = true
|
||||
feedbackWindow.canBecomeKey_ = true
|
||||
}
|
||||
|
||||
func closeSelectedWindow() {
|
||||
@@ -136,19 +146,18 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
@objc func showFeedbackPanel() {
|
||||
if feedbackWindow == nil {
|
||||
feedbackWindow = FeedbackWindow()
|
||||
}
|
||||
Screen.repositionPanel(feedbackWindow!, Screen.preferred(), .appleCentered)
|
||||
App.shared.activate(ignoringOtherApps: true)
|
||||
feedbackWindow!.makeKeyAndOrderFront(nil)
|
||||
showSecondaryWindow(feedbackWindow)
|
||||
}
|
||||
|
||||
@objc func showPreferencesWindow() {
|
||||
if let preferencesWindow = preferencesWindow {
|
||||
Screen.repositionPanel(preferencesWindow, Screen.preferred(), .appleCentered)
|
||||
showSecondaryWindow(preferencesWindow)
|
||||
}
|
||||
|
||||
func showSecondaryWindow(_ window: NSWindow?) {
|
||||
if let window = window {
|
||||
Screen.repositionPanel(window, Screen.preferred(), .appleCentered)
|
||||
App.shared.activate(ignoringOtherApps: true)
|
||||
preferencesWindow.makeKeyAndOrderFront(nil)
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ class FeedbackWindow: NSWindow {
|
||||
var email: TextArea!
|
||||
var sendButton: NSButton!
|
||||
var debugProfile: NSButton!
|
||||
var canBecomeKey_ = true
|
||||
override var canBecomeKey: Bool { canBecomeKey_ }
|
||||
|
||||
override init(contentRect: NSRect, styleMask style: StyleMask, backing backingStoreType: BackingStoreType, defer flag: Bool) {
|
||||
super.init(contentRect: .zero, styleMask: style, backing: backingStoreType, defer: flag)
|
||||
|
||||
@@ -2,6 +2,8 @@ import Cocoa
|
||||
|
||||
class PreferencesWindow: NSWindow, NSToolbarDelegate {
|
||||
var toolbarItems = [NSToolbarItem.Identifier: (Int, NSToolbarItem, NSView)]()
|
||||
var canBecomeKey_ = true
|
||||
override var canBecomeKey: Bool { canBecomeKey_ }
|
||||
|
||||
override init(contentRect: NSRect, styleMask style: StyleMask, backing backingStoreType: BackingStoreType, defer flag: Bool) {
|
||||
super.init(contentRect: .zero, styleMask: style, backing: backingStoreType, defer: flag)
|
||||
|
||||
Reference in new issue
Block a user