You are not logged in.
Pages: 1
Topic closed
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
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:
Call savesession to store the state of each window
Restart dwm, passing the temporary file name as argument
Upon start up, if an argument is passed, treat it as a "session savefile"; call restoresession
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).
Offline
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
[...]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
}
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.
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
for each saved client
match the window/client with the saved state using the window ID (if it fails, skip to next)
update the `tags` variable
(if necessary) send to the right monitor using `sendmon()`
call `pop()` on that client, to keep the right order
for each monitor: call `arrange()`, to make it show the right thing
Last edited by ayekat (2015-05-04 10:36:10)
Offline
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
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
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
Pages: 1
Topic closed