Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quick terminal on Linux #4624

Open
pluiedev opened this issue Jan 5, 2025 · 14 comments
Open

Quick terminal on Linux #4624

pluiedev opened this issue Jan 5, 2025 · 14 comments
Labels

Comments

@pluiedev
Copy link
Contributor

pluiedev commented Jan 5, 2025

As discussed in #4361, it appears that we could implement the quick terminal on Linux if we make use of the wlr-layer-shell protocol.

For our specific use case as a GTK4 application, however, we might also consider an off-the-shelf, battle-tested solution such as gtk4-layer-shell instead as to reduce the burden of maintaining our own Wayland glue code (at the cost of introducing a new dependency, of course).

A perhaps ironic downside to this is that GNOME users won't be able to use this, though the stubbornness of GNOME developers is scantly our fault...

@gucci-on-fleek
Copy link

gucci-on-fleek commented Jan 6, 2025

(sorry if this comment belongs in a discussion thread instead)

A perhaps ironic downside to this is that GNOME users won't be able to use this, though the stubbornness of GNOME developers is scantly our fault...

Guake works on my Gnome+Wayland system, so wlr-layer-shell shouldn't be strictly necessary to implement a quick terminal. The only tricky thing is that a Wayland application cannot add a global hotkey, but Guake solves this by having the user manually register it with their desktop environment, so having the +toggle_quick_terminal action (or similar) work from the command line should be sufficient for this to work.

@pluiedev
Copy link
Contributor Author

pluiedev commented Jan 6, 2025

Guake is GTK3, though. GTK4 removed a LOT of APIs that allow windows to position themselves (since that is something Wayland explicitly forbids), so I doubt their approach still works

@pluiedev
Copy link
Contributor Author

pluiedev commented Jan 6, 2025

After looking at the gtk4-layer-shell docs, I realize that it's not exactly the best solution for us — not only does it mean even more C code (yikes) it also has its own Wayland register roundtrip logic which is terribly redundant.

I think writing the glue ourselves shouldn't be that bad, given a) how small the API is in reality (and how many of them are simple wrappers around existing Wayland protocols) and b) we can use Zig for a large part of the Wayland interface code thanks to zig-wayland, which should be a lot easier than trying to write raw C.

@MakotoTheKnight
Copy link

Going to capture this since it came up in the Discord:

Looking at prior art with ddterm, which bundles the terminal within a whole plugin, or with another plugin which attempts to do the same, this could set some direction on how to tackle this within GNOME. It'd likely need to be something that isn't directly bundled with Ghostty but could be offered as an addition to the platform, since GNOME's native approach is to use plugins.

Simply put, this appears to be the "workaround" that GNOME has to go through in order to place arbitrary windows of varying width and height on the screen. Doesn't have to be an option today, but could be revisited when libghostty is released.

@pluiedev
Copy link
Contributor Author

pluiedev commented Jan 8, 2025

Looks like reimplementing gtk4-layer-shell may be more difficult than I initially thought. The core problem is that GTK forces its windows to be initialized as xdg_toplevel windows, while we want them to be zwlr_layer_shell_v1 windows. (These are known as "roles" in Wayland jargon, and you cannot set a new role when one's already been set.) gtk4-layer-shell uses an extremely unsightly hack to essentially intercept any attempt by GTK to set the toplevel role and ignore them, thereby avoiding the collision.

I... am not down for patching and overriding symbols inside dynamic libraries. We should probably try doing something else (if an alternative exists).

@jcollie
Copy link
Collaborator

jcollie commented Jan 8, 2025

Ugly. I'd say us Gnome users just lose out until hell freezes over and Gnome implements the layer shell.

@pluiedev
Copy link
Contributor Author

pluiedev commented Jan 8, 2025

This isn't even just exclusive to GNOME — it's GTK being GTK 😛

@jcollie
Copy link
Collaborator

jcollie commented Jan 8, 2025

So a big FU from Gnome to everyone else too, huh?

@digitalsignalperson
Copy link

Some related issues on upstreaming the needed changes to gtk:
wmww/gtk4-layer-shell#9
wmww/gtk4-layer-shell#43
https://gitlab.gnome.org/GNOME/gtk/-/issues/2132

I... am not down for patching and overriding symbols inside dynamic libraries. We should probably try doing something else (if an alternative exists).

I'm imagining another (probably not practical) way to proxy between an output top-level window to a layer-shell window.

Create the layer-shell window by other means without gtk, and imagine it as a mini compositor for the gtk app window (all private to the same process). The gtk app will get a wayland display socket, and the idea is to have some minimal wayland proxy/server code translates things over. Or maybe there's a way to do that without a proxy by just rendering to texture?

@pluiedev
Copy link
Contributor Author

That sounds technically feasible I guess (basically making a relay that's both a client and a server simultaneously and pointing GTK at the relay server, which allows the relay to filter requests) but I'd have to think more about it. It sounds like something that maybe someone has made before though.

@digitalsignalperson
Copy link

Interestingly, firefox bundles it's own thin wayland proxy which is only 733 loc of C++. I wonder if something around this level of complexity is possible:

Various other references I have for either proxies or self hosted compositors that may be educational or have bits to copy:

@digitalsignalperson
Copy link

@digitalsignalperson
Copy link

digitalsignalperson commented Jan 22, 2025

Here's a bit of a toy POC: https://gist.github.com/digitalsignalperson/9f6bc16ba1954c40cb61ca4babc8c419

  • Create a gtk app with gtk4-layer-shell which contains a single CasildaCompositor widget, then spawn a ghostty process on the socket created by casilda.
  • Toggle visibility of the drop-down terminal with kill -USR1 $(cat /tmp/casilda-tty.pid) (which could be the cmdline associated with a global hotkey)

Jankyness:

  • clipboard doesn't work
  • have to use ghostty --fullscreen as casilda doesn't act like something like cage where the top level window is forced to take up the whole screen. If you un-maximize it you can move the window around in the space
  • non-rounded corners and blank area on startup/finish looks not pretty
  • a window size greater than 1000x600 didn't fullscreen properly (not sure which part of the stack is responsible)

Adding to references of interest: wlroots has a nice example of a layer-shell client https://gitlab.freedesktop.org/wlroots/wlr-clients/-/blob/master/layer-shell.c but idk if there is a way with gtk4 to render to something "offscreen" and deal with passing inputs

Also thought wofi was a good reference until I realized it was gtk3

@digitalsignalperson
Copy link

Also noticed that gtk4-layer-shell is an official package in almost all major distros. Seems like a kind of accepted solution despite the method of overriding functions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants