83 Commits

Author SHA1 Message Date
Qwerasd
308f8cce36 macOS: center window title when titlebar tabs enabled
Uses a custom toolbar that populates itself with a centered text field and provides a method to set the text.
2024-01-31 16:16:41 -05:00
Mitchell Hashimoto
1a3d2d151e macos: fix tabs vs spaces 2024-01-31 12:06:58 -08:00
Mitchell Hashimoto
fbac2d9810 macos: titlebar tab logic shuffling 2024-01-31 10:08:05 -08:00
Qwerasd
dacbdf3f38 fix(macOS): set titlebar background color to support transparent windows with titlebar tabs 2024-01-31 07:58:31 -05:00
Qwerasd
ba16d65d02 macOS: Added titlebar tabs 2024-01-30 18:48:36 -05:00
Mitchell Hashimoto
fa0ba0a354 macos: terminals with custom commands are not restorable
Fixes #1317
2024-01-17 08:26:48 -08:00
Mitchell Hashimoto
875a774d4b macos: remove AppState and unify onto Ghostty.App cross-platform 2024-01-14 19:35:57 -08:00
Mitchell Hashimoto
eba3d5414d macos: Ghostty.Config to store all config-related operations 2024-01-14 15:53:33 -08:00
Thorsten Ball
2bf8dac864 macos: use switch statement instead of if-let 2024-01-13 08:32:50 +01:00
Thorsten Ball
90427a8d22 macos: respect window-new-tab-position configuration 2024-01-12 20:22:53 +01:00
Mitchell Hashimoto
8b0d4312ee macos: invalidate restorable state whenever a terminal window is closed 2024-01-10 21:28:49 -08:00
Mitchell Hashimoto
837b551a92 macos: invalid restorable state whenever surface tree changes
Related to #1177

This detects whenever the surface tree (splits) change in any way and
requests that the restorable state be invalided by macOS.
2024-01-10 21:24:47 -08:00
Mitchell Hashimoto
88c525d593 macos: minor style changes 2024-01-10 09:37:36 -08:00
Thorsten Ball
3e811dad2c macos: stop windows glitching when cascading
Noticed that windows glitch when cascading: they show up in center of
screen, then quickly move to the correct position at last-cascade point.

This fixes the issue, by moving the `showWindow` call to _after_ the
setting of the last cascade point.

Now if you look at the code and think: "shouldn't this work without the
async-dispatch, like this?"

```swift
if (!window.styleMask.contains(.fullScreen)) {
    Self.lastCascadePoint = window.cascadeTopLeft(from: Self.lastCascadePoint)
}
c.showWindow(self)
```

Then, yes, I had the same thought, but it doesn't. And as discussed on
Discord, we probably don't know what's going on behind the scenes.

So this is the simplified code of the version we have to live with:
async dispatching the cascade and non-cascade versions both.
2024-01-10 18:28:19 +01:00
Mitchell Hashimoto
44544f29b2 macos: support Display P3 colorspace through configuration
Fixes #1214

This introduces the `window-colorspace` configuration which allows
configuring the colorspace to use for windows on macOS. The default is
sRGB (same as before) but this can also be set to `display-p3`.
2024-01-09 20:47:07 -08:00
Vivek Roy
3aad646be2 macos: Address window spawning and ordering issues from service. 2024-01-06 00:35:34 +05:30
Mitchell Hashimoto
9bf13c6236 macos: set initial window size in controller window init
Fixes #1227
Fixes #1206

This moves the logic that respects `window-width` and `window-height` to
the controller window initialization. This is where it should've been
all the time but we previously didn't use a controller architecture so
we did our best to use heuristics in the view to do this.

This location now ensures that this only happens on window
initialization and only if we have one surface.
2024-01-05 09:42:50 -08:00
Mitchell Hashimoto
f93c41669e macos: order main window front on restore 2024-01-03 12:10:52 -08:00
Mitchell Hashimoto
c9ff034b62 macos: prevent super hot loop to restore focus state 2024-01-03 12:07:03 -08:00
Mitchell Hashimoto
0008fb0a27 macos: set surface tree on init in restore
This prevents an unnecessary SurfaceView from being created. Creating a
SurfaceView is very expensive because this starts multiple threads,
creates the pty, starts the pty process, etc.

