summaryrefslogtreecommitdiff
path: root/src/Surface.zig
AgeCommit message (Collapse)Author
2025-06-27core: only update selection clipboard on left mouse releaseMitchell Hashimoto
Fixes #4800, supercedes #5995 This is a rewrite of #5995 (though the solution is mostly the same since this is pretty straightforward). The main difference is the rebase on the new mouse handling we've had since, and I also continue to update the selection clipboard on non-left-mouse events.
2025-06-24core, gtk: implement host resources dir for FlatpakLeorize
Introduces host resources directory as a new concept: A directory containing application resources that can only be accessed from the host operating system. This is significant for sandboxed application runtimes like Flatpak where shells spawned on the host should have access to application resources to enable integrations. Alongside this, apprt is now allowed to override the resources lookup logic.
2025-06-20renderer: big rework, graphics API abstraction layers, unified logicQwerasd
This commit is very large, representing about a month of work with many interdependent changes that don't separate cleanly in to atomic commits. The main change here is unifying the renderer logic to a single generic renderer, implemented on top of an abstraction layer over OpenGL/Metal. I'll write a more complete summary of the changes in the description of the PR.
2025-06-15apprt/embedded: improve text reading APIs (selection, random points)Mitchell Hashimoto
2025-06-07Make undo/redo app-targeted so it works with no windowsMitchell Hashimoto
2025-06-07add undo/redo keybindings, default them on macOSMitchell Hashimoto
2025-05-29input: "ignore" binding action are still be processed by the OS/GUIMitchell Hashimoto
Related to #7468 This changes the behavior of "ignore". Previously, Ghostty would consider "ignore" actions consumed but do nothing. They were like a black hole. Now, Ghostty returns `ignored` which lets the apprt forward the event to the OS/GUI. This enables keys that would otherwise be pty-encoded to be processed later, such as for GTK to show the GTK inspector.
2025-05-27code style: use `@splat` where possibleQwerasd
As of Zig 0.14.0, `@splat` can be used for array types, which eliminates a lot of redundant syntax and makes things generally cleaner. I've explicitly avoided applying this change in the renderer files for now since it would just create rebasing conflicts in my renderer rework branch which I'll be PR-ing pretty soon.
2025-05-27decl literalMitchell Hashimoto
2025-05-27test: introduce helper function for mouse selection testsQwerasd
Removes a lot of repeated code and makes the test cases easier to understand at a glance.
2025-05-27unit test mouse selection logicQwerasd
Adds many test cases for expected behavior of the selection logic, this will allow changes to be made more confidently in the future without fear of regressions.
2025-05-27terminal: rework selection logic in core surfaceQwerasd
This logic is cleaner and produces better behavior when selecting by dragging the mouse outside the bounds of the surface, previously when doing this on the left side of the surface selections would include the first cell of the next row, this is no longer the case. This introduces methods on PageList.Pin which move a pin left or right while wrapping to the prev/next row, or clamping to the ends of the row. These need unit tests.
2025-05-26style: use decl literalsQwerasd
This commit changes a LOT of areas of the code to use decl literals instead of redundantly referring to the type. These changes were mostly driven by some regex searches and then manual adjustment on a case-by-case basis. I almost certainly missed quite a few places where decl literals could be used, but this is a good first step in converting things, and other instances can be addressed when they're discovered. I tested GLFW+Metal and building the framework on macOS and tested a GTK build on Linux, so I'm 99% sure I didn't introduce any syntax errors or other problems with this. (fingers crossed)
2025-05-19Add `selection-clear-on-typing`Mitchell Hashimoto
Fixes #7392 Docs: > Whether to clear selected text when typing. This defaults to `true`. > This is typical behavior for most terminal emulators as well as > text input fields. If you set this to `false`, then the selected text > will not be cleared when typing. > > "Typing" is specifically defined as any non-modifier (shift, control, > alt, etc.) keypress that produces data to be sent to the application > running within the terminal (e.g. the shell). Additionally, selection > is cleared when any preedit or composition state is started (e.g. > when typing languages such as Japanese). > > If this is `false`, then the selection can still be manually > cleared by clicking once or by pressing `escape`.
2025-05-09clean up bindings so that they match macOS menusMitchell Hashimoto
2025-05-09input: remove `physical_key` from the key event (all keys are physical)Mitchell Hashimoto
2025-05-09apprt/glfw: buildsMitchell Hashimoto
2025-05-06Add "Scroll to Selection" commandfn ⌃ ⌥
2025-05-01Binding for toggling window float on top (macOS only)Mitchell Hashimoto
This adds a keybinding and apprt action for #7237.
2025-04-21add toggle command palette bindingMitchell Hashimoto
2025-04-14gtk: implement bell (#7087)Mitchell Hashimoto
This PR implements a more lightweight alternative to #5326 that contains features that I personally think Just Make Sense for the bell. No configs, no GStreamer stuff, just sane defaults to get us started.
2025-04-14gtk: implement bellLeah Amelia Chen
Co-authored-by: Jeffrey C. Ollie <jeff@ocjtech.us>
2025-04-13Mouse drag while clicked should cancel any mouse link actionsMitchell Hashimoto
Fixes #7077 This follows pretty standard behavior across native or popular applications on both platforms macOS and Linux. The basic behavior is that if you do a mouse down event and then drag the mouse beyond the current character, then any mouse up actions are canceled (beyond emiting the event itself). This fixes a specific scenario where you could do the following: 1. Click anywhere (mouse down) 2. Drag over a valid link 3. Press command/control (to activate the link) 4. Release the mouse button (mouse up) 5. The link is triggered Now, step 3 and step 5 do not happen. Links are not even highlighted in this scenario. This matches iTerm2 on macOS which has a similar command-to-activate-links behavior.
2025-04-10config: allow commands to specify whether they shell expand or notMitchell Hashimoto
This introduces a syntax for `command` and `initial-command` that allows the user to specify whether it should be run via `/bin/sh -c` or not. The syntax is a prefix `direct:` or `shell:` prior to the command, with no prefix implying a default behavior as documented. Previously, we unconditionally ran commands via `/bin/sh -c`, primarily to avoid having to do any shell expansion ourselves. We also leaned on it as a crutch for PATH-expansion but this is an easy problem compared to shell expansion. For the principle of least surprise, this worked well for configurations specified via the config file, and is still the default. However, these configurations are also set via the `-e` special flag to the CLI, and it is very much not the principle of least surprise to have the command run via `/bin/sh -c` in that scenario since a shell has already expanded all the arguments and given them to us in a nice separated format. But we had no way to toggle this behavior. This commit introduces the ability to do this, and changes the defaults so that `-e` doesn't shell expand. Further, we also do PATH lookups ourselves for the non-shell expanded case because thats easy (using execvpe style extensions but implemented as part of the Zig stdlib). We don't do path expansion (e.g. `~/`) because thats a shell expansion. So to be clear, there are no two polar opposite behavioes here with clear semantics: 1. Direct commands are passed to `execvpe` directly, space separated. This will not handle quoted strings, environment variables, path expansion (e.g. `~/`), command expansion (e.g. `$()`), etc. 2. Shell commands are passed to `/bin/sh -c` and will be shell expanded as per the shell's rules. This will handle everything that `sh` supports. In doing this work, I also stumbled upon a variety of smaller improvements that could be made: - A number of allocations have been removed from the startup path that only existed to add a null terminator to various strings. We now have null terminators from the beginning since we are almost always on a system that's going to need it anyways. - For bash shell integration, we no longer wrap the new bash command in a shell since we've formed a full parsed command line. - The process of creating the command to execute by termio is now unit tested, so we can test the various complex cases particularly on macOS of wrapping commands in the login command. - `xdg-terminal-exec` on Linux uses the `direct:` method by default since it is also assumed to be executed via a shell environment.
2025-03-19apprt/embedded: utf8 encoding buffer lifetime must extend beyond callMitchell Hashimoto
Fixes #6821 UTF8 translation using KeymapDarwin requires a buffer and the buffer was stack allocated in the coreKeyEvent call and returned from the function. We need the buffer to live longer than this. Long term, we're removing KeymapDarwin (there is a whole TODO comment in there about how to do it), but this fixes a real problem today.
2025-03-18ci: zig fmt checkMitchell Hashimoto
This adds a CI test to ensure that all Zig files are properly formatted. This avoids unrelated diff noise in future PRs.
2025-03-15scroll: translate non-precision to precisionTim Culverhouse
Some wheel mice are capable of reporting fractional wheel ticks. These mice don't necessarily report a corresponding precision scroll start event, at least in Wayland + GTK. We can treat all discrete (ie non-precision) events as the number of wheel ticks - for wheel mice, yoff will be "1.0" per tick, while precision wheel mice may report fractional values. This unifies handling of scroll events by normalizing all events to "pixels to scroll". We now report `mouse-scroll-multiplier` wheel or arrow events per wheel tick (or per accumulated cell height). This means that applications which subscribe to mouse button events will receive (by default) three wheel events per wheel tick. For precision scrolls, they will receive one wheel tick per line of scroll. In my opinion, this provides the best user experience while also allowing customization of how much a wheel tick should scroll Reference: https://github.com/ghostty-org/ghostty/discussions/6677
2025-03-11Zig 0.14Mitchell Hashimoto
2025-03-06gtk: add separate close_window apprt actionLeah Amelia Chen
For *some* reason we have a binding for close_window but it merely closes the surface and not the entire window. That is not only misleading but also just wrong. Now we make a separate apprt action for close_window that would make it show a close confirmation prompt identical to as if the user had clicked the (X) button on the window titlebar.
2025-03-02scroll: only use multiplier for non-precision scrollsTim Culverhouse
Precision scrolls don't require a multiplier to behave nicely. However, wheel scrolls feel extremely slow without one. We apply the multiplier to wheel scrolls only
2025-03-02scroll: don't use multiplier for wheel eventsTim Culverhouse
When we report mouse scroll wheel events, they should not be multiplied. Refactor the scrollCallback to only use a multiplier for viewport or alternate scroll reports.
2025-03-02surface: calculate scroll amount directly from yoff/xoff for non-precision ↵Tim Culverhouse
scrolls Calculate the scroll amount for non-precision scrolls as a direct multiple of yoff. This fixes an issue where Ghostty sends scroll wheel events (or arrow keys if in alternate scroll mode) that are variable, dependent on the screen size. I checked multiple terminals, and each responds to a single wheel click by sending only a single wheel / arrow key - independent of screen size. ```sh printf "\x1b[?1049h" printf "\x1b[?1007h" cat -v ``` Using the above procedure, with varying screen sizes: ``` # 50% Screen height | terminal | arrows keys sent| wheels events sent| |------------|-----------------|-------------------| | alacritty | 3 | 1 | | foot | 3 | 1 | | xterm | 5 | 1 | | kitty | 3 | 1 | | ghostty | 2 | 2 | # 100% Screen height | terminal | arrows keys sent| wheels events sent| |------------|-----------------|-------------------| | alacritty | 3 | 1 | | foot | 3 | 1 | | xterm | 5 | 1 | | kitty | 5 | 1 | | ghostty | 3 | 3 | ``` Both ghostty and kitty scale the number of arrow keys sent in proportion to the screen size. However, when mouse reporting is on, only ghostty does this. This commit makes Ghostty behave like foot, and more generally removes the dependence on screen size.
2025-02-28Introduce `reset_window_size` keybinding and apprt actionMitchell Hashimoto
Related to #6035 This implements the keybind/action portion of #5974 so that this can have a binding and so that other apprts can respond to this and implement it this way.
2025-02-28apprt initial_size is sent whenever the grid size changesMitchell Hashimoto
As noted in the comments, this is so that apprt's can always know what the default size of a window would be so they can utilize this for "return to default size" actions. The initial size shouldn't be treated as a "resize" event and was already documented as such. Prior to this commit the docs already noted that the initial size may be sent multiple times but only the first time during initialization should be used as a resize. Therefore, this shouldn't impact prior behavior. I've verified this with the apprts.
2025-02-14core: add `env` config optionJeffrey C. Ollie
Fixes #5257 Specify environment variables to pass to commands launched in a terminal surface. The format is `env=KEY=VALUE`. `env = foo=bar` `env = bar=baz` Setting `env` to an empty string will reset the entire map to default (empty). `env =` Setting a key to an empty string will remove that particular key and corresponding value from the map. `env = foo=bar` `env = foo=` will result in `foo` not being passed to the launched commands. Setting a key multiple times will overwrite previous entries. `env = foo=bar` `env = foo=baz` will result in `foo=baz` being passed to the launched commands. These environment variables _will not_ be passed to commands run by Ghostty for other purposes, like `open` or `xdg-open` used to open URLs in your browser.
2025-02-14Add tab title rename feature to macosAswin M Prabhu
2025-02-13macos: add `padded-notch` option for `macos-non-native-fullscreen`Mitchell Hashimoto
Finishes #378 Supercedes #4159 This adds a new enum value for `macos-non-native-fullscreen`: `padded-notch`. This value will add padding to the top of the window to account for the notch on applicable devices while still hiding the menu. This value is preferred over "visible-menu" by some people because for screens without a notch, the window will take up the full height. The plan in the future is that we may color the padded area when a notch is present. In this commit it appears as transparent.
2025-02-13apprt: require envmap for exec-based termioMitchell Hashimoto
Supercedes #5726
2025-02-11core: performAction now returns a boolJeffrey C. Ollie
This is to facilitate the `performable:` prefix on keybinds that are implemented using app runtime actions.
2025-02-11gtk(x11): set `WINDOWID` env var for subprocessesLeah Amelia Chen
`WINDOWID` is the conventional environment variable for scripts that want to know the X11 window ID of the terminal, so that it may call tools like `xprop` or `xdotool`. We already know the window ID for window protocol handling, so we might as well throw this in for convenience.
2025-01-22Prevent hyperlink hover state when mouse is outside viewportBryan Lee
2025-01-20use whitespace instead of new flag for selecting full lineotomist
2025-01-14add and use flag for selecting empty lines in the selectLine functionotomist
2025-01-13Handle setting _NET_WM_STATE (#4936)Mitchell Hashimoto
As recommended in https://github.com/ghostty-org/ghostty/pull/4927#issuecomment-2585003934, adds a config option `maximize` for starting a window in a maximized state in terms of window properties. Also adds a `toggle_maximize` keybind to allow users to manually toggle this feature on and off. It might make more sense to make this an optional config value so that we don't toggle the state off if the WM already handles that for us, but I'll let a reviewer decide. Closes https://github.com/ghostty-org/ghostty/issues/4646
2025-01-11core: clear selection whenever preedit is changedMitchell Hashimoto
2025-01-12Correct IME position calculation with window paddingBryan Lee
2025-01-10chore: rename config value to maximize and move startup logic to proper locationAdam Wolf
2025-01-10apprt/gtk: add toggle_maximize keybind and window-maximize config optionAdam Wolf
2025-01-08Add keybind action `copy_url_to_clipboard`Bryan Lee
2025-01-08Add `close_tab` keybinding action for macOSBryan Lee
Implement `close_tab` keybinding action to close the current tab and all splits within that tab.