i3-resurrect icon indicating copy to clipboard operation
i3-resurrect copied to clipboard

Allow saving whole session with all workspaces

Open cedryc opened this issue 5 years ago • 21 comments

Saving whole user session in one command would be convenient for the user in my opinion.

I propose this implementation made in my repo :

  • i3-resurrect save/restore --session to save whole session
  • i3-resurrect save/restore --workspace list-of-workspaces for saving multiples workspaces
  • i3-resurrect restore --session --clear for deleting active workspaces before restoring
  • Save profile in directory instead of a file to allow saving multiples workspaces or whole session profile

Glade to have your feedback about this.

cedryc avatar Apr 13 '20 12:04 cedryc

Hi, thanks for your work.

I see you have added a load command and if I'm not mistaken its behaviour overlaps with restore a lot? Would it not make sense to just add functionality to restore instead?

  • i3-resurrect save/restore --session to save whole session

I am open to this idea, although I have been hesitant to implement it as it can be done easily with a script and I'm not sure it's worth adding that complexity

  • i3-resurrect save/restore --workspace list-of-workspaces for saving multiples workspaces

Same as above, although this might be cleaner to implement, I'm not sure. I also notice that in the usage text from your repo, this is not the syntax used:

Usage: i3-resurrect restore [OPTIONS] [WORKSPACES]...

  Restore i3 workspace(s) layout(s) or whole session and programs.

  WORKSPACES are the workspaces to restore. [default: current workspace]

Options:
  -w, --workspace            The workspace to restore. This can either be a
                             name or the number of a workspace.
...

Which indicates that the list of workspaces is a separate argument, not an argument passed to the --workspace option. That doesn't strike me as desirable if so.

  • i3-resurrect save --session --clear for deleting old workspace layouts that belong to a session
  • i3-resurrect restore --session --clear for deleting active workspaces before restoring

clear means two distinct things in these two different contexts, so maybe it would be better to give these flags different names.

  • i3-resurrect save --session --clear for deleting old workspace layouts that belong to a session

Also this clear_directory() method seems to also delete profiles? That would not be what you want.

  • i3-resurrect restore --session --focus for keeping the focus on the current window

What happens without --focus? Is there any reason not to make this default? Also what happens if you use --clear and --focus? The current window will be destroyed, right? So where does the focus stay?

  • Save profile in directory instead of a file to allow saving multiples workspaces or whole session profile

Not sure what you mean, but there is already a --directory option that allows you to specify the directory to save to/restore from. I don't see why you would need two ways of changing the directory.

I'm also curious what the TARGET_WORKSPACE is for in the load command. Currently it already switches to the workspace being restored. If you wanted to restore a saved workspace to a different workspace, that is what profiles are for, e.g.

# Save workspace 1 to profile "Project X"
i3-resurrect save -w 1 -p "Project X"

# Another day I am using workspace 1 for something else, but I want to work on "Project X", so I restore the profile "Project X" to workspace 2 instead.
i3-resurrect restore -p "Project X" -w 2

Note that the order of the options does not matter but I ordered it that way to make it clearer.

I guess there could be the case that you saved a layout as a workspace previously but later realise you want that layout on a different workspace. Personally I haven't really had that problem because if I'm saving a layout for a project that I don't always work on, or any other layout that I only sometimes use, I just use a profile for it instead, and when I reboot my PC I save all my open workspaces the normal (non-profile) way.

JonnyHaystack avatar Apr 14 '20 15:04 JonnyHaystack

This is a terrific project but until we have this feature, it is of very limited utility. hopefully @cedl38 can address the ambiguous issues in his branch and submit a PR.

aarobc avatar Jul 18 '20 20:07 aarobc

If you just need to save/restore all workspaces at once, you can do that by just writing a small wrapper script around i3-resurrect. I don't see how it is of limited utility. It is intended to be designed in such a way that you can easily use it in scripts for your own needs, as I understand that there are many different ways people would want to use it.

JonnyHaystack avatar Jul 23 '20 10:07 JonnyHaystack

Very valid, and I'm grateful for the work done in creating this project.

My thought is this: the scenario most people are interested in is saving/restoring all workspaces and applications on the fly, rather than curate a number of profiles. It makes sense to address this common scenario.

For cases where customization is required, users are likely to write them in python anyway, so being able to import this package and use it as a library would make more sense rather than having to exec out commands.

aarobc avatar Jul 23 '20 16:07 aarobc

Seeing as a lot of people have requested this feature I will probably add a basic save all option, but I think if you go any further you end up trying to solve too many problems which makes the interface unnecessarily complicated. For those cases it would be better to write a script.

By the way, in the mean time, here's a script that I wrote in about a minute to save all workspaces:

for workspace in $(wmctrl -d | awk '{print $9}'); do
  i3-resurrect save -w "$workspace"
done

Maybe now you see why for so long I didn't feel any need to add this as a feature :stuck_out_tongue:

JonnyHaystack avatar Oct 17 '20 14:10 JonnyHaystack

Must say that using wmctrl adds a dep. At least for Slackware.

Tonus1 avatar Oct 17 '20 17:10 Tonus1

Fair enough. I will at most add an --all flag to save, restore, and rm commands.

JonnyHaystack avatar Oct 18 '20 09:10 JonnyHaystack

Here's a cleaner one liner without the wmctrl dependency, in case anyone's interested:

i3-msg -t get_workspaces | jq -r '.[].name' | xargs -n1 i3-resurrect save -w

