Skip to content
This repository has been archived by the owner on Nov 1, 2021. It is now read-only.

WIP: Added wlr-workspace-unstable-v1.xml #35

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

chrisjbillington
Copy link

This is a draft for addressing issue #10.

I likely don't have the C chops to contribute much to wlroots' code (though I might try), but maybe I can talk about protocols.

To accommodate both compositors that have workspaces spanning all outputs, as well as those that have each output with its own independent set of workspaces, this protocol has the concept of 'workspace groups'. A workspace group is a set of outputs that share workspaces. Each output may belong to at most one group. Each workspace group has one active workspace at any one time. This allows arbitrary grouping of outputs, including the two common cases of all outputs sharing a group and of each output being its own group.

There is more to think about here.

Is the protocol sufficient for required atomicity? If an output moves to a different workspace group, then the 'each output may belong to at most one group' requirement will be violated from the perspective of the client until both an output and an output_remove event are processed on the two zwlr_workspace_group_handle_v1 objects. But the compositor can refrain from sending done events until both of these events are sent, so we could say that if the client gets an output or output_remove event, it must wait for the done event before it has a consistent state for what groups all the outputs belong to.

Similarly with zwlr_workspace_handle_v1, if a workspace changes what its number is, the client must wait for the done event in order to see that the 'workspaces are sequentially numbered from zero' requirement is satisfied.

I am also a bit confused about destroy events and requests. If you request to destroy an object, you're just asking to clean up resources - you're not asking the compositor to remove a workspace or whatnot. However, if the compositor does remove a workspace (not just move it to a different workspace group), does it send a destroyed event?

I suspect the general ideas in this protocol are pretty unobjectionable, but potentially more contentious things that I haven't included are:

Workspaces are simply numbered here. Should it be left that way, or should they be defined on a 2D grid? If we do not allow for information about a 2D grid, then if the compositor is laying out the workspaces this way, panels will not be able to reflect that in how they display workspaces, and they will not be able to implement 'move to workspace left' and 'move to workspace up' functionality, etc.

Should workspaces and/or workspace groups have names?

Here are some events/requests I have not included

zwlr_workspace_manager_v1:

  • request: create workspace group

zwlr_workspace_group_v1:

  • request: add an output to the group
  • request: remove an output from the group
  • request: add a workspace to the group
  • request: remove a workspace from the group
  • request: set a name as a string
  • event: name as a string

zwl_workspace_v1:

  • event: name as a string
  • request: move (change the number of the workspace - processed as an insert to keep numbers sequential)
  • request: set name as a string

There is also some question of whether only one workspace can be active at a time. In compositor workspace overview interfaces, you can often see multiple workspaces. However, that's not inconsistent with only one of them being 'active', active doesn't have to mean visible, so I'm not sure if that's a problem.

@ammen99
Copy link
Member

ammen99 commented Feb 25, 2019

Thanks for starting work on this one!

This is a draft for addressing issue #10.

I likely don't have the C chops to contribute much to wlroots' code (though I might try), but maybe I can talk about protocols.

To accommodate both compositors that have workspaces spanning all outputs, as well as those that have each output with its own independent set of workspaces, this protocol has the concept of 'workspace groups'. A workspace group is a set of outputs that share workspaces. Each output may belong to at most one group. Each workspace group has one active workspace at any one time. This allows arbitrary grouping of outputs, including the two common cases of all outputs sharing a group and of each output being its own group.

I wonder, why do we need workspace groups at all? It seems to me that if we had just workspaces and outputs, where each workspace might be visible on more than one output, that would be enough?

There is more to think about here.

Is the protocol sufficient for required atomicity? If an output moves to a different workspace group, then the 'each output may belong to at most one group' requirement will be violated from the perspective of the client until both an output and an output_remove event are processed on the two zwlr_workspace_group_handle_v1 objects. But the compositor can refrain from sending done events until both of these events are sent, so we could say that if the client gets an output or output_remove event, it must wait for the done event before it has a consistent state for what groups all the outputs belong to.

Similarly with zwlr_workspace_handle_v1, if a workspace changes what its number is, the client must wait for the done event in order to see that the 'workspaces are sequentially numbered from zero' requirement is satisfied.

