fix: sometimes moved cursor on focus wrong (closes #1087)
This commit is contained in:
1 parent
26e2375bfb
commit
ed102015ad
7 files changed
+65
-11
No files matched your search
@@ -90,6 +90,7 @@ They helped [localize the app](https://poeditor.com/join/project/8AOEZ0eAZE):
|
||||
* Martin Mitka
|
||||
* Martin. mitka
|
||||
* Max
|
||||
* MaximilianFreitag
|
||||
* Michael
|
||||
* Mohammad Al Zouabi
|
||||
* Mr. axel. bock
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
"Minimized windows:" = "Minimierte Fenster:";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Miscellaneous:" = "Miscellaneous:";
|
||||
"Miscellaneous:" = "Sonstiges";
|
||||
|
||||
/*No comment provided by engineer.*/
|
||||
"Mouse hover" = "Maus hover";
|
||||
|
||||
@@ -170,7 +170,7 @@ extension pid_t {
|
||||
return kinfo.kp_proc.p_stat == SZOMB
|
||||
}
|
||||
|
||||
// the algorithm used by updateTabs is incorrect is the screen is in the middle of an animation (e.g. window going fullscreen)
|
||||
// the algorithm used by updateTabs is incorrect if the screen is in the middle of an animation (e.g. window going fullscreen)
|
||||
// we retry until there is no animation, then we proceed
|
||||
func retryToRefreshTabsUntilScreenIsNotAnimating(_ fn: @escaping ([Window]) -> Void) {
|
||||
if NSRunningApplication(processIdentifier: self) != nil,
|
||||
|
||||
@@ -402,3 +402,43 @@ func SLSManagedDisplayIsAnimating(_ cid: CGSConnectionID, _ displayUuid: CFStrin
|
||||
// CGSGetConnectionPSN(elementConnection, &psn)
|
||||
// return psn
|
||||
//}
|
||||
//
|
||||
//
|
||||
//// the following functions can be used to handle child-windows
|
||||
//// see https://developer.apple.com/documentation/appkit/nswindow/1419236-childwindows
|
||||
//// example of usage:
|
||||
//// var windowList = [] as CFArray
|
||||
//// var windowCount = 10 as UInt
|
||||
//// CGSCopyWindowGroup(cgsMainConnectionId, wid, "movementGroup" as CFString, &windowList, &windowCount)
|
||||
//// let wins = SLSCopyAssociatedWindows(cgsMainConnectionId, try currentWindows![0].cgWindowId()!)
|
||||
//// let query = SLSWindowQueryWindows(cgsMainConnectionId, [try currentWindows![0].cgWindowId()!] as CFArray, 1)
|
||||
//// let iterator = SLSWindowQueryResultCopyWindows(query)
|
||||
//// while SLSWindowIteratorAdvance(iterator) == .success {
|
||||
//// let parent_wid = SLSWindowIteratorGetParentID(iterator)
|
||||
//// let wid = SLSWindowIteratorGetWindowID(iterator)
|
||||
//// let tags = SLSWindowIteratorGetTags(iterator)
|
||||
//// }
|
||||
//
|
||||
//@_silgen_name("CGSCopyWindowGroup")
|
||||
//func CGSCopyWindowGroup(_ cid: CGSConnectionID, _ wid: CGWindowID, _ groupType: CFString, _ windowList: inout CFArray, _ windowCount: inout UInt) -> Void
|
||||
//
|
||||
//@_silgen_name("SLSCopyAssociatedWindows")
|
||||
//func SLSCopyAssociatedWindows(_ cid: CGSConnectionID, _ wid: CGWindowID) -> CFArray
|
||||
//
|
||||
//@_silgen_name("SLSWindowQueryWindows")
|
||||
//func SLSWindowQueryWindows(_ cid: CGSConnectionID, _ wids: CFArray, _ windowsCount: UInt) -> CFTypeRef
|
||||
//
|
||||
//@_silgen_name("SLSWindowQueryResultCopyWindows")
|
||||
//func SLSWindowQueryResultCopyWindows(_ query: CFTypeRef) -> CFTypeRef
|
||||
//
|
||||
//@_silgen_name("SLSWindowIteratorAdvance")
|
||||
//func SLSWindowIteratorAdvance(_ iterator: CFTypeRef) -> CGError
|
||||
//
|
||||
//@_silgen_name("SLSWindowIteratorGetParentID")
|
||||
//func SLSWindowIteratorGetParentID(_ iterator: CFTypeRef) -> CGWindowID
|
||||
//
|
||||
//@_silgen_name("SLSWindowIteratorGetWindowID")
|
||||
//func SLSWindowIteratorGetWindowID(_ iterator: CFTypeRef) -> CGWindowID
|
||||
//
|
||||
//@_silgen_name("SLSWindowIteratorGetTags")
|
||||
//func SLSWindowIteratorGetTags(_ iterator: CFTypeRef) -> UInt
|
||||
+10
-1
@@ -221,7 +221,8 @@ class Window {
|
||||
return screenSpaces.contains { $0 == spaceId }
|
||||
}
|
||||
} else {
|
||||
if let topLeftCorner = position, let size = size {
|
||||
let referenceWindow = referenceWindowForTabbedWindow()
|
||||
if let topLeftCorner = referenceWindow?.position, let size = referenceWindow?.size {
|
||||
var screenFrameInQuartzCoordinates = screen.frame
|
||||
screenFrameInQuartzCoordinates.origin.y = NSMaxY(NSScreen.screens[0].frame) - NSMaxY(screen.frame)
|
||||
let windowRect = CGRect(origin: topLeftCorner, size: size)
|
||||
@@ -230,5 +231,13 @@ class Window {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func referenceWindowForTabbedWindow() -> Window? {
|
||||
// if the window is tabbed, we can't know its position/size before it's focused, so we use the currently
|
||||
// visible window-tab to decide where to put the cursor, as these are known and will match the other tab
|
||||
// TODO: handle the case where the app has multiple window-groups. In that case, we need to find the right
|
||||
// window-group, instead of picking the focused one
|
||||
return isTabbed ? application.focusedWindow : self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,10 @@ fileprivate func handleEvent(_ type: String, _ element: AXUIElement) throws {
|
||||
}
|
||||
|
||||
fileprivate func focusedUiElementChanged(_ pid: pid_t) throws {
|
||||
// this event is the only event triggered when the user tabs a window. However, macOS implementation is lazy: a
|
||||
// window freshly tabbed will still return the size/position/screenshot as when it was still a standalone
|
||||
// window. Only when the user clicks on the tab, and it gets displayed, will the tabbed window actually resize
|
||||
// (it will send the windowResized event)
|
||||
pid.retryToRefreshTabsUntilScreenIsNotAnimating { App.app.refreshOpenUi($0) }
|
||||
}
|
||||
|
||||
@@ -187,11 +191,15 @@ fileprivate func windowTitleChanged(_ element: AXUIElement, _ pid: pid_t) throws
|
||||
|
||||
fileprivate func windowResized(_ element: AXUIElement) throws {
|
||||
// TODO: only trigger this at the end of the resize, not on every tick
|
||||
// currenly resizing a window will lag AltTab as it triggers too much UI work
|
||||
// currently resizing a window will lag AltTab as it triggers too much UI work
|
||||
if let wid = try element.cgWindowId() {
|
||||
let isFullscreen = try element.isFullscreen()
|
||||
let size = try element.size()
|
||||
let position = try element.position()
|
||||
DispatchQueue.main.async {
|
||||
if let window = (Windows.list.first { $0.isEqualRobust(element, wid) }) {
|
||||
window.size = size
|
||||
window.position = position
|
||||
if window.isFullscreen != isFullscreen {
|
||||
window.isFullscreen = isFullscreen
|
||||
App.app.checkIfShortcutsShouldBeDisabled(window, nil)
|
||||
|
||||
+3
-7
@@ -199,13 +199,9 @@ class App: AppCenterApplication, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
func moveCursorToSelectedWindow(_ window: Window) {
|
||||
guard let position = window.position, let size = window.size else { return }
|
||||
|
||||
let point = CGPoint(
|
||||
x: position.x + size.width / 2,
|
||||
y: position.y + size.height / 2
|
||||
)
|
||||
|
||||
let referenceWindow = window.referenceWindowForTabbedWindow()
|
||||
guard let position = referenceWindow?.position, let size = referenceWindow?.size else { return }
|
||||
let point = CGPoint(x: position.x + size.width / 2, y: position.y + size.height / 2)
|
||||
CGWarpMouseCursorPosition(point)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user