Additionally, this was exposing what I believe to be #497 when restoring
state: a surface view was created and destroyed very quickly causing
hangs on some machines. This still needs to be resolved but the behavior
in this commit was still a bug anyways.
2023-12-27 20:12:46 -08:00
Mitchell Hashimoto
2aa7f12417 macos: increment restorable state version 2023-12-26 14:45:39 -08:00
Mitchell Hashimoto
98041940f0 macos: restore focused split on app restore 2023-12-26 14:45:27 -08:00
Mitchell Hashimoto
a321ef515d macos: assign unique UUID per surface, store in app state 2023-12-26 14:24:05 -08:00
Mitchell Hashimoto
20f9a3baab macos: reset state version to 1 2023-12-23 18:59:19 -08:00
Mitchell Hashimoto
2390668834 macos: encode surface tree in state restore 2023-12-23 13:15:46 -08:00
Mitchell Hashimoto
a5d249eb48 config: if window-save-state is never, never restore state 2023-12-22 22:00:25 -08:00
Mitchell Hashimoto
59f54a1d88 macos: initial window save/restore is working for frames only 2023-12-22 21:24:27 -08:00
Mitchell Hashimoto
97433d3aa1 macos: close all windows
Fixes #1052

This implements a `close_all_windows` binding in the core and implements
it for macOS specifically. This will ask for close confirmation if any
surface in any of the windows requires confirmation.

This is bound by default to option+shift+command+w to match Safari. The
binding is generall option+command+w but users may expect this to also
mean "Close All Other Tabs" which is the changed behavior if any tabs
are present in a standard macOS application. So I chose to follow Safari
instead.

This doesn't implement this feature for GTK, that's left as an exercise
for a contributor.
2023-12-17 20:54:57 -08:00
Mitchell Hashimoto
20ba6f3d78 macos: close_window binding works properly again
This binding closes the physical window and all surfaces in that window.
2023-12-17 20:29:23 -08:00
Mitchell Hashimoto
2e74a0f9d4 macos: custom about window so we can be a first responder
Fixes #1052

This implements the about window as a custom window with a view
controller. This lets us implement the proper responder chain so that
our custom close window IBActions do the right thing.

This has an additional benefit that we can easily customize this window
going forward.
2023-12-17 15:51:04 -08:00
Mitchell Hashimoto
45a4573991 macos: previous_tab/next_tab wraps
Fixes #999
2023-12-10 15:12:22 -08:00
Mitchell Hashimoto
ec989d6b46 macos: newTab needs to call Controller.showWindow 2023-12-08 08:46:05 -08:00
Mitchell Hashimoto
4b25356625 macos: manually show window to handle mission control behavior
Fixes #1018
Fixes #1020

This disables the "visibleAtLaunch" configuration in the xib and
manually shows the window when it loads. This lets us carefully control
what happens particularly when a window is full screen (native) and part
of Mission Control.

Previously, the behavior depended on the Settings.app "Prefer tabs
when opening documents" setting, but we didn't handle every behavior
correctly (see #1018 and #1020). I couldn't find a way to robustly
handle all cases because there are no published macOS APIs for
interacting with Mission Control...

Plus, terminals aren't really "documents" so it did confuse at least one
user that Ghostty would follow this configuration. We just incidently
did because we use native tabbing.

This PR takes full control into our own hands. Our behavior is now:

  - If a new window is created from a native fullscreen window, the
    new window is created into native fullscreen.

  - If a new tab is created from a native fullscreen window, the
    tab is added to the existing window and does not create a new space.

  - If a window or tab is created from a non-fullscreen window, the
    existing behaviors remain.
2023-12-07 22:44:47 -08:00
Mitchell Hashimoto
3f76094d84 macos: handle the "+" button automatically adding the window to the tabs
Fixes #1010
2023-12-07 14:39:54 -08:00
Mitchell Hashimoto
fc6def01a1 macos: new tab button creates new tab after short delay
Fixes #1010

I can't explain this. See the comment in the diff.
2023-12-07 12:35:19 -08:00
Mitchell Hashimoto
6fed7cde19 macos: do not open an initial window if opening from URL 2023-12-01 19:28:06 -08:00
Mitchell Hashimoto
7036676ec0 macos: relabel tabs when they're reordered with the mouse
Prior to this commit, the shortcut shown on the tab would not be updated
until a focus change occurred. There is no event for this so the way we
do it is by listening for the tab view frame to change, comparing the
window state, and then updating labels.
2023-11-22 11:43:04 -08:00
Mitchell Hashimoto
7d9eaddeb3 macos: alternate solution to ignoring "always" userTabbingPreference
Related to #642
Fixes #910

See #642 for why we want to ignore the "always" userTabbingPreference.
To do that, we'd set tabbingMode to "disallow" because we manually (in
code) handled it all.

