ipc: support workspace sets
This is a draft PR for an implementation of querying and configuring workspace sets via IPC. This would be a way to interface with workspaces via bars such as waybar or window rule scripts specific to workspaces. Leaving it as a draft for now since I am unsure if this should live in wsets or ipc-rules. For now, it lives in ipc-rules. This is a very quick, very untested implementation as I do not have time at the moment to build and test the plugin.
This would likely require signals for seeing if a workspace set is created or destroyed. I'm not too sure if they already exist, but this would require more signals to be defined I imagine, if they aren't defined already.
Views should also know which workspace set and viewport they exist on, but I don't know if that would complicate anything in the codebase, or if that is considered out of scope for this PR. On paper, listing views and specifying the workspace set id and/or viewport position should list all the views that exist on that workspace set (and viewport if specified). This would make it less simple for scripts to know which workspace set they exist on however- an example would be seeing if a view's title change is on the second workspace. One would have to list all the views that exist on the second workspace in order to check if the view is indeed on it whereas ideally, one could simply check properties such as workspace-set-id and workspace-point. Again, that might be out of scope for this specific PR as it doesn't necessarily pertain to interfacing with workspace sets.
Hi and thanks for starting the work on this. A few things:
-
I don't think we ought to filter views in the plugin. Instead, we should return the full list of views, on all workspaces/workspace-sets. We should indicate the wset id for each view (if the view is on a wset id) - this should be as simple as adding a new field to the
view_to_jsonfunction. Then the ipc client can do the filtering on its own. -
A view is not really 'on' a particular viewport/workspace/however you call it, Views can be visible on multiple of those. Again, I think it is better that we don't have a bigger API than we need. If ipc scripts need to query something in particular, they can easily go through all views and check whether they fit/overlap a particular workspace rectangle.
-
About the signal for output-workspace-changed: this signal should be
wset-workspace-changed, because workspaces change within a workspace set, not within an output. -
About workspace-set-info and output-info commands: with your patch they have a different syntax for the workspace information, output-info has output[workspace][x/y/width/height], I'd prefer workspace-set-info to report in the same format.
@ammen99 Updated ipc-rules to reflect your comments on this.
About workspace-set-info and output-info commands: with your patch they have a different syntax for the workspace information, output-info has output[workspace][x/y/width/height], I'd prefer workspace-set-info to report in the same format.
Does the output data need to contain any workspace information except for the workspace set's id? It could easily just provide the id, and scripts can query for the workspace set info itself afterwards with that. Right now, the output data still supplies the workspace data to clients.
@ammen99 Updated
ipc-rulesto reflect your comments on this.About workspace-set-info and output-info commands: with your patch they have a different syntax for the workspace information, output-info has output[workspace][x/y/width/height], I'd prefer workspace-set-info to report in the same format.
Does the output data need to contain any workspace information except for the workspace set's id? It could easily just provide the id, and scripts can query for the workspace set info itself afterwards with that. Right now, the output data still supplies the workspace data to clients.
Yes, that's true but I'd like to avoid breaking changes - and I guess that this is information which would be commonly requested so I think overall it is better to spare the additional IPC call needed otherwise.
Took a brief look over the PR, looks much better now :) I'll do a full review on the weekend & merge if everything is fine.
Took a brief look over the PR, looks much better now :) I'll do a full review on the weekend & merge if everything is fine.
Sounds good. I just added configure_output and configure_wset as well, allowing scripts to manipulate workspace sets.
EDIT: I also have to build and try it for myself :) Still haven't done that yet!
Sounds good. I just added
configure_outputandconfigure_wsetas well, allowing scripts to manipulate workspace sets.
I think this features should belong to the wsets plugin though, since it can also create/destroy wsets and already has all the logic for moving wsets around (and also I think it keeps an internal mapping of wsets). It can also show a popup when the wset changes (which I guess should happen also for ipc-triggered switches).
Sounds good. I just added
configure_outputandconfigure_wsetas well, allowing scripts to manipulate workspace sets.I think this features should belong to the wsets plugin though, since it can also create/destroy wsets and already has all the logic for moving wsets around (and also I think it keeps an internal mapping of wsets). It can also show a popup when the wset changes (which I guess should happen also for ipc-triggered switches).
Good point! I'll revert the commit for now and look into adding this feature before the merge, if it is in scope for this PR.
Good point! I'll revert the commit for now and look into adding this feature before the merge, if it is in scope for this PR.
I don't personally mind merging either two separate PRs or one bigger PR, feel free to organize it as you wish.
I would like to switch between workspace in a bar. Can I have an example of a script to do that?
@bluebyt Workspace or workspace set? Here is an example for workspaces using the vswitch plugin:
from wayfire_socket import WayfireSocket, get_msg_template
import os
addr = os.getenv('WAYFIRE_SOCKET')
sock = WayfireSocket(addr)
msg = get_msg_template('vswitch/set-workspace')
msg['data']['x'] = x
msg['data']['y'] = y
msg['data']['output-id'] = output-id
sock.send_json(msg)
For reference: https://github.com/WayfireWM/wayfire/blob/4f65d16420aad0dae6f26018088cfb839e93a622/plugins/vswitch/vswitch.cpp#L242
https://github.com/WayfireWM/wayfire/blob/4f65d16420aad0dae6f26018088cfb839e93a622/plugins/vswitch/vswitch.cpp#L251-L255
@ammen99 Something like this, all workspace are displayed in the bar with numbers or icons and with the mouse you can navigate between them by clicking or scrolling on the number in the bar.
I don't known what is workspace set?
I tried the script on the terminal, but I get multiple error, my system should be all set, I can run other script like inactive-alpha.py without any error.
./workspace.py: line 1: from: command not found
import: unable to grab mouse '': Resource temporarily unavailable @ error/xwindow.c/XSelectWindow/9354.
import: unable to read X window image '': Success @ error/xwindow.c/XImportImage/4961.
import: unable to read X window image '': Resource temporarily unavailable @ error/xwindow.c/XImportImage/5068.
import: os' @ error/import.c/ImportImageCommand/1289. ./workspace.py: line 4: syntax error near unexpected token ('
./workspace.py: line 4: `addr = os.getenv('WAYFIRE_SOCKET')'
@bluebyt In case you're not looking at the matrix chat .. maybe you need #!/bin/env python3 at the start?
After added the line "#!/bin/env python3" I have less error.
Traceback (most recent call last):
File "/home/bluebyt/.config/ipc-scripts/./workspace.py", line 9, in
Yes, replace x/y and the output-id appropriately xD
What is output-id? I tried this HDMI-A-1, but I get an error. I have only one monitor, I guess I set it number 1 . that working!
You can see a list of available output by making a query window-rules/list-outputs, no arguments needed. Then you'll get in return a json object with a list of all outputs with their names and IDs
also you can try: pip install wayfire
from wayfire import sock
focused_view_id = sock.get_focused_view()["id"]
sock.set_workspace({"x":1, "y":1}, focused_view_id)
# or not moving the view and yet going to the workspace
# sock.set_workspace({"x":1, "y":1})
Thanks @ammen99 and @killown I will play around with this!