JonnyHaystack avatar Oct 30 '20 11:10 JonnyHaystack

This one adds a dep to jq :-D

Could this work ?

i3-msg -t get_workspaces | sed 's/},{/\n/g' | awk -F, '{ print $2}' | awk -F: '{ print $2}' | xargs -n1 i3-resurrect save -n

I can't really test since I'm waiting for a new release ;-)

Tonus1 avatar Oct 30 '20 13:10 Tonus1

Better :

i3-msg -t get_workspaces | sed 's/},{/\n/g' | awk -F, '{ print $3}' | awk -F: '{ print $2 }' | xargs -n1 i3-resurrect save -w

Tonus1 avatar Oct 30 '20 13:10 Tonus1

This one adds a dep to jq :-D

Haha I just assumed most people would have it seeing as it's a super useful and common scripting tool

I can't really test since I'm waiting for a new release ;-)

Do you mean a new release of i3-resurrect? How come?

Better :

i3-msg -t get_workspaces | sed 's/},{/\n/g' | awk -F, '{ print $3}' | awk -F: '{ print $2 }' | xargs -n1 i3-resurrect save -w

Yup that does indeed work without jq :smiley:

JonnyHaystack avatar Oct 30 '20 18:10 JonnyHaystack

I wanted a new release at first thinking that 1.4.3 do not have -n option, but not sure anymore, especially because -w works fine even with my weird workspace naming...

Tonus1 avatar Oct 30 '20 19:10 Tonus1

The -n option came out in 1.4.0 actually. Also if you like you can install directly from the master branch with pip. I think the syntax is: pip install git+https://github.com/JonnyHaystack/i3-resurrect.git

JonnyHaystack avatar Oct 30 '20 21:10 JonnyHaystack

I prefere building packages. I already build one for Slackware, it's 1.4.3 already. I was confused with the text provided with the --help option and the README.md text. I may have skipped the docs when preparing quick and dirty package, my bad !

Tonus1 avatar Oct 31 '20 10:10 Tonus1

What's the last update on this? Is the -all flag implemented? The script solution is inferior because preferably it is simpler to save a number of workspaces with a single profile name...
i3-resurrect save -w 1,2,3,9,0 --swallow=class,instance,title -p "web-dev-project-2"

pvonmoradi avatar Nov 04 '20 09:11 pvonmoradi

@pvonmoradi you can do that. Just set the --directory/-d option to something else. That's how I plan to have it work anyway.

I haven't implemented --all yet, but should be happening soon.

JonnyHaystack avatar Nov 04 '20 09:11 JonnyHaystack

@JonnyHaystack Thanks for your reply and awesome project!
I don't quite follow -d option. what does The directory to restore the workspace from has to do with "saving a number of workspaces with a single name"?

Edit: I think I got what you meant. The "profile" option is simply a default -d name. I just used -d "my_desired_path" and use this path as named distinction to manage multiple projects.

pvonmoradi avatar Nov 04 '20 09:11 pvonmoradi

Using the one liner from @Tonus1 above, and another one liner I made to restore all layouts and windows, for anyone who might stumble upon this issue. Here's what I ended up with in my i3 config (obviously can change the keybinding if you don't like it):

# save all workspace layouts
bindsym $super+grave exec "i3-msg -t get_workspaces | sed 's/},{/\n/g' | awk -F, '{print $3}' | awk -F: '{print $2}' | xargs -n1 i3-resurrect save -w"

# restore all workspaces and windows
bindsym $super+shift+grave exec "i3-resurrect ls | sed -n '/programs/!p' | awk '{print $2}' | xargs -n1 i3-resurrect restore -w"

mfkp avatar May 13 '21 08:05 mfkp

WIP pull request referring to this issue #104

cedryc avatar Jun 06 '21 15:06 cedryc

Thanks for this awesome work.

I found restoring all workspaces via script to be a pita.

Grabbing all workspaces with this pulls in a lot of "other" profiles, no good: i3-resurrect ls | sed -n '/programs/!p'

When I ran a simple loop, it didn't actually use the target workspace unless it already existed with at least one running app window (which makes it pretty useless - many desktops get dumped into one if you don't do a lot of prepwork):

workspaces.forEach( w => {
  rs.run_command_sync( `i3-msg workspace ${ w.name }; i3-resurrect restore -w '${ w.name }'` );
});

This node script is mostly working for me. About 5% of browser titles may come up different and get lost.

  const workspaces = JSON.parse( rs.run_command_sync( 'i3-msg -t get_workspaces' ).trim());

    if ( target == 'i3-save' || target == 'is' ) { // save
      workspaces.forEach( w => {
        rs.run_command_sync( `i3-resurrect save --swallow=class,instance,title -w '${ w.name }'` );
      });
    } else { // restore
      rs.run_command_sync( `pk --yes firefox || true` ); // kill ff

      setTimeout( () => {
        rs.run_command_sync( `i3-msg -t get_workspaces | sed 's/},{/\\n/g' | awk -F, '{ print $3}' | awk -F: '{ print $2 }' | xargs -n1 i3-resurrect restore -w`);
        rs.run_command_sync( `start_browser &` );
      }, 2000);
    }

Would love to see a simple --all option that made all this noise a lot easier. Or fork and update i3 to bake all this python goodness in natively. Everyone is very resistant to bloat (here, and at i3), but just about everyone wants this, from what I've seen. I know I do! Again, thanks, @JonnyHaystack

moodboom avatar Jul 08 '23 17:07 moodboom