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

i3bar: protocol for workspace buttons #3818

Closed
xzfc opened this issue Oct 10, 2019 · 33 comments · Fixed by #4311
Closed

i3bar: protocol for workspace buttons #3818

xzfc opened this issue Oct 10, 2019 · 33 comments · Fixed by #4311
Assignees
Labels
accepted Has been approved and is ok to start working on enhancement requires-configuration This feature request requires new configuration

Comments

@xzfc
Copy link
Contributor

xzfc commented Oct 10, 2019

Proposal

I am proposing to add ws_command option to i3bar. It should be similar to status_command but for controlling workspace buttons instead of statusline blocks.

This would allow the user to define arbitrary complex customizations without introducing actual complexity into the i3bar code or i3bar configuration syntax.

Examples of customizations are:

Examples of per-button customizations:

  • "min_width":32 (related to Minimal width for workspace buttons #3711)
  • "separator":true — personally I find it is useful to visually separate groups of workspaces.
  • "color":[...] — could be used to distinguish fake empty workspaces.

Diagram

i3bar_ws

Example configurations

bar {
	ws_command ~/bin/ws_command_default.sh
}

ws_command_default.sh - recreate the default i3bar behavior.

#!/bin/sh
i3-msg -t subscribe -m '["workspace"]' | {
	i3-msg -t get_workspaces;
	while read; do i3-msg -t get_workspaces; done;
}

ws_command_hide.sh - hide workspace named foo unless it is visible.

#!/bin/sh
i3-msg -t subscribe -m '["workspace"]' | {
	i3-msg -t get_workspaces;
	while read; do i3-msg -t get_workspaces; done;
} | jq -c '[ .[] | select(.name != "foo" or .visible) ]'

ws_command_show_empty.sh - show empty workspaces foo and bar on LVDS1 even if they do not exist at the moment.

#!/bin/sh
i3-msg -t subscribe -m '["workspace"]' | {
	i3-msg -t get_workspaces;
	while read; do i3-msg -t get_workspaces; done;
} | jq -c '
	def fake_ws(name): {
		num: -1, name: name,
		visible: false,
		focused: false,
		urgent: false,
		output: "LVDS1",
		"colors":["#191919", "#111111", "#444444"], # dimmed inactive_workspace
	};
	. + [ fake_ws("foo"), fake_ws("bar") ] | unique_by(.name)
'
@orestisfl
Copy link
Member

I like the idea and since we have the infrastructure to support IPC and JSON parsing this will not be very complex. @Airblader will have to approve though.

Btw, are you willing to implement this?

@xzfc
Copy link
Contributor Author

xzfc commented Oct 10, 2019 via email

@Airblader
Copy link
Member

Yes, I think this is a great, extensible solution. I'd say we for now start with a protocol that only covers what we currently need and leave additional features (such as separators) for follow-up work. So it would be good to define what that protocol could look like and then get the PR going.

Something we need to decide is whether coloring focused / urgent workspaces is left up to that interface as well or whether this will still be done by i3bar.

@Airblader
Copy link
Member

Another thing, I would not support multiple protocols here like we do in the status command and go for JSON right away.

@ammgws
Copy link
Contributor

ammgws commented May 28, 2020

@xzfc Just wondering if you made any progress on this?

@ymolists
Copy link

ymolists commented Jun 10, 2020

@xzfc I am trying to get clarifications around the design so please bear with me if i am missing some parts. The way i see it this is pushing the complexity to people who are customising i3 in a very significant way. Here is my use case :

bindsym $mod+F1 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 1 
bindsym $mod+F2 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 2
bindsym $mod+F3 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 3
bindsym $mod+F4 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 4
bindsym $mod+F5 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 5
bindsym $mod+F6 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 6
bindsym $mod+F7 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 7
bindsym $mod+F8 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 8
bindsym $mod+F9 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 9
bindsym $mod+F10 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 10
bindsym $mod+F11 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 11
bindsym $mod+F12 exec --no-startup-id /opt/i3/sbin/i3ws.sh --wsgrp 12

wsgroup is a grouping of wspaces with each having a unique id. Each func keys basically maps to one single ws group.

The logic to managing all these is handled by the script internally. The script does not store state outside of i3 for all the existing wsgroup at all. Instead it stores this metadata as part of the i3 wspace name so effectively the wspace name is <ws_id>:<ws_name>:<groupid>:<hide_suffix>
This script works because in my local i3 branch i added a way to hide a ws if the ws name has a fixed suffix as part of the name.

This proposal would make writing simple bindings/scripts like the one above i have more complicated because it has to be able to sync whit whatever ws_command_hide.sh script is called behind the scene.

Can someone tell me how i can make sure the binding i have above would work in the new scheme ? I might be missing something.

@ymolists
Copy link

I thought the i3ws.sh and ws_command_hide.sh had to be in sync and be coupled somehow. I am starting to see they actually do not need to. Starting to see the light !

@xzfc
Copy link
Contributor Author

xzfc commented Jun 14, 2020

@ymolists
I see it this way:
Both i3ws.sh and ws_command_hide.sh have to be in sync in the implementation sense. That is, i3ws.sh should rely on the behavior of particular ws_command_hide.sh.

But the following much the same as what you describe.
They don't have state outside of i3. i3ws.sh would add some particular suffix to workspace names that have to be hidden; and ws_command_hide.sh would hide workspaces with this particular suffix.

@RafalSkolasinski
Copy link

Hi,

Is there any already existing mechanism that would allow me to hide specified workspaces on the bar?

I am very much looking towards that feature.

@orestisfl
Copy link
Member

Hi,

Is there any already existing mechanism that would allow me to hide specified workspaces on the bar?

No, see the patches in #2333 for workarounds

@ymolists
Copy link

ymolists commented Nov 3, 2020

@xzfc Just wondering if you made any progress on this? I cant wait to start using an official supported way to hide workspaces.

@Airblader Airblader added tentatively_accepted This feature has been previously accepted, but needs to be re-evaluated now. and removed accepted Has been approved and is ok to start working on labels Dec 31, 2020
@orestisfl orestisfl added accepted Has been approved and is ok to start working on requires-configuration This feature request requires new configuration and removed tentatively_accepted This feature has been previously accepted, but needs to be re-evaluated now. labels Jan 2, 2021
@orestisfl orestisfl assigned orestisfl and unassigned xzfc Jan 4, 2021
@Stardust-kyun
Copy link

Would this only be available for i3bar, polybar's i3 module, and similar workspace indicators, or would it work with workspace indicators like the xworkspaces module for polybar? Not sure if I explained that well enough, but hopefully you can tell what I meant.

@Airblader
Copy link
Member

This is purely i3bar, nothing else. Any other client is already free to display (or not display) whatever they choose.

@Stardust-kyun
Copy link

This is purely i3bar, nothing else. Any other client is already free to display (or not display) whatever they choose.

I actually forgot to specify what for! From what I understand, other clients like polybar are unable to display empty inactive workspaces because of i3 dynamically loading them, so I was wondering if the example of "show empty workspaces" would work with other clients.

@orestisfl
Copy link
Member

orestisfl commented Jan 19, 2021 via email

@Airblader
Copy link
Member

Clients which strictly show workspaces based on EWMH will not show such workspaces since they don't exist and thus we don't list them in the hints. This feature won't change anything about that, no.

@Stardust-kyun
Copy link

Ah, I see. Do either of you know of any way that I can create dummy workspaces for xworkspaces or the like to somewhat create that?

@Airblader
Copy link
Member

I don't even know that tool. Regardless, you can ask that question on the i3wm subreddit. Let's please keep the discussion here on topic.

@Stardust-kyun
Copy link

Alrighty, sorry for the confusion. Thanks!

@MarcosCosmos
Copy link

MarcosCosmos commented May 28, 2021

Clients which strictly show workspaces based on EWMH will not show such workspaces since they don't exist and thus we don't list them in the hints. This feature won't change anything about that, no.

I am confused here... Do you mean to imply that there is already a way for clients to query the configured (but not existent) workspaces known to i3, or, else that such a feature is out of scope?

I understand that erasing empty workspaces is long standing behaviour and I expect changing that would surely be a breaking change, but I get the (possibly mistaken) impression that you intend to make internal information available to i3-bar exclusively, which seems incongruous?

Third-party tools may be free to display anything they like but, and I am happy to be disproven: it seems to me that (perhaps like i3-bar) almost all, if not all, clients that aren't entirely manual/static in the content they display, are designed to assume that the WM has exclusive authority over what information can be be displayed in the layout, including workspaces. I would argue, in fact, that this is necessary, in order to display dynamic content (which is to say, all content, with how i3 is designed).

@Airblader
Copy link
Member

Airblader commented May 28, 2021

There are no "configured workspaces". Workspaces are created when you switch to them and exist for as long as there are windows on them or they are active on an output. Otherwise they don't exist, and thus also cannot be queried. That's true both externally and internally – i3bar doesn't know about them either, they simply do not exist.

@MarcosCosmos
Copy link

MarcosCosmos commented May 28, 2021

I was referring to the "show empty workspaces" feature which I see on the OP, has that been excluded from this issue, then?

@Airblader
Copy link
Member

Airblader commented May 28, 2021

Currently, i3bar pulls its information on which workspaces exist from i3, which is fed by its internal state. With this PR you have a protocol such that you can define yourself where this information comes from. This allows you to enrich the information you query from i3's IPC with non-existing workspaces, or replace it entirely, which means those workspaces would be shown in i3bar.

A feature like "show empty workspaces" cannot possibly be implemented, because empty workspaces don't exist in the first place. With this protocol you can choose how you want to implement it:

  1. You could simply hard-code a list of workspaces to be shown in i3bar.
  2. Alternatively, a list of hard-coded workspaces merged with those which exist based on i3's IPC response.
  3. Or you could listen for new workspace events, build up a set of workspaces which existed but never remove from that list, which basically means your i3bar will show all workspaces which existed at some point.

@MarcosCosmos
Copy link

MarcosCosmos commented May 28, 2021

To clarify, I understand well enough that an empty workspace cannot exist in the sense that workspaces must be destroyed when they empty, as that is your convention.

However, it appears as though this PR would introduce an analogous or an adjacent concept, specific to i3, and only in respect to the information emitted via IPC, is that correct?

It seems like in your most recent comment, you are saying I would be able to feed artificial information into the IPC that other clients can then receive?

I do not use i3bar currently; I don't know it would suit my needs (this issue aside); But I am not actually aware of any client/bar that would allow me to configure a manual set of workspaces without managing all IPC interactions myself.

I recently switched to i3 to make use of it's mode switching, and found the lack of empty workspaces made it severely more time consuming to determine which, of the workspaces pinned to an output are free to use.

On that note, these pinned workspaces, I would argue, ARE in fact configured and, as far as client are concerned, differ only in that said configuration cannot be observed when the workspace is out-in-use.

The fact that this configuration is accessible only when in use is arguably part of the semantics of i3 and so, of course, any i3-aware client will naturally adopt the same model. The proposed IPC changes seem useful, but I don't actually see how they assist in the display of a pseudo-statically list of (potential) workspaces any more than not having these changes would? - It seems that it would not allow for any differentiation between a current and future workspace, without including third-party information tags, which standard clients would be unable to register.

In that sense it may actually introduce more problems than it solves.

Edit: it would probably be more useful to provide a feature that queries the output a non-existent workspace with a particular name has been configured to pin to, if any.

@Airblader
Copy link
Member

It seems like in your most recent comment, you are saying I would be able to feed artificial information into the IPC that other clients can then receive?

No – this protocol does not feed the IPC. It feeds i3bar.

But I am not actually aware of any client/bar that would allow me to configure a manual set of workspaces without managing all IPC interactions myself.

I don't know of one either, but this is really outside our control. We will not implement a feature to keep empty workspaces, this is the most we want to do to support it, but it requires i3bar. For other clients you'll have to raise feature requests to allow specifying workspaces to be shown despite not existing.

@MarcosCosmos
Copy link

MarcosCosmos commented May 28, 2021

For other clients you'll have to raise feature requests to allow specifying workspaces to be shown despite not existing.

I made an edit to my last post that is relevant on this point:

Edit: it would probably be more useful to provide a feature that queries the output a non-existent workspace with a particular name has been configured to pin to, if any.

This pinning information is something that clients need to honour, to show the workspace on the correct bar instance; Without it, no client-side solution would be complete.

@Airblader
Copy link
Member

I don't think I understand your edited-in sentence. Can you elaborate?

@MarcosCosmos
Copy link

MarcosCosmos commented May 28, 2021

Certainly. Consider, for example, the config line:

workspace "1:a" output HDMI1

This is persistent configuration information within i3 but exposed, to my knowledge, only when the workspace is in use.

It is, for the purposes of any IPC clients, functionally equivalent analogous to the presence of any empty workspace. I am not concerned in the slightest with what you expose via EWMH, but this output pinning is important information that I believe should be exposed via IPC.

@Airblader
Copy link
Member

I think what you're looking for is something you will get from #4427.

@MarcosCosmos
Copy link

Yes, that would certainly suffice, thank you!

@ymolists
Copy link

I cant wait for this feature. Can someone summarise the state it is in now ? Thank you for all your efforts !

@orestisfl
Copy link
Member

There is PR #4311 that mostly works but I need to handle some issues regarding reading input line-by-line. ETA unknown.

@ymolists
Copy link

@orestisfl i am still hopeful someone will review/complete that PR !!!

orestisfl added a commit that referenced this issue Jan 22, 2023
Closes #3818 (parent issue)
Fixes #1808
Fixes #2333
Fixes #2617
Fixes #3548
orestisfl added a commit that referenced this issue Jan 22, 2023
Closes #3818 (parent issue)
Fixes #1808
Fixes #2333
Fixes #2617
Fixes #3548
desmana pushed a commit to desmana/i3 that referenced this issue Feb 27, 2023
jbenden pushed a commit to jbenden/i3 that referenced this issue Jun 7, 2023
@orestisfl orestisfl mentioned this issue Sep 21, 2023
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted Has been approved and is ok to start working on enhancement requires-configuration This feature request requires new configuration
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants