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

Show window icons in titlebar #4882

Open
hasufell opened this issue Jan 5, 2020 · 38 comments
Open

Show window icons in titlebar #4882

hasufell opened this issue Jan 5, 2020 · 38 comments
Labels
enhancement New feature or incremental improvement i3-compat Sway doesn't match i3's behavior

Comments

@hasufell
Copy link

hasufell commented Jan 5, 2020

I generally find it hard to distinguish the type of window just based on the title. I'm wasting time reading titles and being confused about whether I'm switching to a console, browser window or something else. Workspaces alone don't fix it, they are only useful to group windows, not distinguish them visually. Icons fix this easily with little visual overhead.

There were several i3 window titlebar icon patches. Also see the screenshot.

I wasn't able to find an existing issue report about this.

@emersion
Copy link
Member

emersion commented Jan 5, 2020

Sorry, this isn't something we're interested in.

@hasufell
Copy link
Author

hasufell commented Jan 5, 2020

Sorry, this isn't something we're interested in.

Why?

@emersion
Copy link
Member

emersion commented Jan 5, 2020

We try to keep Sway simple. You're free to add this feature to a fork of Sway if you want it.

@emersion emersion closed this as completed Jan 5, 2020
@hasufell
Copy link
Author

hasufell commented Jan 5, 2020

We try to keep Sway simple.

What is simple and what isn't? How is showing a text simpler than showing an icon?

@emersion
Copy link
Member

emersion commented Jan 5, 2020

Icon lookup is far from simple. Sway would need to implement it, then load the image (supporting multiple file formats), and render it.

@hasufell
Copy link
Author

hasufell commented Jan 5, 2020

Wondering what #307 was about then

@vvrein
Copy link

vvrein commented Apr 9, 2020

@hasufell you could try something like this:

for_window    [app_id="(?i)firefox"]            title_format "<span foreground='#FF6611'><tt></tt></span> %title"
for_window    [app_id="Alacritty"]              title_format "<span foreground='#00FF00'><tt></tt></span> %title"
for_window    [app_id="telegramdesktop"]        title_format "<span foreground='#84b3ff'><tt></tt></span> %title"

@laur89
Copy link

laur89 commented Jul 5, 2021

Worth mentioning that upstream i3 has implemented the feature.

@brett-mahar
Copy link

As a workaround, you can name windows incorporating emojis, eg in sway's config:

for_window [title="cmus"] title_format "🔊 cmus "
for_window [title="rss"] title_format "📜 rss "

And your font has to have emoji support, eg:

font pango:Liberation Sans 21

@fluix-dev
Copy link
Contributor

Worth mentioning that upstream i3 has implemented the feature.

Though this is a link to Airblader's fork, true upstream did indeed implement this in i3/i3#4439.

@Xyene Xyene reopened this Jul 5, 2021
@Xyene Xyene added the i3-compat Sway doesn't match i3's behavior label Jul 5, 2021
@emersion
Copy link
Member

FWIW, I don't really like the idea of this feature from a technical point of view. It comes at a significant cost: using the XDG icon spec to find the icon from the app-id, then load it (we need to support a variety of file formats), then upload it to the GPU for rendering.

@emersion emersion changed the title [Feature request] Windows titlebar icons Windows titlebar icons Jul 24, 2021
@emersion emersion added the enhancement New feature or incremental improvement label Jul 24, 2021
@emersion
Copy link
Member

Note, i3 doesn't need all of this, because X11 clients upload their icon pixel data themselves to the X11 server as a window property. Wayland doesn't do such things (for good reasons!), but that means more work for Sway.

@emersion emersion changed the title Windows titlebar icons Show window icons in titlebar Jul 24, 2021
@emersion
Copy link
Member

emersion commented Jul 24, 2021

Yet another note, a way out of this would be to have a helper client responsible for rendering the titlebars. This would also allow users to arbitrarily customize the titlebars. As a bonus, this would remove the need for cairo/pango in Sway completely.

This needs a lot more investigation before it can become a viable option, though.

@fluix-dev
Copy link
Contributor

This needs a lot more investigation before it can become a viable option, though.

Very true, but this sounds like it could be really clever!

@ghost
Copy link

ghost commented Aug 3, 2021

Excited about the removal of cairo/pango as dependencies :)

@WhyNotHugo
Copy link
Contributor

Yet another note, a way out of this would be to have a helper client responsible for rendering the titlebars. This would also allow users to arbitrarily customize the titlebars. As a bonus, this would remove the need for cairo/pango in Sway completely.

I believe that, for an implementation to be efficient, it should need to draw the titlebars into a surface itself (rather than pipe bytes to sway and have sway draw that), right?

What do you think of drawing all decorations on this external helper (titlebars and borders). The default helper that sway ships can keep the current, very simple, implementation, but a potential third party one can add shadows and other eye candy without adding maintenance burden on sway.

@emersion
Copy link
Member

Yeah, that's what I had in mind.

@twitchyliquid64
Copy link

twitchyliquid64 commented Feb 28, 2022

How do you imagine this working? A new WLR-specific Wayland protocol for signalling what needs to be rendered by the helper program + shuttling the surfaces around, or perhaps something more lightweight (just using wayland surfaces as a convenient render surface, the rest signaled out-of-band)?

I'll be between roles soon, and might be interested in giving this a go.

@WhyNotHugo
Copy link
Contributor

Basically the helper needs to render two things: borders, and titlebar. The titlebar in sway doesn't follow the same rules as more traditional (e.g.: xfce-like) desktops. For a window in a tabbed container, the titlebar should actually enumerate all the windows in the tabbed container, so the protocol needs to actually describe the three itself.

I've seen other x11 window managers that something similar when it comes to tabbing arbitrary windows (e.g.: pekwm), so the wayland protocol may be reusable by other compositors (even if the helpers themselves are not necessarily all portable).


Re regarding the size of the borders "surface". Assume a window has a 200x200px space. If the helper renders a 2px border, should sway resize the inner window to 196x196px? Does the helper render 200x200px with a transparent/ignored area in the middle? Or does it render four different surfaces (top, right, bottom, left)? I suspect the latter is more efficient.

The helper could indicate a global "oh, my borders are all top:2px, bottom: 2px, left: 2px, right:2px", so sway knows how much it'll need to pad windows.. I think per-window border sizes would be far more problematic.

Side question: Can borders for floating windows have alpha? I'm sure someone will eventually want to use this for shadows and such.

@twitchyliquid64
Copy link

For a first pass, would we really want to delegate all logic for configuring border sizes etc to the helper? could we keep that in Sway's configuration, and simply pass that global info (as well as the window information and the surfaces) to the helper for rendering?

@twitchyliquid64
Copy link

More generally, what should be the behavior in the case that the helper is 'slow' in rendering the surface and yeeting it back? My guess is that somehow, sway should avoid blocking frames and instead just paint the border/titlebar with the correct color as defined by the config?

@mid-kid
Copy link

mid-kid commented Mar 2, 2022

Note, i3 doesn't need all of this, because X11 clients upload their icon pixel data themselves to the X11 server as a window property. Wayland doesn't do such things (for good reasons!), but that means more work for Sway.

Maybe a bit off-topic, but what good reasons? Applications being able to dynamically update their window icon alongside their title has been a thing since the dawn of time, I'm not sure what exactly is the issue with communicating that along with the protocol.

+1 for splitting off the titlebar/border rendering. I've been thinking about patching sway locally to modify the borders since I find them a tad boring.

@PAI5REECHO
Copy link

PAI5REECHO commented Mar 28, 2022

I'm surprised that people are able to use Sway quickly and efficiently without window titlebar icons. Having to visually scan and read text for dozens of window titles you have open wastes a lot of time and reduces productivity.

@emersion
Copy link
Member

Discussion about this on IRC:

2022-03-14 21:33:37	twitchyliquid64	Hi! I'm interested in working on https://github.com/swaywm/sway/issues/4882#issuecomment-886101225 and wanted to kick off the conversation in a high-bandwidth channel like here if thats okay
2022-03-14 21:43:46	emersion	sure thing
2022-03-14 21:43:53	emersion	are you familiar with wayland protocols?
2022-03-14 21:59:28	<--	illiliti (~illiliti@user/illiliti) has quit (Quit: leaving)
2022-03-14 22:09:49	twitchyliquid64	A little!
2022-03-14 22:10:47	twitchyliquid64	Were you thinking of a wayland protocol extension to communicate the titlebars + surfaces back and forth, somewhat in the same spirit of how wlr layer shell works?
2022-03-14 22:27:06	emersion	yeah i was thinking about a protocol to set the surface for each side
2022-03-14 22:27:58	emersion	one really important thing is synchronization
2022-03-14 22:28:14	emersion	also disclaimer: i'm not 100% sure this is a good way forward
2022-03-14 22:28:39	emersion	ifreund, kennylevinsen, vyivel: thoughts on the approach described in the link above?
2022-03-14 22:29:29	emersion	the possible alternatives would be:
2022-03-14 22:29:55	emersion	(1) just… load the PNG/JPG/SVG files inside sway and render the icons there
2022-03-14 22:30:30	emersion	(2) add a protocol for a helper client which just renders the icon, not the whole decorations
2022-03-14 22:31:13	emersion	(3) restrict how decorations can look like so that we can re-render them in sway without asking the helper client to re-render
2022-03-14 22:31:35	emersion	(e.g. surfaces for each corner + repeating surfaces for the edges)
2022-03-14 22:31:49	twitchyliquid64	Is communicating with the helper client over stdin + shared memory (as opposed to a brand new wayland protocol, which would need code in wlr) a non-starter?
2022-03-14 22:31:57	emersion	(+ one surface anchored on the top-left?)
2022-03-14 22:32:16	emersion	such a protocol would just reinvent wayland
2022-03-14 22:32:30	emersion	wayland is basically a pipe + shared memory
2022-03-14 22:32:36	emersion	s/pipe/socketpair/
2022-03-14 22:32:51	twitchyliquid64	Yeah fair enough
2022-03-14 22:33:12	twitchyliquid64	I'll need to dig in and learn wlr and a bunch more is all, but if its the right way to do it its the right way to do it.
2022-03-14 22:33:17	emersion	but if we just reinvent our thing, we need to also reinvent a marshalling, synchronization primitives, what if clients want to use the GPU, etc
2022-03-14 22:33:42	emersion	submitting a wlr patch shouldn't be more scary than submitting a sway patch
2022-03-14 22:33:54	twitchyliquid64	okies
2022-03-14 22:34:00	twitchyliquid64	As for the alternatives, Im not a huge fan of (1) or (2) because a lot of the appeal of this (for me at least) is flexibility. As for (3) I don't know enough about these nuances yet.
2022-03-14 22:34:09	emersion	it's basically the same, except in wlr it can be re-used by other compositors, if there is interest
2022-03-14 22:34:32	emersion	and we can provide guidance ;)
2022-03-14 22:34:37	emersion	yeah
2022-03-14 22:34:45	emersion	i'm not a huge fan of (1) for sure
2022-03-14 22:35:01	emersion	i don't want to have an SVG parser in something as critical as a compositor
2022-03-14 22:35:43	emersion	and yeah, the flexibility is reduced greatly with (1) and (2), but it's also a simpler problem to solve :P
2022-03-14 22:37:32	twitchyliquid64	As a starting point, could we aim to start with just titlebars (ie: `container->title_focused` and friends) rather than the full set of decorations? Or is it easier just to lump it all into one surface rather than borders and titlebar and marks all separately
2022-03-14 22:38:53	emersion	if you want to start experimenting right away, it might be a good start (especially if you're new to all these things)
2022-03-14 22:39:31	emersion	have you read the wayland book?
2022-03-14 22:40:42	twitchyliquid64	A while back (im familiar with the concepts) but its probably time for another read
2022-03-14 22:43:55	vyivel	emersion: not sure if i like the idea of separate client being responsible for decorations tbh
2022-03-14 22:44:11	vyivel	a library to help with managing this kind of stuff, maybe
2022-03-14 22:44:49	vyivel	wouldn't put in wlroots
2022-03-14 22:47:46	twitchyliquid64	Hmm, how else would you implement it (flexibility in rendering titlebars and the like) short of forking sway?
2022-03-14 22:49:22	ifreund	emersion: I'd lean towards 2) myself. It keeps the code parsing stupidly the complex svg file format outside of the compositor process but doesn't introduce the IMO unnecessary complexity of rending all parts of the decorations in the client
2022-03-14 22:49:48	vyivel	twitchyliquid64: perhaps with something like libdecoration but on the server side
2022-03-14 22:50:22	ifreund	if all parts of the decorations were rendered in the client I think it'd also result in lots of synchronous round trips to get new decorations on focus/urgency/etc
2022-03-14 22:51:02	vyivel	that is, if we're discussing flexible decorations; for just an icon, a sway/wlroots-specific helper client is totally fine by me
2022-03-14 22:58:57	emersion	vyivel: we don't really want to do stuff as complex as rendering fancy titlebars in the compositor though
2022-03-14 22:59:48	vyivel	why not?
2022-03-14 23:00:10	emersion	if the compositor goes down, the whole session is toast
2022-03-14 23:00:15	emersion	thus the compositor needs to be robust
2022-03-14 23:01:13	emersion	robust = doesn't do complex operations (which will take time, slowing down everything else), and doesn't parse heaps of untrusted data with complicated logic (PNG/JPG/SVG)
2022-03-14 23:01:58	emersion	exhibit 1: GNOME does all of this in the main compositor thread, and more (JS engine for their extensions)
2022-03-14 23:02:12	bl4ckb0ne	any compositor maintainer here using the device field of the wlr_event_switch_toggle https://gitlab.freedesktop.org/wlroots/wlroots/-/blob/104060fec57bec2a282c52f7e849f40fd1b1b45e/include/wlr/types/wlr_switch.h#L41
2022-03-14 23:02:18	vyivel	gnome shouldn't be used as an example of good software
2022-03-14 23:02:20	emersion	it's a bad design decision but they can't easily revert it
2022-03-14 23:03:08	kennylevinsen	Hmm drawing decorations in a separate client sounds cool but also like true synchronization hell
2022-03-14 23:03:13	vyivel	^
2022-03-14 23:03:24	emersion	yeah, the synchronization part of it is pretty scary
2022-03-14 23:03:35	vyivel	if not sync i'd be fine with it
2022-03-14 23:04:31	vyivel	maybe could slap xdg-foreign in this somehow, if it wasn't so limited
2022-03-14 23:07:29	kennylevinsen	A client could send us a raster of a titlebar segment with alpha that we blend over the titlebar (and also contains the text, removing pango), but I am not sure if it is worth the complexity
2022-03-14 23:07:59	kennylevinsen	Otherwise we'd definitely be relying on transactions heavier to synchronize client changes to the decorator
2022-03-14 23:09:33	vyivel	just run every client in a nested compositor which draws decorations as it wants ezpz
2022-03-14 23:10:26	 *	kennylevinsen pulls vyivel's power cable out
2022-03-14 23:11:32	vyivel	i run on battery :p
2022-03-14 23:12:14	kennylevinsen	don't run on the battery, it's fragile
2022-03-14 23:12:28	vyivel	-_-
2022-03-14 23:12:32	bl4ckb0ne	all in favour of yeeting the input device from wlr_switch_toggle_event?
2022-03-14 23:12:43	 *	twitchyliquid64 yeets in australian]
2022-03-14 23:13:18	vyivel	people who choose to support switch devices probably have code complex enough to store the device somewhere else anyway
2022-03-14 23:16:50	twitchyliquid64	On the topic of offloading raster to separate clients, is there a reason why the sway bar has its own funky protocol as opposed to being a wayland extension + client?
2022-03-14 23:17:18	vyivel	funky protocol?
2022-03-14 23:18:25	vyivel	afaik it's just layer-shell + sway ipc for workspaces
2022-03-14 23:21:17	twitchyliquid64	vyivel: The JSON protocol thingy
2022-03-14 23:21:18	twitchyliquid64	https://github.com/swaywm/sway/blob/master/swaybar/swaybar-protocol.7.scd
2022-03-14 23:22:01	kennylevinsen	Ah that's an i3 thing
2022-03-14 23:22:22	kennylevinsen	Or wait is it
2022-03-14 23:22:34	vyivel	yep
2022-03-14 23:22:34	vyivel	https://i3wm.org/docs/i3bar-protocol.html
2022-03-14 23:23:37	emersion	it's for communication between swaybar and the status_command
2022-03-14 23:23:42	emersion	not between sway and swaybar
2022-03-14 23:23:52	emersion	it basically carries the bar text
2022-03-14 23:23:59	emersion	which swaybar will render
2022-03-14 23:27:18	twitchyliquid64	Ahhhh gotcha
2022-03-14 23:27:56	twitchyliquid64	Okay heres a cursed idea
2022-03-14 23:28:19	twitchyliquid64	what if sway supported loading a shared library which implemented decorations or raster of titlebars and the like
2022-03-14 23:28:44	vyivel	as in, finding and loading the library in runtime?
2022-03-14 23:29:02	twitchyliquid64	yeah dl_open, and then calling some raster_titlebar()
2022-03-14 23:29:16	twitchyliquid64	the shared library to use can be configured in the sway config or soemthing like that
2022-03-14 23:29:39	vyivel	ehhhh
2022-03-14 23:29:43	emersion	dlopen hell :S
2022-03-14 23:29:47	vyivel	this sounds even less robust
2022-03-14 23:29:49	kennylevinsen	if it's just a transparent chunk we can overlay with the text and image then it could be an executable writing it to stdout that we call
2022-03-14 23:30:05	kennylevinsen	Once when we find it appropriate and cache the output
2022-03-14 23:30:28	vyivel	what if the executable prints out 1 byte per hour
2022-03-14 23:30:34	vyivel	will it slow down the compositor?
2022-03-14 23:31:03	kennylevinsen	in that case I think you deserve the resulting sluggishness for intentionally adding that sleep
2022-03-14 23:31:12	<--	twitchyliquid64 (~twitchyli@c-24-6-228-142.hsd1.ca.comcast.net) has quit (Quit: Client closed)
2022-03-14 23:31:15	kennylevinsen	Or alternatively you really need a new computer
2022-03-14 23:31:28	-->	twitchyliquid64 ([https://web.libera.chat] twitchyliquid64) (~twitchyli@c-24-6-228-142.hsd1.ca.comcast.net) has joined #sway-devel
2022-03-14 23:31:43	emersion	kennylevinsen: exec'ing one executable per toplevel doesn't seem very fun
2022-03-14 23:31:48	kennylevinsen	it could also send an fd we can import or something...
2022-03-14 23:32:02	kennylevinsen	emersion: but only once/on title change though
2022-03-14 23:32:27	vyivel	feeling like we're two steps away from reinventing x11's "server + wm" model
2022-03-14 23:32:49	twitchyliquid64	vyivel: emersion: I think for dl_open if people use that feature they accept the resulting bugs they introduce?
2022-03-14 23:33:35	twitchyliquid64	Yeah Im in camp 'one offload process per sway instance' rather than fork/exec every time we need a raster. But agree everytime we talk about doing it via stdin it sounds like we reinvent wayland all over again
2022-03-14 23:33:36	kennylevinsen	the idea here was not to have it as an optional feature, it would be the only way title bars are made so we can remove Cairo/pango from sway
2022-03-14 23:34:35	emersion	i don't care that much about removing pango/cairo, it would've been a nice side-effect but it's not the end of the world to have these
2022-03-14 23:35:00	emersion	but yeah ideally there is only one way the titlebars get generated
2022-03-14 23:35:27	emersion	and we don't duplicate the code between "fancy" and "baseline" titlebars
2022-03-14 23:37:54	emersion	in any case, the (ugh) dlopen idea wouldn't buy much in terms of synchronization
2022-03-14 23:38:31	emersion	the process of rendering the titlebars would need to be async because it could take a while and we don't want to block the whole compositor
2022-03-14 23:38:41	emersion	and then we end up with the same issues as a helper wayland client
2022-03-14 23:39:08	twitchyliquid64	What is it currently? Synchronous no?
2022-03-14 23:39:20	emersion	yes, but the titlebars are guaranteed to be very simple
2022-03-14 23:39:27	emersion	solid color + one texture
2022-03-14 23:42:12	twitchyliquid64	I wonder how terrible it would be if we kept the current sway implementation (solid color + texture) in the hot path, but let the 'decorations client' push a new texture or something at any time?
2022-03-14 23:42:35	twitchyliquid64	Could look jittery like the swaybar on startup tho
2022-03-14 23:42:37	emersion	it would look pretty bad when resizing
2022-03-14 23:42:55	emersion	"every frame is perfect with wayland" ™
2022-03-14 23:43:20	twitchyliquid64	whelp
2022-03-14 23:43:25	twitchyliquid64	this is a hard-ass problem

@twitchyliquid64
Copy link

To summarize from chatting with the core-devs over IRC, we don't seem to have a great path forward:

  • The core of the issue is synchronization: Wayland expects frame perfection, but if you delegate something as core as titlebars to another process, you need to synchronize. And what if the delegated process is too slow to yeet back rasterized surfaces before the next scan-out? then you either need to block the compositor, or deliver imperfect frames. Both of these are undesirable.
  • The current implementation works because of its simplicity. Rendering a solid color + some pango text is super simple, so it can stay in the hot path and then we never need to deliver imperfect frames, and the blocking of the compositor from this has never been an issue.
  • Simultaneously, if we were going to go ahead and do this, the right place for it would be a new wayland protocol, because inventing anything else would mostly be re-inventing a lot of the concepts from Wayland into a new protocol.

So what do? The default (and implicitly accepted path) is to stay the course: maintain the status-quo where core textures needed to composite windows (ie: titlebars) require no synchronization with an outside client and are done in the hot-path. It doesn't appear that we have agreement amongst devs/contributors on changing that, and its a reasonable architectural choice to make, but it does imply that features like this arent possible.

@WhyNotHugo
Copy link
Contributor

The core of the issue is synchronization: Wayland expects frame perfection, but if you delegate something as core as titlebars to another process, you need to synchronize. And what if the delegated process is too slow to yeet back rasterized surfaces before the next scan-out? then you either need to block the compositor, or deliver imperfect frames. Both of these are undesirable.

Sounds like this delivers perfect frames, at a price of never allowing out-of-compositor decorations.

The current implementation works because of its simplicity. Rendering a solid color + some pango text is super simple, so it can stay in the hot path and then we never need to deliver imperfect frames, and the blocking of the compositor from this has never been an issue.

Removing pango and fontconfig dependencies can also reduce complexity for sway.

Simultaneously, if we were going to go ahead and do this, the right place for it would be a new wayland protocol, because inventing anything else would mostly be re-inventing a lot of the concepts from Wayland into a new protocol.´

I agree.


How do other DEs delegate decorations without compromising on perfect frames?

@WhyNotHugo
Copy link
Contributor

Also, could some wayland-protocol proxy do decorations and synchronisation on its own? That is, by exposing a different wayland socket to clients.

@emersion
Copy link
Member

How do other DEs delegate decorations without compromising on perfect frames?

They mostly don't.

  • GNOME doesn't support server-side decorations. Not sure what they do for X11 clients, perhaps the same as Weston.
  • KWin has in-house decorations only.
  • Weston doesn't support server-side decorations for Wayland clients, it draws decorations only for X11 clients via the X11 protocol (ie, by asking the X11 server to render them).

Also, could some wayland-protocol proxy do decorations and synchronisation on its own? That is, by exposing a different wayland socket to clients.

Would be very complicated.

@PAI5REECHO
Copy link

Note, i3 doesn't need all of this, because X11 clients upload their icon pixel data themselves to the X11 server as a window property. Wayland doesn't do such things (for good reasons!), but that means more work for Sway.

Maybe a bit off-topic, but what good reasons?

Sorry, but can you elaborate on this a little? I haven't read the Wayland book, nor do I have any knowledge about Wayland's protocol design, but this seems like a rather odd/regressive design decision.

The core of the issue is synchronization: Wayland expects frame perfection, but if you delegate something as core as titlebars to another process, you need to synchronize. And what if the delegated process is too slow to yeet back rasterized surfaces before the next scan-out? then you either need to block the compositor, or deliver imperfect frames.

I understand that synchronization is required but why would this need to block the compositor? I don't see any issue with having the icon being rendered once/if/whenever the data becomes available. It can render the titlebars as they are now with no icon and if the surrogate process takes even say 10, 20, or 30 seconds to get the icon then so be it, just render it once it's available no matter how ridiculously long it takes. Having icons, even if they don't render immediately, is better than no icons at all. Also, I agree that delivering imperfect frames is unacceptable, I now understand the technical limitations surrounding this feature.

@emersion
Copy link
Member

emersion commented Mar 30, 2022

Sorry, but can you elaborate on this a little? I haven't read the Wayland book, nor do I have any knowledge about Wayland's protocol design, but this seems like a rather odd/regressive design decision.

No, this isn't the place to discuss this.

I understand that synchronization is required but why would this need to block the compositor?

Synchronization doesn't mean blocking the compositor. It means that the updates of the client surface and the decorations are synchronized, and happen atomically, to ensure there are no glitchy frames displayed to the user. The main concern is that this adds substantial complexity.

@adrusi
Copy link

adrusi commented Apr 17, 2022

What are people's thoughts on designing the protocol in such a way that for simple window decorations clients like what sway would presumably ship by default, the consequences of a failure of synchronization are minor (either perfect or minimally imperfect frames), and users who choose to use fancier window decorations may end up with more noticeably imperfect frames if their decorations client can't keep up?

As I understand, the state which would need to be synchronized between the compositor and the decorations client is:

  • window titles, which window is active, which window is frontmost in each container, which windows have alerts, possibly everything returned by swaymsg -t get_tree
  • dimensions of the decorations surfaces, whatever those end up being defined as
  • possibly user interaction with decorations elements

The most likely culprit for noticeably imperfect frames is loss of synchronization in surface dimensions, which could cause resized containers to have unrendered regions of their borders, or in the case of e.g. center-aligned text and tabbed container titles, cropped or missing window titles.

The maximally flexible protocol design would allow the decorations client to negotiate, for any container, how much space it gets to draw on any side. This approach is great for my personal agenda, because I'd like to co-opt the stacked layout to implement vertical tabs in the style of firefox's tree-style-tabs extension. However —

An alternative would be to give the compositor more control over which decorations surfaces get to exist. Currently, as I understand (and I might misunderstand), you can categorize containers into two classes based on what decorations they have:

  • containers with no decorations (like an application window inside of a tabbed or stacked container)
  • containers with optional borders on the left, right and bottom, with 0 or more window titles arranged in some manner on the top side.

Here is an outline of a minimum viable protocol that would minimize the imperfections caused by failures of synchronization:

The compositor gets to decide which decorations surfaces exist. Each container that gets decorations gets three surfaces: left, right and bottom borders. Additionally, each application window gets one decorations surface, namely its title. In order to accommodate resizing of containers without rendering obviously bad frames in the case of lost synchronization, each of these surfaces is larger than it needs to be. Window-title and bottom-border surfaces are all as wide as they might ever possibly be — maybe as wide as the widest output, maybe as wide as the widest row of pixels in the output arrangement. Left and right borders are similarly maximally tall. The compositor notifies the decorations client of the actual rendered regions of these surfaces at any given time, but the client is expected to draw something useful in the rest of the surface just in case synchronization is lost. The compositor never blocks on decorations redraws, instead always rendering the decorations surface clipped to the needed dimensions.

Advantages

  • The default decorations are solid colors for borders with left-aligned text on a solid background for window titles. The default decorations client could feasibly ignore all information about the actual rendered size of each surface and let the compositor clip them as needed.
  • Various oft-requested features can still be accommodated: icons in titles, rounded borders, etc. Although decorations clients providing e.g. rounded borders would need to be good at maintaining synchronization to avoid obviously imperfect frames when a container is resized.

Disadvantages

  • Memory usage.
  • Not maximally flexible, couldn't accommodate e.g. my wishes for vertical tabs on the left side of the container without additional protocol complexity.

That's my analysis anyhow. I lack experience with wayland and might well have missed something.

@WhyNotHugo
Copy link
Contributor

So it seems that synchronisation issues are a blocker for delegating all decorations to a dedicated/privileged client.

The original issue here is just about showing icons in titlebars. I'd like to re-focus discussion on that.

I'm thinking on an approach as follows:

  • Add a new protocol. Let's call this protocol ext-icon-manager for now. It implements:
    • A set_icon(toplevel: zwlr_foreign_toplevel_handle_v1, icon: wl_surface) request.
    • A icons_size(size: uint) event, which indicates which size all icons should have.
  • Have a privileged client use wlr-foreign-toplevel-management-unstable to enumerate all toplevels.
  • That same priviledged client uses the above described set_icon request to set icons for known applications. How it determines which icons to use is implementation specific (note that it'll have access to title and app_id).
  • wlr-foreign-toplevel-management already enabled a privileged client to keep track of all existing clients, so no need to do anything there.

On the sway side:

  • This just requires rendering on more surface, no parsing PNG or SVG or anything.
  • Render the icon on the titlebar if we have one, don't render the icon if we don't.

This protocol is perfectly usable by other compositors too. FWIW, a well-written icon-manager-helper could also be cross-compositor.

Some points worth discussing:

  • Is it safe to assume that all clients will have icons with the same size? Or is the protocol being artificially limited for some other scenario here?
  • This approach expects the privileged client to proactively send icons for all toplevels. Is it maybe better for the compositor to request them explicitly instead? Requesting them with an event could allow the compositor to specify the size for each one, but I'm not sure that's flexibility that we need.

@mildred
Copy link

mildred commented Jan 2, 2023

Just for the record, color fonts now can embed SVG documents which in itself can contain bipmap image data...

It seems that drawing fonts is (or soon might be) more complex than drawing simple images... https://pixelambacht.nl/2014/multicolor-fonts/

edit: This makes me think that perhaps implementing icons on the titlebars could be done by an external process that would transform the icon from the window into a font and return to sway the font to use as well as the glyph to use within the font, and this could be done.

However, it seems sway has to be restarted completely (not just reloaded) to get it to accept a new font. There is probably a call somewhere to make to refresh the font list.

@mildred
Copy link

mildred commented Jan 3, 2023

What are people's thoughts on designing the protocol in such a way that for simple window decorations clients like what sway would presumably ship by default, the consequences of a failure of synchronization are minor (either perfect or minimally imperfect frames), and users who choose to use fancier window decorations may end up with more noticeably imperfect frames if their decorations client can't keep up?
#4882 (comment)

Seems like a good idea, however I don't think we need to go to the length of drawing all the borders and corners. I'm perfectly fine having this fixed in sway or configurable by simple options. What we might need instead is to draw the content of the titlebar itself.

The simpler version of the protocol could be:

  • The compositor gets to decide which decorations surfaces exist and their sizes.
  • each application window gets one decorations surface, namely its title, excluding the borders drawn by the compositor
  • In order to accommodate resizing of containers without rendering obviously bad frames in the case of lost synchronization, last column of pixels in the surface should be repeatable so it can extend (obviously the text would wait the synchronization to show up

This keep things simple. The only drawback compared to the current state is that when the titlebar is extended, there might be a loss of synchronization that would delay showing up the rest of the text, but it should not be that noticeable and if we want to separate the text rendering to a separate process, this is something can will necessarily happen (unless we take the decision to render all of the text even if not shown). Shrinking the titlebar would not cause any visual imperfection as the title would be clipped as of today.

If we want to extend the protocol to draw the borders, the process that draws the decoration can draw a larger surface that could be cut in four (vertically and horizontally) and in place of the cuts, the compositor would extend the pixels. I do not really imagine a use case where the border could not be drawn like this. But then with drawing borders, we will want to also tell which parts are clickable and which parts should trigger a window resize, ...

edit: for the simple version:

  • let's add a protocol wlr-decoration-shell that a decorator can use
  • the decorator would use wlr-foreign-toplevel-management-unstable to enumerate toplevels
  • A new event wlr-foreign-toplevel-management-unstable::title-size will tell about the titlebar size (width and height)
    (or perhaps this should be in wlr-decoration-shell)
  • the decorator can send a surface via wlr-decoration-shell::set-title(toplevel: zwlr_foreign_toplevel_handle_v1, surface: wl_surface)
  • the compositor can freely clip the surface if it is too big for its title decoration, and can freely extend the last row/column of pixels if it is too small

@iguanajuice
Copy link

iguanajuice commented Nov 26, 2023

@hasufell you could try something like this:

for_window    [app_id="(?i)firefox"]            title_format "<span foreground='#FF6611'><tt></tt></span> %title"
for_window    [app_id="Alacritty"]              title_format "<span foreground='#00FF00'><tt></tt></span> %title"
for_window    [app_id="telegramdesktop"]        title_format "<span foreground='#84b3ff'><tt></tt></span> %title"

I like the idea of this; but manually setting each icon is very tedious.

So I decided to make this repo: https://github.com/iguanajuice/sway-font-awesome

Right now, it only adds icons to apps that I personally use. Please open issues for apps that I haven't added an icon for yet (which is a lot of them), if you're interested.

@allie-wake-up
Copy link

@hasufell you could try something like this:

for_window    [app_id="(?i)firefox"]            title_format "<span foreground='#FF6611'><tt></tt></span> %title"
for_window    [app_id="Alacritty"]              title_format "<span foreground='#00FF00'><tt></tt></span> %title"
for_window    [app_id="telegramdesktop"]        title_format "<span foreground='#84b3ff'><tt></tt></span> %title"

I like the idea of this; but manually setting each icon is very tedious.

So I decided to make this repo: https://github.com/iguanajuice/sway-font-awesome

Right now, it only adds icons to apps that I personally use. Please open issues for apps that I haven't added an icon for yet (which is a lot of them), if you're interested.

I wrote a little rust app for this a while back also. It has a bunch of icons defined in the default config and I'd gladly accept PRs with more set. Setting icons in the sway config is probably preferable for a lot of use cases, but if you want to change the icon based on window title changes for instance (like to change a terminal icon to a vim icon), as far as i know an app is necessary: https://github.com/allie-wake-up/swaycons

@sripwoud
Copy link

@tmccombs
Copy link
Contributor

Sorry, but can you elaborate on this a little? I haven't read the Wayland book, nor do I have any knowledge about Wayland's protocol design, but this seems like a rather odd/regressive design decision.

No, this isn't the place to discuss this.

Why not? My first thought on how to implement icons in the titlebar would be to have a protocol to allow the client to give the compositor a surface to use for the icon, similar to setting the cursor shape. And allow the application to update the icon, so it can use it to indicate status.

The problem with that is it isn't very useful unless most applications implement it. And since gnome only supports client side decorations it is unlikely gtk would support such a protocol.

With the proposal for a separate decorations app, I'm not sure how it would know what icon to use. Does determine it based on the app id? If so, that means an app can't dynamically change the icon, or use different icons for different windows . Both of which I think are possible in X. How does KDE determine the icon to use?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or incremental improvement i3-compat Sway doesn't match i3's behavior
Development

No branches or pull requests