I am also a bit confused about destroy events and requests. If you request to destroy an object, you're just asking to clean up resources - you're not asking the compositor to remove a workspace or whatnot. However, if the compositor does remove a workspace (not just move it to a different workspace group), does it send a destroyed event?

Such a destroyed event should be explicitly specified in the protocol. I'm not sure that this is a very good name though, although I can't think of a better one right now.

I suspect the general ideas in this protocol are pretty unobjectionable, but potentially more contentious things that I haven't included are:

Workspaces are simply numbered here. Should it be left that way, or should they be defined on a 2D grid? If we do not allow for information about a 2D grid, then if the compositor is laying out the workspaces this way, panels will not be able to reflect that in how they display workspaces, and they will not be able to implement 'move to workspace left' and 'move to workspace up' functionality, etc.

Many window managers don't arrange workspaces in a grid (think for example tagging WMs). If we want this cross-compositor, I think it is best to leave "ordering" of workspaces.

Should workspaces and/or workspace groups have names?

I am +1 on this, I see no problem in having an optional name event so that the compositor can say if the workspace has a name (for ex. Openbox-like) or having them numbered 1,2,... (Sway) or perhaps something like 1-1, 1-2, ... for Wayfire.

Here are some events/requests I have not included

zwlr_workspace_manager_v1:

  • request: create workspace group

zwlr_workspace_group_v1:

  • request: add an output to the group
  • request: remove an output from the group
  • request: add a workspace to the group
  • request: remove a workspace from the group
  • request: set a name as a string
  • event: name as a string

zwl_workspace_v1:

  • event: name as a string
  • request: move (change the number of the workspace - processed as an insert to keep numbers sequential)

Do pagers and the like actually have the ability to reorder workspaces? It seems to me that if this gets included at all, it should be optional, so that the compositor may ignore this request.

  • request: set name as a string

There is also some question of whether only one workspace can be active at a time. In compositor workspace overview interfaces, you can often see multiple workspaces. However, that's not inconsistent with only one of them being 'active', active doesn't have to mean visible, so I'm not sure if that's a problem.

Thinking of the tagging paradigm I mentioned earlier, I think it may well be that more than a single "workspace" can be active at a given time.

@chrisjbillington
Copy link
Author

I wonder, why do we need workspace groups at all? It seems to me that if we had just workspaces and outputs, where each workspace might be visible on more than one output, that would be enough?

It's a good point. Though then, when an output is added or removed, all workspace objects will get events about it, instead of just one workspace_group object. So it will be a bit more chatty, but that's probably fine.

Also, without explicit workspace_group objects, if ever a compositor has a concept of workspaces that has some outputs sharing workspaces but not others, then a client would have to do some set arithmetic on the sets of outputs from each workspace in order to work out what the groups are. Again, that's probably fine.

So I think I like it, I'll get rid of the workspace_group interface.

Such a destroyed event should be explicitly specified in the protocol. I'm not sure that this is a very good name though, although I can't think of a better one right now.

I'll have to read up on this a bit. I notice in the foreign toplevel management protocol, there is an event closed that appears to be notifying the client that the toplevel object has been destroyed. Now, is this event emitted both in the case of the toplevel being closed for some external reason, and after the client makes a destroy request? If so, it seems like it is playing two roles: one is about resource freeing, the other about the toplevel closing. Closing implies resource freeing, but not necessarily the other way around. So if I understand correctly, I should make separate workspace_remove events and destroy events, and a workspace_remove event will always be followed by a destroy event, but not necessarily the other way around if a destroy event is in response to a destroy request. And perhaps the foreign toplevel management protocol should distinguish between close and destroy as well. Am I understanding correctly?

Many window managers don't arrange workspaces in a grid (think for example tagging WMs). If we want this cross-compositor, I think it is best to leave "ordering" of workspaces.

Ok, sounds good.

I am +1 on this, I see no problem in having an optional name event so that the compositor can say if the workspace has a name (for ex. Openbox-like) or having them numbered 1,2,... (Sway) or perhaps something like 1-1, 1-2, ... for Wayfire.

