fix: show windows of apps launched hidden (#390)
This commit is contained in:
1 parent
4003df41e1
commit
eb5d0196ba
2 files changed
+39
-22
No files matched your search
@@ -9,6 +9,7 @@ class Application: NSObject {
|
|||||||
var axObserver: AXObserver?
|
var axObserver: AXObserver?
|
||||||
var isReallyFinishedLaunching = false
|
var isReallyFinishedLaunching = false
|
||||||
var isHidden: Bool!
|
var isHidden: Bool!
|
||||||
|
var hasBeenActiveOnce: Bool!
|
||||||
var icon: NSImage?
|
var icon: NSImage?
|
||||||
var dockLabel: String?
|
var dockLabel: String?
|
||||||
var pid: pid_t { runningApplication.processIdentifier }
|
var pid: pid_t { runningApplication.processIdentifier }
|
||||||
@@ -39,6 +40,7 @@ class Application: NSObject {
|
|||||||
self.runningApplication = runningApplication
|
self.runningApplication = runningApplication
|
||||||
super.init()
|
super.init()
|
||||||
isHidden = runningApplication.isHidden
|
isHidden = runningApplication.isHidden
|
||||||
|
hasBeenActiveOnce = runningApplication.isActive
|
||||||
icon = runningApplication.icon
|
icon = runningApplication.icon
|
||||||
addAndObserveWindows()
|
addAndObserveWindows()
|
||||||
kvObservers = [
|
kvObservers = [
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ fileprivate func handleEvent(_ type: String, _ element: AXUIElement) throws {
|
|||||||
debugPrint("Accessibility event", type, type != kAXFocusedUIElementChangedNotification ? (try element.title() ?? "nil") : "nil")
|
debugPrint("Accessibility event", type, type != kAXFocusedUIElementChangedNotification ? (try element.title() ?? "nil") : "nil")
|
||||||
// events are handled concurrently, thus we check that the app is still running
|
// events are handled concurrently, thus we check that the app is still running
|
||||||
if let pid = try element.pid(),
|
if let pid = try element.pid(),
|
||||||
try (!(type == kAXWindowCreatedNotification && pid == ProcessInfo.processInfo.processIdentifier && element.subrole() == kAXUnknownSubrole)) {
|
try (!(pid == ProcessInfo.processInfo.processIdentifier && element.subrole() == kAXUnknownSubrole)) {
|
||||||
switch type {
|
switch type {
|
||||||
case kAXApplicationActivatedNotification: try applicationActivated(element)
|
case kAXApplicationActivatedNotification: try applicationActivated(element, pid)
|
||||||
case kAXApplicationHiddenNotification,
|
case kAXApplicationHiddenNotification,
|
||||||
kAXApplicationShownNotification: try applicationHiddenOrShown(element, pid, type)
|
kAXApplicationShownNotification: try applicationHiddenOrShown(element, pid, type)
|
||||||
case kAXWindowCreatedNotification: try windowCreated(element, pid)
|
case kAXWindowCreatedNotification: try windowCreated(element, pid)
|
||||||
@@ -54,10 +54,13 @@ fileprivate func updateTabs(_ pid: pid_t, _ currentWindows: [AXUIElement]?) -> [
|
|||||||
return windows
|
return windows
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func applicationActivated(_ element: AXUIElement) throws {
|
fileprivate func applicationActivated(_ element: AXUIElement, _ pid: pid_t) throws {
|
||||||
if let appFocusedWindow = try element.focusedWindow(),
|
if let appFocusedWindow = try element.focusedWindow(),
|
||||||
let wid = try appFocusedWindow.cgWindowId() {
|
let wid = try appFocusedWindow.cgWindowId() {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
if let app = (Applications.list.first { $0.pid == pid }), !app.hasBeenActiveOnce {
|
||||||
|
app.hasBeenActiveOnce = true
|
||||||
|
}
|
||||||
// ensure alt-tab window remains key, so local shortcuts work
|
// ensure alt-tab window remains key, so local shortcuts work
|
||||||
if App.app.appIsBeingUsed { App.app.thumbnailsPanel.makeKeyAndOrderFront(nil) }
|
if App.app.appIsBeingUsed { App.app.thumbnailsPanel.makeKeyAndOrderFront(nil) }
|
||||||
if let window = Windows.updateLastFocus(appFocusedWindow, wid) {
|
if let window = Windows.updateLastFocus(appFocusedWindow, wid) {
|
||||||
@@ -107,26 +110,38 @@ fileprivate func windowCreated(_ element: AXUIElement, _ pid: pid_t) throws {
|
|||||||
|
|
||||||
fileprivate func focusedWindowChanged(_ element: AXUIElement, _ pid: pid_t) throws {
|
fileprivate func focusedWindowChanged(_ element: AXUIElement, _ pid: pid_t) throws {
|
||||||
if let wid = try element.cgWindowId(),
|
if let wid = try element.cgWindowId(),
|
||||||
let runningApp = NSRunningApplication(processIdentifier: pid),
|
let runningApp = NSRunningApplication(processIdentifier: pid) {
|
||||||
// photoshop will focus a window *after* you focus another app
|
// photoshop will focus a window *after* you focus another app
|
||||||
// we check that a focused window happens within an active app
|
// we check that a focused window happens within an active app
|
||||||
runningApp.isActive {
|
if runningApp.isActive {
|
||||||
let axTitle = try element.title()
|
let axTitle = try element.title()
|
||||||
let subrole = try element.subrole()
|
let subrole = try element.subrole()
|
||||||
let role = try element.role()
|
let role = try element.role()
|
||||||
let isFullscreen = try element.isFullscreen()
|
let isFullscreen = try element.isFullscreen()
|
||||||
let isMinimized = try element.isMinimized()
|
let isMinimized = try element.isMinimized()
|
||||||
let level = try wid.level()
|
let level = try wid.level()
|
||||||
let position = try element.position()
|
let position = try element.position()
|
||||||
let size = try element.size()
|
let size = try element.size()
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if let windows = Windows.updateLastFocus(element, wid) {
|
if let windows = Windows.updateLastFocus(element, wid) {
|
||||||
App.app.refreshOpenUi(windows)
|
App.app.refreshOpenUi(windows)
|
||||||
} else if element.isActualWindow(runningApp, wid, level, axTitle, subrole, role, size),
|
} else if element.isActualWindow(runningApp, wid, level, axTitle, subrole, role, size),
|
||||||
let app = (Applications.list.first { $0.pid == pid }) {
|
let app = (Applications.list.first { $0.pid == pid }) {
|
||||||
let window = Window(element, app, wid, axTitle, isFullscreen, isMinimized, position, size)
|
let window = Window(element, app, wid, axTitle, isFullscreen, isMinimized, position, size)
|
||||||
Windows.appendAndUpdateFocus(window)
|
Windows.appendAndUpdateFocus(window)
|
||||||
App.app.refreshOpenUi([window])
|
App.app.refreshOpenUi([window])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
if let app = (Applications.list.first { $0.pid == pid }) {
|
||||||
|
// work-around for apps started "hidden" like in Login Items with the "Hide" checkbox, or with `open -j`
|
||||||
|
// these apps report isHidden=false, don't generate windowCreated events initially, and have a delay before their windows are created
|
||||||
|
// our only recourse is to manually check their windows once they emit
|
||||||
|
if (!app.hasBeenActiveOnce) {
|
||||||
|
app.observeNewWindows()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user