You are not logged in.

#1 2015-05-03 22:17:44

Goran
Member
Registered: 2012-01-24
Posts: 92

dwm: preserve state on restart.

I'm using dwm as my window manager.

I have a function called restart:

void
restart(const Arg *arg) {
	const char *p = "/usr/local/bin/dwm";
	execv(p, (char *const[]) {p, NULL});
}

I use it to restart dwm, so that I can see my changes to config.h quickly, without having to restart X, and re-load all my applications.

This works, but it places all my windows back into the default workspace, which is very inconvenient.

Is there a way to preserve the overall dwm state, so that windows remain in their present workspace after restart?

Offline

#2 2015-05-03 22:51:09

ayekat
Member
Registered: 2011-01-17
Posts: 1,611

Re: dwm: preserve state on restart.

I would probably create two functions

  • savesession: query the list of clients + their state (workspace/tag mask) and store it to a temporary file;

  • restoresession: read a file and apply the information about clients + their state contained therein to existing clients

Restarting dwm would then work as follows:

  1. Call savesession to store the state of each window

  2. Restart dwm, passing the temporary file name as argument

  3. Upon start up, if an argument is passed, treat it as a "session savefile"; call restoresession

  4. Read the list of clients/states from the given file, try to apply to the corresponding client (if existing)

There are also people who pass the state by environment variables, or directly as a command line argument for the new instance (although I oppose the latter, as the executed command line gets unnecessarily long, causing ugly process listings).


pkgshackscfgblag

Offline

#3 2015-05-04 05:40:35

Goran
Member
Registered: 2012-01-24
Posts: 92

Re: dwm: preserve state on restart.

I assumed that I would have to write some basic serialization/deserialization code, but I'm not really that familiar with dwm, so I don't know where to start.

I'm looking at the Monitor struct, and there is a `Client *clients` member, but there is no client_count, or something similar, which would allow me to loop through them, and also allocate new memory for the serialized data buffer.

Also, I'm not sure when best to inject the deserialized state back into all the clients - Should it be after the setup() call? Is it as simple as just setting the fields directly on the client struct, or do I have to call certain methods to make make the system aware of the changes?

There are also people who pass the state by environment variables, or directly as a command line argument for the new instance (although I oppose the latter, as the executed command line gets unnecessarily long, causing ugly process listings).

I would prefer to pass state as a command line argument - I think it's simpler than having to deal with files, and I don't mind the long process listings.

Offline

#4 2015-05-04 06:30:33

ayekat
Member
Registered: 2011-01-17
Posts: 1,611

Re: dwm: preserve state on restart.

Goran wrote:

[...]there is no client_count, or something similar, which would allow me to loop through them[...]

The clients are a linked list: the `Clients` struct contains the a pointer `next` to the next client in the linked list. You could do something like

Client *c;
for (c = clients; c != NULL; c = c->next) {
        // serialize here
}
Goran wrote:

Also, I'm not sure when best to inject the deserialized state back into all the clients - Should it be after the setup() call?

I would probably do it after the `scan()` part, when dwm has already created the list of existing clients.

Goran wrote:

Is it as simple as just setting the fields directly on the client struct, or do I have to call certain methods to make make the system aware of the changes?

The client information I would store are probably:

  • its window ID (to be able to match with the existing client list)

  • its tags

  • the monitor it belongs to (by e.g. assigning a number to each monitor, starting at 0)

So when restoring, I would

  1. for each saved client

    1. match the window/client with the saved state using the window ID (if it fails, skip to next)

    2. update the `tags` variable

    3. (if necessary) send to the right monitor using `sendmon()`

    4. call `pop()` on that client, to keep the right order

  2. for each monitor: call `arrange()`, to make it show the right thing

Last edited by ayekat (2015-05-04 10:36:10)


pkgshackscfgblag

Offline

#5 2015-05-04 10:20:00

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: dwm: preserve state on restart.

Ayekat, your for loop is out of order.  It would actually run, but it would skip the first client.  That should read:

for (c = clients; c; c = c->next) {

(edit: the code in the previous post is now correct)


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#6 2015-05-04 10:36:49

ayekat
Member
Registered: 2011-01-17
Posts: 1,611

Re: dwm: preserve state on restart.

Oops... thanks for correcting. Must've been too early in the morning for me.


pkgshackscfgblag

Offline

#7 2022-03-08 15:48:07

mahdymirzade
Member
Registered: 2021-07-09
Posts: 1

Re: dwm: preserve state on restart.

Goran wrote:

I assumed that I would have to write some basic serialization/deserialization code, but I'm not really that familiar with dwm, so I don't know where to start.

I'm looking at the Monitor struct, and there is a `Client *clients` member, but there is no client_count, or something similar, which would allow me to loop through them, and also allocate new memory for the serialized data buffer.

Also, I'm not sure when best to inject the deserialized state back into all the clients - Should it be after the setup() call? Is it as simple as just setting the fields directly on the client struct, or do I have to call certain methods to make make the system aware of the changes?

There are also people who pass the state by environment variables, or directly as a command line argument for the new instance (although I oppose the latter, as the executed command line gets unnecessarily long, causing ugly process listings).

I would prefer to pass state as a command line argument - I think it's simpler than having to deal with files, and I don't mind the long process listings.

I've been wanting to implement the same thing to my dwm build, but even after reading this discussion couldn't make it possible. It's been 7years, have you succeeded to coding this or you've given up? do you still have your old build and is it possible to link it to me so I can see how you did it?

Offline

#8 2022-03-08 23:27:14

2ManyDogs
Forum Fellow
Registered: 2012-01-15
Posts: 4,645

Re: dwm: preserve state on restart.

mahdymirzade, this thread is very old, and the OP has not been here since 2020. Please do not necrobump.

Instead, please open a new topic for your issue and link back to this one if you think it still applies.

Closing.

Offline

Board footer

Powered by FluxBB