Great. Ah, I see grid information could be put in there: clever clients could then still take that into account if they wanted, albeit in a compositor-specific way.

Do pagers and the like actually have the ability to reorder workspaces? It seems to me that if this gets included at all, it should be optional, so that the compositor may ignore this request.

In gnome-shell at least, if you go into the overview and drag a window into the gaps between workspaces, a new workspace is created there. So that would be equivalent to a 'create' and then a 'move'. But that's all I can think of.

Thinking of the tagging paradigm I mentioned earlier, I think it may well be that more than a single "workspace" can be active at a given time.

Ok, so if we don't impose that only one workspace can be active per output, then we will need a deactivate request as well, since activating another workspace might not imply deactivating all others.

Futher, if there is more than one request for manipulating workspaces, does there need to be done requests (or however convention is to name them), so that a set of requests can be treated atomically by the server?

@ddevault
Copy link
Contributor

Great. Ah, I see grid information could be put in there: clever clients could then still take that into account if they wanted, albeit in a compositor-specific way.

Hm, this makes me uncomfortable. I'm not opposed to covering spatial information in this protocol, it just needs to support an arbitrary number of dimensions.

@ddevault
Copy link
Contributor

Note that including the workspace name is a good idea, though.

@ddevault
Copy link
Contributor

Thought which is probably only going to be useful for future work: some workspace switchers display a little rectangle or something representing where each toplevel is shown on the workspace.

* Remove the concept of a workspace group, instead associate outputs directly with
  workspaces.

* Remove 'empty' state: clients will instead determine themselves if a workspace
  is empty once functionality is added either to this or the foreign toplevel
  manager protocol to determine which toplevels are on which workspaces.

* Add name event

* Replace number event with coordinates of arbitrary dimension

* Add deactivate request, since activating one workspace need not imply
  that others are deactivated

* Rename destroy event to remove.

* Improve descriptions
@chrisjbillington
Copy link
Author

chrisjbillington commented Feb 26, 2019

Ok, I've pushed some changes.

  • There is now a coordinates event instead of a number event.

  • There is now a name event.

  • There is now no imposed concept of workspace groups, just outputs associated with workspaces. The description for coordinates does impose extra requirements on the coordinates of workspaces that share a common set of outputs (their coordinates must have equal dimension and be unique), this is the only place where the concept of a group of workspaces remains.

  • Added a deactivate request, since activating one workspace need not necessarily imply deactivating all others.

  • I removed the empty state. I imagine we will add either to this or the foreign topevel management protocol the ability to find out which toplevels are on which workspaces, and clients can figure out for themselves if a workspace is empty.

  • I renamed the destroy event to remove for when the workspace is removed for some external reason. I think I understand how destruction works now, and that what I've done makes sense. It matches what the foreign toplevel handles have for when the toplevels are destroyed externally. I now understand that if you call the destroy request, the server does not send an event in response, but that if the client receives the remove event, it should call destroy (correct me if I'm wrong).

  • I wrote more explicitly in the overall protocol description what active and inactive mean

Yet to add:

  • A request to tell the compositor that a set of activate/deactivate requests to be treated as atomic is complete (to be used also for making any more requests we add atomic).

Still no abilities to manipulate workspaces beyond activating and deactivating them, so we can talk more about that still.

@chrisjbillington
Copy link
Author

Thought which is probably only going to be useful for future work: some workspace switchers display a little rectangle or something representing where each toplevel is shown on the workspace.

perhaps the foreign toplevel protocol ought to grow workspace, workspace_remove and geometry events. I'll certainly need the first two to be implemented (somewhere, if not in the foreign toplevel protocol) for my panel to know which toplevels are on which workspaces.

workspaces that have identical sets of outputs, workspaces must have unique
coordinates with the same number of dimensions, such that the workspaces form a
grid with at most one workspace in each position. By convention, 2D coordinates
represent [y_pos, x_pos].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's unconventional, is there a reason to do this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Row before column is the convention for image pixel coordinates and matrix indexing as far as I'm aware. I might change the text to say [row, column] instead though, since x and y are more often used for continuous variables where the convention is opposite.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer x, y, z, … because that way pos[0] is always x, pos[1] is always y and so on.

