This fixes two things:
1. Issue #294: cascade point for new windows is set when creating new tabs
2. Cascade point was *not* reset when closing windows, which lead to a
big "gap" appearing when, say, opening 5 windows, closing 4, opening
a new window.
This reverts commit c139279d479682c17f63d9b57c2d56608d09d16a, reversing
changes made to 4ed21047a734d7c586debe0026e3b6ea90ed1622.
We do want to do this but this broke bindings.
This menu got list in #215 and with it we lost the ability to use the
macOS emoji picker via the `Cmd+Ctrl Space` shortcut, for example.
This adds a standard Edit menu back to the main menu.
Previously, this would crash. Once the crash was fixed, it would hang
because we would only show confirmation if the terminal window had
focus.
This introduces some medium complexity logic to work around this:
1. If we are the key window, then show the confirmation dialog. Done.
2. Otherwise, if any other window is a terminal window and is key,
they're going to take it so we do nothing.
3. Otherwise, if we are the first terminal window in the application
windows list, we show it even if we're not focused.
This adds support for what's commonly referred to as "non-native
fullscreen": a fullscreen-mode that doesn't use macOS' native fullscreen
mechanism and thus doesn't use animations and a separate space on which
to display the fullscreen window. Instead it's really fast and it allows
the user to `Cmd+tab` to other windows, with the fullscreen-ed window
staying in the background.
Another name for it is "traditional fullscreen" since it was the default
pre Mac OS X Lion, if I remember correctly.
Other applications that offer macOS non-native fullscreen:
- Kitty: https://sw.kovidgoyal.net/kitty/conf/#opt-kitty.macos_traditional_fullscreen
- wezterm: https://wezfurlong.org/wezterm/config/lua/config/native_macos_fullscreen_mode.html
- MacVim
- IINA: fc66b27d50/iina/MainWindowController.swift (L1401-L1423)
- mpv: https://mpv.io/manual/stable/#options-native-fs
- iTerm2
Adding this wasn't straightforward, as it turned out. Mainly because
SwiftUI's app lifecycle management doesn't allow one to use a custom
class for the windows it creates. And without custom classes we'd always
get a warning when entering/leaving fullscreen mode.
So what I did here is the following:
- remove SwiftUI app lifecycle management
- introduce `MainMenu.xib` to define the main menu via interface builder
- add `GhosttyAppController` to handle requests from the app
- add a `main.swift` file to boot up the app without a storyboard and
without SwiftUI lifecycle management
- introduce the `FullScreenHandler` to manage non-native fullscreen -
this is where the "magic" is
But since removing the SwiftUI lifecycle management also means removing
the top-level `App` that means I had to introduce the menu (which I
mentioned), but also tab and window management.
So I also added the `WindowService` which manages open tabs and windows.
It's based on the ideas presented in
https://christiantietze.de/posts/2019/07/nswindow-tabbing-multiple-nswindowcontroller/
and essentially keeps tracks of windows.
Then there's some auxilliary changes: `CustomWindow` and `WindowController` and so on.
Now everything still works, in addition to non-native fullscreen:
* opening/closing of tabs
* opening/closing of windows
* splits
* `gotoTab`
Worthy of note: when toggling back from non-native fullscreen to
non-fullscreen I had to manually implement the logic to re-add the
window back to a tabgroup. The only other app that supports tabs with
non-native FS is iTerm2 and they have implemented their own tab
management to keep the tab bar even in non-native FS -- that's a bit too
much for me. Every other app has non-native apps and doesn't have to
wory about it.
This fixes or at least is the first step towards #171:
- it adds `cmd/super + return` as the default keybinding to toggle
fullscreen for currently focused window.
- it adds a keybinding handler to the embedded apprt and then changes
the macOS app to handle the keybinding by toggling currently focused
window.
This is my attempt at fixing #63. It works! But:
1. The `NotificationCenter` subscription is triggered once for every
open tab. That's obviously wrong. But I'm not sure and could use some
pointers where else to put the subscription. That leads me to...
2. I'm _not_ knowledgable in Swift/AppKit/SwiftUI, so I might have put
the wrong/right things in the wrong/right places. For example: wasn't
sure what's to be handled in Swift and what's to be handled by the
core in Zig.
Would love some pointers :)
This is, as it turns out, the simple version of #166.
It changes the quit dialog to handle return by removing the
`.destructive` role from the `Quit` button.
When that role is set, the `keyboardShortcut(.defaultAction)` doesn't have an effect.
With the role removed, the dialog handles the return key to quit the
application
As I wrote in #166, I can understand if you don't want this change, but
I personally think it's nice to be able to only use the keyboard. iTerm2
also handles return like this in the "Are you sure?" dialog.
When making a split, the window focus doesn't change so the new splits
were defaulting to "false" (not focused). Let's just assume when a
surface is created that it is in fact focused. This generally fixes the
issue.
If we ever programmatically create splits in background windows this
will probably fail so we should find a way on View init to detect if the
window has focus.