diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/confws.c ion-20011109/src/confws.c --- ion-20011109-pristine/src/confws.c Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/confws.c Mon Jan 14 23:11:58 2002 @@ -214,6 +214,20 @@ return TRUE; } +static bool opt_workspace_single(Tokenizer *tokz, int n, Token *toks) +{ + char *name=TOK_STRING_VAL(&(toks[1])); + bool retval=FALSE; + + if (*name=='\0') { + tokz_warn(tokz, toks[1].line, "Empty name"); + return FALSE; + } + + retval=reset_workspace(current_ws, current_screen, FALSE); + return retval; +} + static bool opt_workspace_end(Tokenizer *tokz, int n, Token *toks) { @@ -280,6 +294,13 @@ fprintf(file, "}\n"); } +static void write_workspace(WWorkspace *ws, FILE *file) +{ + fprintf(file, "workspace \"%s\" {\n", ws->name); + write_obj(file, ws->splitree, 1); + fprintf(file, "}\n"); +} + static void dodo_write_workspaces(FILE *file) { @@ -290,17 +311,14 @@ i++; if(ws->name==NULL){ warn("Not saving workspace %d -- no name", i); - continue; + return; } if(ws->splitree==NULL){ warn("Empty workspace -- this cannot happen"); - continue; + return; } - - fprintf(file, "workspace \"%s\" {\n", ws->name); - write_obj(file, ws->splitree, 1); - fprintf(file, "}\n"); + write_workspace(ws, file); } } @@ -338,12 +356,40 @@ {NULL, NULL ,NULL, NULL} }; +ConfOpt wsconf_opts_single[]={ + {"workspace", "s", opt_workspace_single, workspace_opts}, + {NULL, NULL, NULL, NULL} +}; /*}}}*/ /*{{{ read_workspace, write_workspaces */ +static char *get_wsconfname_for(const char *wsname) +{ + char *dir; + char *tmp; + int len; + + dir=getenv("HOME"); + + if(dir==NULL){ + warn("Could not get $HOME"); + return NULL; + } + + len=strlen(dir)+32; + tmp=ALLOC_N(char, len); + + if(tmp==NULL){ + warn_err(); + return NULL; + } + + snprintf(tmp, len, "%s/.ion/workspace-%s.conf", dir, wsname); + return tmp; +} static char *get_wsconfname() { @@ -380,7 +426,6 @@ return tmp; } - static bool do_read_workspaces() { char *wsconf; @@ -407,6 +452,32 @@ return retval; } +static bool do_read_workspace_from(const char *fname) +{ + char *wsconf; + bool retval=FALSE; + Tokenizer *tokz; + + wsconf=get_wsconfname_for(fname); + + if (wsconf==NULL) + return FALSE; + + if (access(wsconf, F_OK)==0) { + tokz=tokz_open(wsconf); + + if (tokz!=NULL) { + tokz->flags=TOKZ_ERROR_TOLERANT; + tokz_set_includepaths(tokz, includepaths); + retval=parse_config_tokz(tokz, wsconf_opts_single); + tokz_close(tokz); + } + } + + free(wsconf); + return retval; +} + bool read_workspaces(WScreen *scr) { @@ -419,6 +490,27 @@ return successp; } +bool read_workspace_from(WWorkspace *ws, const char *wsname) +{ + bool successp; + + if (ws==NULL) + return FALSE; + + current_screen=SCREEN_OF(ws); + current_ws=ws; + current_split=NULL; + + successp=do_read_workspace_from(wsname); + reattach_orphaned_clients(ws); + + current_screen=NULL; + current_ws=NULL; + current_split=NULL; + + return successp; +} + static bool ensuredir(char *f) { @@ -441,7 +533,6 @@ return TRUE; } - static bool do_write_workspaces() { char *wsconf; @@ -483,6 +574,37 @@ current_screen=NULL; return successp; +} + +bool write_workspace_as(WWorkspace *ws, const char *name) +{ + char *wsconf; + FILE *file; + + if (ws==NULL) + return FALSE; + + wsconf=get_wsconfname_for(name); + if (wsconf==NULL) + return FALSE; + + if (!ensuredir(wsconf)) + return FALSE; + + file=fopen(wsconf, "w"); + if (file==NULL) { + warn_err_obj(wsconf); + free(wsconf); + return FALSE; + } + + fprintf(file, "# This file was created by and is modified by Ion.\n"); + write_workspace(ws, file); + fclose(file); + free(wsconf); + + return TRUE; + } /*}}}*/ diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/confws.h ion-20011109/src/confws.h --- ion-20011109-pristine/src/confws.h Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/confws.h Mon Jan 14 12:36:43 2002 @@ -12,5 +12,7 @@ extern bool read_workspaces(WScreen *scr); extern bool write_workspaces(WScreen *scr); +extern bool write_workspace_as(WWorkspace *ws, const char *name); +extern bool read_workspace_from(WWorkspace *ws, const char *wsname); #endif /* INCLUDED_CONFWS_H */ diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/frame.c ion-20011109/src/frame.c --- ion-20011109-pristine/src/frame.c Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/frame.c Mon Jan 14 23:09:37 2002 @@ -293,10 +293,6 @@ /*{{{ Attach/detach */ -static bool do_frame_detach_client(WFrame *frame, WClient *client, - bool reparent, bool destroy); - - bool frame_attach_client(WFrame *frame, WClient *client, bool switchto) { WFrame *oframe=NULL; @@ -352,7 +348,7 @@ /* */ -static bool do_frame_detach_client(WFrame *frame, WClient *client, +bool do_frame_detach_client(WFrame *frame, WClient *client, bool reparent, bool destroy) { WClient *next=NULL; diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/frame.h ion-20011109/src/frame.h --- ion-20011109-pristine/src/frame.h Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/frame.h Mon Jan 14 22:44:18 2002 @@ -57,6 +57,7 @@ extern bool frame_attach_client(WFrame *frame, WClient *client, bool st); extern void frame_detach_client(WFrame *frame, WClient *client); +extern bool do_frame_detach_client(WFrame *frame, WClient *client, bool reparent, bool destroy); extern void frame_attach_tagged(WFrame *frame); extern void frame_add_clientwin(WFrame *frame, WClient *client, WClientWin *cwin); diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/function.c ion-20011109/src/function.c --- ion-20011109-pristine/src/function.c Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/function.c Mon Jan 14 12:29:30 2002 @@ -70,6 +70,8 @@ FN_VOID(generic, WFrame, "query_workspace", query_workspace), FN_VOID(generic, WFrame, "query_workspace_with", query_workspace_with), FN_VOID(generic, WFrame, "query_renameworkspace", query_renameworkspace), + FN_VOID(generic, WFrame, "query_save_ws_as", query_save_ws_as), + FN_VOID(generic, WFrame, "query_read_ws_from", query_read_ws_from), FN_VOID(generic, WWindow, "goto_above", goto_above), FN_VOID(generic, WWindow, "goto_below", goto_below), Binary files ion-20011109-pristine/src/ion and ion-20011109/src/ion differ diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/query.c ion-20011109/src/query.c --- ion-20011109-pristine/src/query.c Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/query.c Mon Jan 14 12:39:34 2002 @@ -20,6 +20,7 @@ #include "complete_file.h" #include "function.h" #include "wmessage.h" +#include "confws.h" /*{{{ Generic */ @@ -402,6 +403,34 @@ { do_query_edln(frame, handler_function, "Function name:", NULL, complete_simplemainfunc); +} + +static void handler_save_ws_as(WThing *thing, char *name, char *userdata) +{ + save_workspace_as(name); +} + +bool query_save_ws_as(WThing *frame) +{ + WWorkspace *ws=wglobal.current_screen->current_workspace; + do_query_edln((WFrame *)frame, handler_save_ws_as, "Save workspace as:", ws->name, complete_workspace); + return TRUE; +} + +static void handler_read_ws_from(WThing *thing, char *name, char *userdata) +{ + if (wglobal.current_screen) + read_workspace_from(wglobal.current_screen->current_workspace, name); + else { + fprintf(stderr, "Cannot read workspace. No active screen. Argh.\n"); + warn("Cannot read workspace. No active screen. Argh."); + } +} + +bool query_read_ws_from(WThing *frame) +{ + do_query_edln((WFrame *)frame, handler_read_ws_from, "Read workspace from:", NULL, NULL); + return TRUE; } diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/query.h ion-20011109/src/query.h --- ion-20011109-pristine/src/query.h Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/query.h Mon Jan 14 12:31:36 2002 @@ -22,6 +22,8 @@ extern void query_renameworkspace(WFrame *frame); extern void query_yesno(WFrame *frame, char *fn, char *prompt); extern void query_function(WFrame *frame); +extern bool query_save_ws_as(WThing *frame); +extern bool query_read_ws_from(WThing *frame); /* Warning: fwarn will free(p)! */ extern void fwarn(WFrame *frame, char *p); diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/workspace.c ion-20011109/src/workspace.c --- ion-20011109-pristine/src/workspace.c Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/workspace.c Mon Jan 14 23:10:48 2002 @@ -20,6 +20,8 @@ #include "thingp.h" #include "modules.h" #include "complete.h" +#include "confws.h" +#include "query.h" static WThingFuntab workspace_funtab={ @@ -200,7 +202,6 @@ do_switch_workspace(scr, ws); } - bool switch_workspace_nth(WScreen *scr, int num) { WWorkspace *ws=NTH_THING(scr, num, WWorkspace); @@ -283,7 +284,6 @@ do_switch_workspace(scr, ws); } - bool switch_workspace_name(const char *str) { WWorkspace *ws=lookup_workspace(str); @@ -296,6 +296,21 @@ return TRUE; } +bool save_workspace_as(const char *fname) +{ + WScreen *scr=wglobal.current_screen; + WWorkspace *ws; + + if (scr==NULL) + return FALSE; + + ws=scr->current_workspace; + + if (ws==NULL) + return FALSE; + + return write_workspace_as(ws, fname); +} /*}}}*/ @@ -350,6 +365,58 @@ return tmp; } +bool reset_workspace(WWorkspace *ws, WScreen *scr, bool ci) +{ + int old_opmode; + + if (ws->splitree!=NULL) { + + /* prevent the workspace from being deleted in this code-path */ + ws->thing.flags&=~WTHING_DESTREMPTY; + + while (ws->splitree!=NULL) { + WFrame *f; + WClient *client; + if ((f=FIRST_THING(ws, WFrame))) { + + if (f->client_count>0) { + FOR_ALL_TYPED(f, client, WClient) { + do_frame_detach_client(f, client, TRUE, FALSE); + } + } + destroy_thing((WThing *)f); + } + } + } + + ws->thing.flags|=WTHING_DESTREMPTY; + ws->splitree=NULL; + + if(ci) { + if(!create_initial_frame(scr, ws)) + return FALSE; + } + + return TRUE; +} + +bool reattach_orphaned_clients(WWorkspace *ws) +{ + WFrame *frame; + WClient *client; + + frame=FIRST_THING(ws, WFrame); + if (frame==NULL) + return FALSE; + + for (client=wglobal.client_list; client; client=client->g_client_next) { + if (!CLIENT_HAS_FRAME(client)) { + frame_attach_client(frame, client, FALSE); + } + } + + return TRUE; +} static bool init_workspace(WWorkspace *ws, WScreen *scr, const char *name, bool ci) @@ -361,17 +428,11 @@ return FALSE; } - ws->thing.flags|=WTHING_DESTREMPTY; - ws->splitree=NULL; - - if(ci){ - if(!create_initial_frame(scr, ws)){ + link_thing((WThing*)scr, (WThing*)ws); + if (!(reset_workspace(ws, scr, ci))) { free(ws->name); return FALSE; } - } - - link_thing((WThing*)scr, (WThing*)ws); scr->workspace_count++; return TRUE; diff -ubNr --exclude-from=/home/azzit/diffrc/ion.conf ion-20011109-pristine/src/workspace.h ion-20011109/src/workspace.h --- ion-20011109-pristine/src/workspace.h Mon Jan 14 10:39:00 2002 +++ ion-20011109/src/workspace.h Mon Jan 14 13:44:19 2002 @@ -32,6 +32,8 @@ extern void workspace_remove_child(WWorkspace *ws, WThing *thing); extern void init_workspaces(WScreen *scr); +extern bool reset_workspace(WWorkspace *ws, WScreen *scr, bool ci); +bool reattach_orphaned_clients(WWorkspace *ws); extern bool visible_workspace(WWorkspace *ws); extern bool on_visible_workspace(WThing *thing); @@ -48,6 +50,10 @@ extern bool switch_workspace_name(const char *name); extern void switch_workspace_next_n(WScreen *scr, int num); extern void switch_workspace_prev_n(WScreen *scr, int num); + +extern bool save_workspace_nth(WScreen *scr, int num); +extern bool save_workspace_name(const char *str); +extern bool save_workspace_as(const char *fname); extern WWorkspace *lookup_workspace(const char *name); extern int complete_workspace(char *nam, char ***cp_ret, char **beg);