Fixes#2462
This sets up a listener for screen parameter changes. This only triggers
when a screen is added, removed, or a parameter such as its resolution
changes. This doesn't trigger when a window is simply moved from one
screen to another.
On parameter change, we ensure that the window is within the bounds of
the screen. As an exception, if the window was previously already
outside the bounds of the screen, we don't move it back in.
Rather than storing a list of errors we now store a list of
"diagnostics." Each diagnostic has a richer set of structured
information, including a message, a key, the location where it occurred.
This lets us show more detailed messages, more human friendly messages, and
also let's us filter by key or location. We don't take advantage of
all of this capability in this initial commit, but we do use every field
for something.
Fixes#2409
This is one of the weirder macOS quirks (bugs? who knows!) I've seen
recently. The bug as described in #2409: when you have at least two
monitors ("screens" in AppKit parlance), Ghostty on one, a focused app
on the other, and you toggle the quick terminal, the quick terminal
does not have focus.
We already knew and accounted for the fact that
`window.makeKeyAndOrderFront(nil)` does not work until the window is visible
and on the target screen. To do this, we only called this once the
animation was complete. For the same NSScreen, this works, but for
another screen, it does not.
Using one DispatchQueue.async tick also does not work. Based on testing,
it takes anywhere from 2 to 5 ticks to get the window focus API to work
properly. Okay.
The solution I came up with here is to retry the focus operation every
25ms up to 250ms. This has worked consistently for me within the first 5
ticks but it is obviously a hack so I'm not sure if this is all right.
This fixes the issue but if there's a better way to do this, I'm all
ears!
macOS 12 is officially EOL by Apple and the project only supports
officially supported versions of macOS. Once publicly released, users on
older macOS versions will have to use older released builds.
This was recently introduced a few days ago. Unfortunately, this doesn't
work as expected. The "function" modifier is not actually the fn key
but used by macOS to represent a variety of "functional" key presses.
This breaks other bindings such as #2411.
I can't find a source on the internet that reliably tells me how we
can detect fn key presses, but I do find a number of sources that tell
us we can't.
Fixes#2370
Comparing NSScreens directly was fragile. It appears that AppKit/Cocoa
can return different instances of NSScreen for the same screen for
unknown reasons between calls to windowDidChangeScreen. I don't fully
understand why this happens.
In any case, our comparison was not safe. Instad, we now keep track of
of the CGDirectDisplayID for each screen and compare those instead.