alacritty / alacritty

A cross-platform, OpenGL terminal emulator.
https://alacritty.org
Apache License 2.0
55.81k stars 3k forks source link

Investigate macOS tabs #1544

Closed jwilm closed 2 years ago

jwilm commented 6 years ago

Per @pcwalton's comment, this may actually be somewhat easy to support.

paulrouget commented 6 years ago

I have some experience in this area. We ran into the same issues with Servo.

On a general note, for tabs, menu, popups (etc) support or any proper integration with MacOS, we tried:

  1. create an xcode + obj-c/swift project that would load Servo as a library (no winit/glutin)
  2. create a xib the we would in Rust (see https://github.com/paulrouget/servoshell, no winit/glutin)
  3. use the native handle exposed by winit and dynamically build the menu and all the missing MacOS integration bits

2 was my favorite approach as it didn't require writing Obj-c/Swift code, but we could still design the UI with XCode. But we lose winit events which was great for the multiplatform abstraction. It's probably possible now to tell winit to re-use an existing window (the xib loader creates its own window iirc).

3 works. It's not optimal as everything needs to be done manually.

I think the best long term approach is to add these features to winit.

As for tabs, specifically, both for Mac and Windows (window support is still in beta, see Redstone 5 release), it's just matter of supporting multiple windows and flagging them a "tab-able", and the OS will do the rest.

Hope that helps.

jwilm commented 6 years ago

Thanks for sharing your experience here @paulrouget! Even better that there's a big example program to learn from. :smile:

I hope you don't mind; I have a few questions.

  1. When you say "adding these features to winit", are you calling out xib loader/initialization for a winit window?
  2. In servoshell, did you reimplement event handling on top of the handle returned by the xib loader?
  3. Reflecting on this a bit further, it sounds like servo isn't using winit any longer. Is that true? What major features are you missing from winit today beyond xib support?

cc @francesca64 who might be interested in this discussion

paulrouget commented 6 years ago
  1. When you say "adding these features to winit", are you calling out xib loader/initialization for a winit window?

No. I never used xib + winit.

I meant adding methods to the winit builder to support tabs and menus.

  1. In servoshell, did you reimplement event handling on top of the handle returned by the xib loader?

Yes. The xib loader will instantiate whatever classes is referenced in the Xib. These classes are implemented in rust. See for example the NSView which holds the gl buffer: https://github.com/paulrouget/servoshell/blob/master/src/platform/cocoa/view.rs - you'll see the keyUp:, scrollWheel: methods.

  1. Reflecting on this a bit further, it sounds like servo isn't using winit any longer. Is that true? What major features are you missing from winit today beyond xib support?

We use winit on desktop (but not on mobile).

The ServoShell project has been abandoned. It was just a prototype to experiment with xcode/xib. I haven't worked on it for a year now.

If you plan to just add tab and menu support, implementing these 2 features in winit is probably the way to go. If you want a more advanced UI, implementing a way to make Winit load a xib for you would be pretty amazing.

sodiumjoe commented 6 years ago

this sounds like it depends on https://github.com/jwilm/alacritty/issues/607

Spirarel commented 5 years ago

Is anyone able to weigh in where tabs are at? The conversation ended up split over several issues. Last I saw, macOS window grouping required all windows to belong to the same process.

Are native macOS tabs still on the table for Alacritty or has this been abandoned?

nixpulvis commented 5 years ago

As I understand the goals of Alacritty, this wouldn't be ruled out if it only requires a few custom macOS additions to support. However if it conflicts with our own ideas of how we want to support something like this across platforms then it would be best to just implement tabs the one way from the start. The main thing I'd like to avoid personally is two implementations of tabs.

nicolashahn commented 5 years ago

@nixpulvis Is that on the roadmap? I'm loving alacritty on OSX except for having to use tmux for tabs and splits.

herrbischoff commented 5 years ago

Same here. My only gripe is missing tabs. I love the way tabs are implemented in https://github.com/kovidgoyal/kitty, which is DOS-style text tabs at the bottom:

Screenshot 2019-05-07 at 23 32 14

I believe this would fit the simplicity requirement quite nicely and would translate cross-platform.

chrisduerr commented 5 years ago

This feature is only about the native tab support by the macOS window manager, not about tabs inside of Alacritty.

Those are out of scope for Alacritty and better handled by tmux or the WM/Compositor.

herrbischoff commented 5 years ago

I see. Just interpreted @nixpulvis comment

However if it conflicts with our own ideas of how we want to support something like this across platforms then it would be best to just implement tabs the one way from the start.

as possibly pointing in the direction of cross-platform tabs. If tabs are still generally out of scope, wouldn't it be more consistent to allow multiple terminal windows/instances in macOS instead? Just wondering.

chrisduerr commented 5 years ago

wouldn't it be more consistent to allow multiple terminal windows/instances in macOS instead

That's the goal. Based on the information I have, it's necessary on macOS to spawn separate windows from the same process to have them connected together properly. Once that's the case, it will also allow easily making use of the native tab support.

These issues are all linked together as far as I know, however I'm unaware of any specifics (which is why this issue is labeled as investigate macos tabs. If it should turn out that Alacritty will need to do any kind of rendering adjustments to display tabs itself, it will not be supported. However it seems like macOS takes care of that, so it shouldn't be a massive change after proper instancing for macOS is resolved.

gilescope commented 5 years ago

This would be so helpful - Alacritty is excellent, but throw in tmux and vi and copy and paste on OSX becomes an amazing symphony of competing configurations. There are 15 blogs devoted to how one might solve this but not using tmux would make things much simpler - at the moment figuring out copy+paste is like watching inception...

aste4 commented 5 years ago

I'd like to chime in with my reason why tabs are necessary to have in alacritty.

I use tmux daily. It's my life. The one use case alacritty doesn't solve very well is when I want to use tmux locally but also remotely. With almost any other terminal out there, I can create a new instance of a terminal in one tab, run tmux locally there and create window/panes locally. In a second tab, I can ssh to the remote server and use tmux there. I can switch between tab 1 and tab 2 with some key binding.

The other similar use case is that if I use tmux locally, ssh into a remote machine and launch vim, certain key presses (like Ctrl-J and Ctrl-K) are not received by the remote vim session because they are captured by the local instance of tmux and instead move up/down to the next pane. I solve this again by creating a new terminal, sshing, and attaching or creating a new tmux session there.

Supporting these use cases is not impossible but it's very impractical. Sending prefix command to a remote tmux session while in tmux is doable but is a big cognitive tax

One possibility is to have multiple instances of alacritty but from what I've seen in issues raised here, its not so easy/obvious/clean.

Like @herrbischoff mentioned, if alacritty could have the same text-based tabs that kitty has, alacritty would be a no brainer for me. Or just another tmux like pane that adds an extra layer/dimension. I'd drop my current terminals in a heartbeat. I've successfully run alacritty on both mac and linux and I love how easy it is to configure.

This terminal is my number 1 choice and I will use it when my day to day doesn't involve working both remotely and locally but right now the lack of tabs is killing me.

I've tried kitty but the font rendering seems completely off to what I would expect. Alacritty's is perfect with the exception of a font smoothing issue fixed by a patch found in one of the issues here.

I have zero experience with rust but I am slowly starting to learn in hopes of at least adding this functionality in a fork. I have absolutely zero idea where to begin but if there's no hope for tabs in alacritty then I'd better get right to it. Any pointers on where to look to adding a text based like tab at the top similar to what kitty has?

chrisduerr commented 5 years ago

@aste4 Tabs just aren't something that should be supported in a terminal emulator. It's just a waste of effort since it's very complex and completely unrelated to the issues a terminal emulator actually needs to solve. Tiling and tabbing are prime examples of exactly what window managers are there for and if you feel the desire to tab your windows, that's probably where this problem should be raised.

In Linux that's already widely available with many window managers, so it's just about picking one that supports the features you want.

On macOS it's possible to let the macOS WM handle it if the original comment by pcwalton is accurate. That's also something we can do, spawning multiple connected Alacritty processes is something we can do, managing windows is something the macOS WM can do for us then.

On Windows things are the most dire. They actually planned on adding this and I'd assume it would have worked great with Alacritty. I'm not sure if this was just too drastic of a UI/UX change for Windows or what caused this, but they've scrapped it for now. So chances are Windows users are SoL (at least for now), but that's unfortunately a common issue with Windows and I don't think it's Alacritty's shop to solve this.

chrisduerr commented 5 years ago

@BarryMode Your shell should support job control, which allows you to put certain commands in the background and keep stdin available. Though most users that rely on this frequently will likely prefer tmux or screen.

nixpulvis commented 5 years ago

The discussion here should not be focused on whether or not tabs are useful, I think we all know they are. The question is what application's job it is to implement it. As we've now seen in #2786, tabs can be implemented from a third party tool named tabbed on X11 (I've tested it, and it works quite well). If we can do the same kind of thing for macOS without maintaining either a huge macOS specific library, or effectively our own tabbed implementation.

gabeio commented 5 years ago

Can I just request if tabbing is added that it is optional like config setting to get rid of them or even better yet not bother loading that (module?) into memory. I currently love alacritty as it stands today. I actually appreciate that it helped me get into tmux because of the lack of tabs.

nixpulvis commented 5 years ago

@gabeio, with the ways things work in X11 on Linux, you get this for free, and only launch a "tabbed" Alacritty session with tabbed alacritty --embed. However, if to support macOS there is considerable dynamic linking required, it may be less desirable. I hope there's a solution as clean as what we seem to have with X11.

pcwalton commented 5 years ago

Tab support is built into AppKit, which Alacritty is already linking to. I don't know much of the details of how it works, however. There will likely need to be some macOS-specific code, though it could be encapsulated in a macos-tabs crate or something like that.

It seems to involve the NSWindowTab class: https://developer.apple.com/documentation/appkit/nswindowtab?language=objc

This Stack Overflow answer says that if you set the tabbingMode and tabbingIdentifier properties on each NSWindow, then AppKit will automatically allow the user to group the windows into tabs.

gabeio commented 5 years ago

I'm totally cool with even needing to rebuild alacritty (I already build alacritty currently) to disable the tabs so long as it's an easy flag option to make, build environment variable or something similar 😎

chrisduerr commented 5 years ago

Yeah, this issue is purely about investigating the macOS tabs @pcwalton is talking about. It's not about Windows or X11, those will be completely unaffected. And there should not be any rendering code added to Alacritty.

So there's no need to worry about having to explicitly disable Alacritty's tabs, since Alacritty itself will not have tabs. We're just integrating functionality provided by the window manager.

This is also why it's a bit unfortunate that Windows seems to have canceled their tabs feature. Because that makes it the only platform where this isn't possible. But with Windows' terminal support there are many issues that Windows users currently just have to live with because of lacking support from Microsoft.

pcwalton commented 5 years ago

The main difficulty would involve enabling multi-window support for Alacritty. Allowing for macOS tabs would be trivial after that.

chrisduerr commented 5 years ago

Yeah, that describes the TL;DR on this issue pretty well. And that's also what has been stated so far. Currently this means that this issue is blocked by #607.

harrysolovay commented 4 years ago

Any movement on this issue? Lack of multiple tabs/windows support it the only feature keeping me from using Alacritty.

gilescope commented 4 years ago

Windows Terminal has tabs and works pretty well. I will use that while waiting for a rust terminal that can do tabs.

Sent with GitHawk

adzierzanowski commented 4 years ago

I'm using XQuartz on macOS and I compiled tabbed. It works fine with xterm. Even though alacritty opens inside X server if XQuartz is running, tabbed alacritty --embed creates detached windows instead of tabs. I wonder what is the point of failure here.

kchibisov commented 4 years ago

@adzierzanowski oh it won't work, since X11 is limited to linux/bsd(mean not macOS) in alacritty, and you're using some linux/bsd only APIs.

diego-lipinski-de-castro commented 4 years ago

I found alacritty today and will already need to stop using because it does not have tabs support, oh well

adzierzanowski commented 4 years ago

@diego-lipinski-de-castro Try tmux, it supports tabs, keyboard shortcuts and has mouse support.

Screen Shot 2020-09-18 at 18 21 03
coolaj86 commented 4 years ago

Tabs just aren't something that should be supported in a terminal emulator.

That's a moral argument. Not that we can't have morals, but... why can't we have tabs?

I mean, I just can't imagine a person saying "Tabs just aren't something that should be supported in a web browser" and yet, the Terminal is the browser of the computer.

coolaj86 commented 4 years ago

Could there be some sort of agreement on a way to put tabs in, but keep that in a separate fork that can easily track without other conflicts?

coolaj86 commented 4 years ago

@adzierzanowski How does one get Cmd ⌘ + T and Click to switch tab working in tmux?

jbg commented 4 years ago

@coolaj86 please be considerate of the fact that your issue comments here are emailed to probably >50 people. You can get a tmux tutorial elsewhere.

coolaj86 commented 4 years ago

@jbg I believe that people come to this issue through search, looking for a solution. If there's a solution and someone here knows it, let them speak.

Likewise, let the people who don't want to follow this thread unsubscribe.

Much like it's not a terminal's job to manage tabs, it's not my job to micro-manage who should be exposed to what kind of information.

(my goal is to find solutions and make the best, most applicable information available to those who are interested in it)

SalomonSmeke commented 4 years ago

Excuse me for adding to the noise.

+1 to tmux, but it's a really popular tool and you're likely going to find many comprehensive or quick guides with a quick google.

This issue is blocked by another issue, about multiple window support. It's listed above in the buried comments!

I also think this would be a great feature; but it's blocked. Even if it would be given priority, that would have to happen first. Might be worth marking that other issue with comments mentioning the issue remains relevant; but don't spam it. Please. I'm sure the maintainers have things they do.

Maybe try a hand at it yourself! I'm down to donate some time if you find folk familiar with this codebase that need a monkey.

Jeppelelle commented 4 years ago

Any news on this? Apple have made it fairly easy to setup tabs in applications that are running NSWindow

I am not to familiar with Rust (creating NSWindow that allow for tabs is super easy in Xcode + Swift, basically just a bool for allowing/implementing tabs & some minor extra code for controller logic if needed, usually not needed since macOS/X11/Quartz/whatever takes care if it for you), having said that, it should not really be that much of an issue for anyone familiar to Rust to implement tabs on macOS:

Alacritty already uses flags for target_os = "macos" for creating windows with WindowBuilder (through winit(?)), going by the Rust docs WindowBuilder / Window in Rust implements platformspecific (not with winit since it seems somewhat limited to which flags can be set on NSWindows, would probably have to go through WindowExt/WindowBuilderExt, or any other way of accessing NSWindows directly): https://docs.rs/winit/0.15.1/i686-apple-darwin/winit/os/macos/trait.WindowExt.html

So, there should be an easy access to NSWindows, as many have stated in this thread, some have mentioned NSWindowTab which works but allowsAutomaticWindowTabbing is even easier to setup, it takes a bool (true) which is basically a "set it and forget it" toggle; the system takes care of most of the rest (most, because as i said, sometimes developers want custom logic to tabs & windows but i think this works good enough for most macOS Alacritty users who are longing for tabs) https://developer.apple.com/documentation/appkit/nswindow/1646657-allowsautomaticwindowtabbing

So, Alacritty DON'T need to implement its own tab system on macOS, it just have to allow NSWindow to implement native macOS tabs which the system takes care of outside of it's apps (when intercommunication between tabs is not needed, which Alacritty don't need, the default emulator (zsh) don't) & multiwindows would not be affected with this implementation, user/system decides if it wants new multiple windows or opening a new tab inside a window (basically with automatic tabbing macOS just groups together multiple windows inside a tabbed NSWindow, all Alacritty instances would still be separate)

So yeah, a Tab inside ActionWrapper that implements a bool toggle from "allowsAutomaticWindowTabbing" on macOS would be awesome

onedr0p commented 4 years ago

I don't see this mentioned anywhere in this issue but Wezterm has tab support (not using OS APIs afaik) and is also written in Rust. Maybe the developers can see how it's done there?

kchibisov commented 4 years ago

I don't see this mentioned anywhere in this issue but Wezterm has tab support (not using OS APIs afaik) and is also written in Rust. Maybe the developers can see how it's done there?

It doesn't matter how it's done there, and it has nothing to do with rust. The only thing that matters is someone dedicated to work on that feature on macOS, since core maintainers are not using macOS. However the one thing that we need to do before doing macOS tabs is multi window support.

chrisduerr commented 4 years ago

Any news on this?

If anyone else is curious about this question, please just read the previous discussions. There is no news about this, because even the issue blocking it isn't done yet. So unless that changes there's no point at all in asking again and again.

Chances are this will take a long time too, because there's no benefit to any of the main contributors to Alacritty. Nobody contributing to Alacritty actually wants to use macOS. If you're familiar with Rust and willing to look into this, I'm always happy to mentor people through the implementation process, but there's no incentive for most contributors to work on this and constantly asking about it doesn't really help.

terhechte commented 3 years ago

Just wanted to chime in. Although this is in theory rather easy to do on macOS and even with winit and glutin, it is much harder for Alacritty because allowsAutomaticWindowTabbing works on a per window basis. Each window (NSWindow) becomes a new tab. Alacritty, however, doesn't support multiple windows. When you open another window it actually forks a new process / instance. macOS / Cocoa doesn't support tabbing for multiple processes. See event::spawn_new_instance.

I'd guess rewriting Alacritty to support multiple event loops (one per window) in one process is a lot more work. Actually, I briefly looked at the code and couldn't see an easy way to pull this off 😔

Edit: Actually, if #1589 were to be updated and merged, I think it would be much easier to implement tabs:

chichid commented 3 years ago

I don't see this mentioned anywhere in this issue but Wezterm has tab support (not using OS APIs afaik) and is also written in Rust. Maybe the developers can see how it's done there?

Thanks for the hint, Wezterm is definitely the best option to get the best of both worlds: a fast GPU accelerated terminal and a lot better feature support.

xenoterracide commented 3 years ago

I like alacritty, especially the vi like navigation, I was hoping for tabs that might be like vim's tabs and once I'm in that vi mode I could just do :gt :gT :tabnew, not really wanting native support. I'll have to take a new look at tmux, but in some ways I'm wondering if I've got too much vi inception going on...

sstubbs commented 2 years ago

Firstly thank you for this amazing project. I've been using https://github.com/zellij-org/zellij with alacritty for tabs and it's working quite well so far.

chrisduerr commented 2 years ago

macOS tab support now works on macOS. There's currently a bug in winit which might require manual resize sometimes but that is tracked separately.

cmoog commented 2 years ago

macOS tab support now works on macOS. There's currently a bug in winit which might require manual resize sometimes but that is tracked separately.

I've read through this thread and still am not sure how to use tab support on macOS. @chrisduerr did you just mean that tab support is unblocked now that multi-window is merged, or is there already a method to use tabs as a user?

kchibisov commented 2 years ago

@cmoog you can use tabs now if you go to system preferences and use prefer tabs for new window option. Each new window created with CreateWindow will tab.

cmoog commented 2 years ago

@kchibisov thank you!

nixpulvis commented 2 years ago

Each new window created with CreateWindow will tab.

Just to be precise, the action is CreateNewWindow.

On the macOS side, it still seems somewhat unfortunate that I can't choose between new windows and new tabs. I've never heard of this whole "Perfer tabs" nonsense but I guess I'll set it to "always" since I can then drag the tab out into a window, whereas I don't think I can drag a window back into a tab.

If anyone knows more about this, I'd be curious to hear more.

chrisduerr commented 2 years ago

If anyone knows more about this, I'd be curious to hear more.

Yeah, if there's an option in the macOS API to set this preference on a per-application level, that might be something we can provide to make things a little easier.

nixpulvis commented 2 years ago

Honestly, I just want to try and understand the motivation for this setting in macOS in the first place. Why the hell would I want a new window to "prefer" anything? Opening a new window should be (pretty much) deterministic, no? Sure there's always going to be conflicts if multiple processes are trying to interact with the WM at once (or maybe someone has clever solutions to this too?), but I see nothing wrong with having a ⌘ + N and a separate ⌘ + T binding for these two different actions.

I'm guessing this is yet another example of iOS crap leaking into macOS. Mobile gestures are much more limited than what we are used to with a proper keyboard. Frankly, I'd be happy relearning my mobile experience around a keyboard long before I give up my desktop/laptop keyboard "power-user" experience with reliable and various keybindings.

But yea, if Alacritty can just force macOS to always open in tabs regardless of preference, that would be nice. At least that way people will be able to use tabs and windows without having to learn about this insane configuration.