I'm still not sure it's a good idea to have this in the protocol.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can just leave it out, just there's a risk that different compositors will choose different conventions, and then clients won't be able to represent them graphically. Happy to go with [column, row] too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if someone wants to make 3D workspaces, or even 4D? I'd suggest adding an event which has dimension and extent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name field works for tagging, no?

Coordinates seem common enough that if we leave it free-form, I imagine an ad-hoc standard for making strings of coordinates will present itself (and that gnome would end up sending 2D coordinates within the strings to tell clients that its workspaces are vertical). So by making it a string we're just deferring that standard to be a de-facto one instead of in the protocol. The benefit is allowing information about non-grid-like layouts.

But if it's an opaque string, what's it called? 'layout?' 'geometry'?

My preferred outcome is coordinates with strictly defined interpretation as x, y, z, etc, with compositors without such a concept just not using this part of the protocol. We can add extra events for other paradigms, including a catch-all opaque string for compositor-specific info.

Copy link
Member

@ammen99 ammen99 Feb 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we make this event optional, I'm ok

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plus, in Wayfire I can't really make workspaces arranged in a grid in multimonitor configuration, they aren't in the same coordinate system.

The coordinates are only meaningful among workspaces that share a set of outputs. So you can have a workspace at (0,0) on output 1, and a workspace on (0,0) on output 2. Or you can have a workspace at (0,0) that is attached to both outputs 1 and 2. But you cannot have two workspaces with coords (0,0) on output 1. This all may have been more clear with the original concept of 'workspace groups' - that the coordinates are only meaningful (and only have to be unique) within a workspace group that share a common set of outputs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an ad-hoc standard for making strings of coordinates will present itself

This sounds fucking awful.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds fucking awful.

👍

@ddevault
Copy link
Contributor

ddevault commented Feb 27, 2019

Let's move the coordinates discussion out into the main thread. We need a design which accomodates the needs of all compositors in an unambiguous and type-safe manner. This includes the workspace designs of sway, waymonad, KDE, and GNOME - which are all different.

@chrisjbillington
Copy link
Author

chrisjbillington commented Feb 27, 2019

I'll fix the issues unrelated to coordinates, and modify the coordinate stuff to what I think the best result of the discussion we've had so far on coordinates has been (admittedly opinionated), and will revisit after said discussion.

Yet to do: a request to signal end of set of other requests to be treated atomically by the compositor. Just need to know what this sort of request is typically named in wayland protocols.

Chris Billington added 2 commits February 27, 2019 11:34
* Fix two minor bugs pointed out in reviews
* clarify meaning and optional-ness of coordinates.
@chrisjbillington
Copy link
Author

I've added a done request so that atomic requests can be made, for example, activating one workspace and deactivating another.

Firstly: no problem with a request having the same name as an event?

Secondly: I can't find similar requests in other wayland protocols. Is there a reason for this? Are batches of client requests intrinsically treated as atomic by the protocol such that done requests are unnecessary?

@emersion
Copy link
Member

Firstly: no problem with a request having the same name as an event?

This is a bad idea, too confusing.

done is when the compositor wants to atomically send a state. Other names (e.g. commit) are used when the client atomically sends a state.

@chrisjbillington
Copy link
Author

Excellent. commit it is then.

@chrisjbillington
Copy link
Author

Hi all,

How do we feel about the current state of this for a v1? See also my comment in the issue thread explaining the "workspace group" concept and other terminology.

@ddevault
Copy link
Contributor

Do we have an example client & server implementation yet?

@AdrianVovk
Copy link

@ammen99 thoughts about this? I could implement this with carbonSHELL's overview mode. With some layer-shell changes, the only wayfire-specific proto I'd depend on will be some way to trigger my switcher plugin (in theory).

@ammen99
Copy link
Member

ammen99 commented Mar 26, 2020

Is there somebody working on an implementation for this in wlroots? I'd pick it up if there are no current ongoing efforts.

workspaces must have unique coordinates of equal dimensionality.
</description>
<arg name="coordinates" type="array"/>
</event>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not define the dimensionality, be it 1D, 2D, etc. We need a second argument for that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered the length of the array to be the dimensionality. Is that insufficient? (or non-obvious enough that I should mention it explicitly)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be fine, xdg-shell already does the same.

