Hammerspoon / hammerspoon

Staggeringly powerful macOS desktop automation with Lua
http://www.hammerspoon.org
MIT License
12.06k stars 583 forks source link

`hs.window.filter.new(true)` return two windows with same `id` and doesn't catch some events, if the window has been opened by command `open -n -a someapp` #3235

Open K4tsuki opened 2 years ago

K4tsuki commented 2 years ago

Test code:

filter = hs.window.filter.new(true)
filter:subscribe({
  [winfilter.windowMoved] = function(win, appname, eventname) 
    print('moved')
    print("win => ", win:id())
    print("title => ", win:title())
  end,
  [winfilter.windowFocused] = function(win, appname, eventname) 
    print("focused")
    print("win => ", win:id())
    print("title => ", win:title())
  end

Then launch IINA or other applications from dock, then run command open -n -a "/Applications/IINA.app"

The windowFocused handler is executed for both windows, but the windowMoved handler isn't executed for window opened by open -n -a command.

Other note: I think hs.window.allWindows() return the expected window id.

kjslag commented 2 years ago

I'm also noticing that hs.window.switcher doesn't see windows created from open -n -a someapp. Is that the same bug or a different bug?

K4tsuki commented 2 years ago

In hs.window.switcher example, it uses hs.window.filter, so I think it is affected.

If I am not wrong, the hs.window.filter problem is because of it catch all running application based on appname. If the command open -n -a is invoked then this line:

https://github.com/Hammerspoon/hammerspoon/blob/7f34baab0488bb1cd9ce1b248ffa0690611526ec/extensions/window/window_filter.lua#L1412

will be executed and will early return without making new application watcher.

dmgerman commented 1 year ago

Looking at the source code, it looks like the name of the app is used as a key to many tables in the hs.window.filter data structures and a rewrite might be needed to fix these issues.

So if you have another app running with the same name, then hammerspoon does not consider them to be different apps.

I think the easiest way to work around this problem is to create a copy of the app and renaming the app (changing the name of the app in the InfoPlist.strings in the bundle) to a unique name.