Unfortunately, setting the tabbingMode to "disallow" introduce #910. I
still believe this is a macOS bug at heart, so I'm going to submit an
Apple Feedback item for it. However, I've found a workaround which I
also feel is the better solution, implemented here.

Instead of setting tabbingMode to "disallow" I now detect if we're in
the scenario where the user has their system tabbing preference set to
"always". In that case, we detect if the new window has been
automatically put into a tab group by macOS, and if so we remove it.

This all happens in the `windowDidLoad` controller callback. At this
phase, our Ghostty-managed windows should NEVER be in a tab group,
because "new tab" adds them to a tab _after_. So we can be certain that
if we're already in a tab group it was from the macOS system setting.

This happens to fix #910.
2023-11-18 21:09:08 -08:00
Gregory Anders
be7be538af macos: ensure all surfaces are closed when a window is closed 2023-11-18 08:40:40 -06:00
Gregory Anders
98b43007a0 core: use ClipboardRequestType instead of ClipboardPromptReason
Instead of making a separate enum that must be translated from the
ClipboardRequest type, simply re-use ClipboardRequest to determine the
clipboard confirmation reason.
2023-11-10 23:12:39 -05:00
Gregory Anders
86245ff0cf macos: add option to prompt user for confirmation on OSC 52 commands 2023-11-10 23:12:39 -05:00
Gregory Anders
dffb5e9f15 macos: ensure tab labels are always visible
This tells AppKit to give the tab labels higher priority than the tab
titles. When the tabs become small, this causes the tab title text to be
truncated instead of dropping the tab label.

Fixes: https://github.com/mitchellh/ghostty/issues/843
2023-11-08 08:48:20 -06:00
Gregory Anders
cd01340cce macos: add key binding for equalizing split sizes 2023-11-07 16:23:28 -06:00
Mitchell Hashimoto
4e3ab4879d Merge pull request #822 from gpanders/split-resizing
macos: implement split resizing
2023-11-06 09:35:43 -08:00
Mitchell Hashimoto
f8b0654a19 Merge pull request #816 from Raiden1411/feat/options
feat: add support for `--fullscreen`, `--title` and `--class` values
2023-11-06 08:55:33 -08:00
Mitchell Hashimoto
efe9721c98 macos: honor fullscreen setting 2023-11-06 08:52:36 -08:00
Gregory Anders
582df33083 macos: use Ghostty.AppState as @EnvironmentObject
This is a small cleanup change. This provides the Ghostty.AppState
object to any view that needs it within the TerminalSplit view hierarchy
without needing to explicitly define EnvironmentKeys.
2023-11-05 20:42:59 -06:00
Gregory Anders
9b14398153 macos: support resizing splits 2023-11-05 20:42:59 -06:00
Gregory Anders
3b2799ce97 macos: refactor SplitNode
This commit does two things: adds a weak reference to the parent
container of each SplitNode.Container and SplitNode.Leaf and moves the
"direction" of a split out of the SplitNode enum and into the
SplitNode.Container struct as a field.

Both changes are required for supporting split resizing. A reference to
the parent in each leaf and split container is needed in order to
traverse upwards through the split tree. If the focused split is not
part of a container that is split along the direction that was requested
to be resized, then we instead try and resize the parent. If the parent
is split along the requested direction, then it is resized
appropriately; otherwise, repeat until the root of the tree is reached.

The direction is needed inside the SplitNode.Container object itself so
that the container knows whether or not it is able to resize itself in
the direction requested by the user. Once the split direction was moved
inside of SplitNode.Container, it became redundant to also have it as
part of the SplitNode enum, so this simplifies things.
2023-11-05 20:20:39 -06:00
Mitchell Hashimoto
ef44551522 apprt/embedded: hook up paste confirmation 2023-11-05 09:20:16 -08:00