@ddevault
Copy link
Contributor

@ammen99 I don't think anyone is actively working on this, feel free.

</description>
</request>

<request name="commit">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should that be here? Can't we move commit to the manager interface, since this request seems to synchronize everything?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, this would make more sense.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll make this change.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for move to manager. Synchronizing between multiple workspace should send not partiualar workspace

@ammen99
Copy link
Member

ammen99 commented Apr 5, 2020

One more thing, I noticed that we have many done events. Shouldn't we like have a single done in the manager, just as I proposed to have a single one for the commit request?

Otherwise, I think that depending on interpretation, we can have:

  1. Done in workspace group is related only to which outputs this group belongs, and which workspaces are part of it. Then, I don't think we have a way to atomically change activated workspace from one to the other, do we?

  2. Done in workspace group applies to also workspaces in this group. Then, my question would be, what is the point of done in each individual workspace?

@coderkalyan
Copy link

Thought which is probably only going to be useful for future work: some workspace switchers display a little rectangle or something representing where each toplevel is shown on the workspace.

For my compositor's future workspace switch panel, I want to be able to accurately display the contents of each workspace, with an image instead of just a few rectangles. I'm not sure what would be the best way to implement this, but could we have some kind of system so the client can request the compositor to return the most recent rendered buffer from a workspace? Sort of like screencopy, but where the last composited frame of a workspace is saved.

For sake of argument, this is what the macOS virtual desktop switcher displays:
image

@ammen99
Copy link
Member

ammen99 commented May 24, 2020

@coderkalyan this looks like something that should be part of the compositor and not a client? NVM, I thought that windows are somehow modified as well

@coderkalyan
Copy link

@ammen99 I'm just talking about the top part of that image - the desktop switcher just shows a workspace-shot instead of a screen-shot :)

@ifreund
Copy link
Member

ifreund commented Jul 2, 2020

I've been working on river which is a tagging compositor in the same vein as dwm, xmonad, etc. I thought that it would be good to mention that I've created a river-status protocol which river uses to communicate this information to status bars (specifically the output-status interface). There's also a client implementation of part of this protocol in waybar here.

One thing that I haven't seen clarified yet is if a given surface can belong to multiple workspaces? This is the case with tags in river: a single view may belong to an arbitrary set of tags, and an arbitrary set of tags may be displayed on a given output at any given time. Both tags and views are local to the output.

As stated earlier, workspace coordinates make absolutely no sense for a tagging compositor like river.

Overall though, this protocol looks promising and I would be interested in implementing it in river given that surfaces may infact belong to multiple workspaces (which should be mentioned in the protocol) and that coordinates remain optional or are removed.

@ammen99
Copy link
Member

ammen99 commented Jul 2, 2020

Overall though, this protocol looks promising and I would be interested in implementing it in river given that surfaces may infact belong to multiple workspaces (which should be mentioned in the protocol) and that coordinates remain optional or are removed.

My understanding is that the link between workspace-unstable and foreign-toplevel-management-unstable is not yet done, and will probably be an event in foreign-toplevel-management (but I 100% agree that a toplevel can be on more than one workspace, this is the case in Wayfire too).

The different states that a workspace can have.
</description>

<entry name="active" value="0" summary="the workspace is active"/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about add urgent state as it was mentioned in issue. For purpose not search urgent toplevels and not bound pure workspace module with taskbar.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, active state means "available" and "visible" workspace, doesn't it?
In this case I think we need something like current state and only for one workspace in group.

</description>
</request>

<request name="commit">
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for move to manager. Synchronizing between multiple workspace should send not partiualar workspace

@ammen99
Copy link
Member

ammen99 commented Aug 4, 2020

@emersion
Copy link
Member

emersion commented Nov 1, 2021

wlr-protocols has migrated to gitlab.freedesktop.org. This pull request has been moved to:

https://gitlab.freedesktop.org/wlroots/wlr-protocols/-/merge_requests/35

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

Successfully merging this pull request may close these issues.

None yet

8 participants