diff -Naur pwm-1.0/Makefile pwm-1.0-p11/Makefile --- pwm-1.0/Makefile Fri Nov 14 14:34:32 2003 +++ pwm-1.0-p11/Makefile Sun Dec 7 13:33:07 2003 @@ -18,7 +18,7 @@ property.o pointer.o key.o moveres.o cursor.o function.o \ exec.o focus.o workspace.o winobj.o screen.o sound.o menu.o \ readconfig.o menudata.o dock.o frameid.o placement.o \ - binding.o winlist.o mwmhints.o signal.o winprops.o + binding.o winlist.o mwmhints.o signal.o winprops.o frameprops.o BINDIR=$(PREFIX)/bin ETCDIR=$(PREFIX)/etc diff -Naur pwm-1.0/clientwin.c pwm-1.0-p11/clientwin.c --- pwm-1.0/clientwin.c Fri Nov 14 14:34:32 2003 +++ pwm-1.0-p11/clientwin.c Sun Dec 7 13:33:07 2003 @@ -20,6 +20,7 @@ #include "focus.h" #include "winlist.h" #include "mwmhints.h" +#include "frameprops.h" #include "winprops.h" #include "sound.h" @@ -171,17 +172,26 @@ } -static void get_initial_winprops(Window win, int *frame_id_ret, int *ws_ret, - int *flags) +static WWinProp* get_initial_winprops(Window win, int *frame_id_ret, + int *ws_ret, int *prop_id_ret, int *flags) { - int ws=-1, frame_id=0; + int ws=-1, frame_id=0, prop_id=0; WWinProp *winprop; winprop=find_winprop_win(win); if(winprop!=NULL){ - ws=winprop->init_workspace; + /* + fprintf(stderr, "Got win-prop %s.%s :\n", winprop->wclass, winprop->winstance); + fprintf(stderr, " workspace %d\n", winprop->init_workspace); + fprintf(stderr, " %s\n", winprop->border ? "BORDER" : "NO BORDER"); + fprintf(stderr, " %s\n", winprop->tab ? "TAB" : "NO TAB"); + fprintf(stderr, " frame %d\n", winprop->init_frame); + fprintf(stderr, " frameprop %d\n", winprop->frameprop); + */ + ws=winprop->init_workspace; frame_id=winprop->init_frame; + if(winprop->frameprop_id!=0) prop_id=winprop->frameprop_id; if(winprop->border==FALSE) *flags|=WFRAME_NO_BORDER; if(winprop->tab==FALSE) @@ -197,9 +207,53 @@ if(ws=SCREEN->n_workspaces) ws=WORKSPACE_CURRENT; + + *frame_id_ret=frame_id; + *ws_ret=ws; + *prop_id_ret=prop_id; + return winprop; +} + + +static WFrameProp* get_initial_frameprops(Window win, int prop_id, + int *frame_id_ret, int *ws_ret, int *flags, XWindowAttributes *attr) +{ + int ws=*ws_ret, frame_id=*frame_id_ret; + WFrameProp *frameprop=NULL; + + if(prop_id!=0) frameprop=find_frameprop(prop_id); + + if(frameprop!=NULL){ + /* + fprintf(stderr, "Got frame-prop %d :\n", frameprop->propid); + fprintf(stderr, " workspace %d\n", frameprop->workspace); + fprintf(stderr, " %s\n", frameprop->border ? "BORDER" : "NO BORDER"); + fprintf(stderr, " %s\n", frameprop->tab ? "TAB" : "NO TAB"); + fprintf(stderr, " %s ", frameprop->geometry ? "geometry" : "no geometry"); + if (frameprop->geometry) + fprintf(stderr, "%dx%d+%d+%d\n", frameprop->w, frameprop->h, frameprop->x, frameprop->y); + */ + if (frameprop->workspace!=-3) + ws=frameprop->workspace; + frame_id=frameprop->frame_id; + if(frameprop->border==FALSE){ + *flags|=WFRAME_NO_BORDER; + } + if(frameprop->tab==FALSE){ + *flags|=WFRAME_NO_BAR; + } + if(frameprop->geometry==TRUE){ + get_frameprop_geometry(frameprop, attr); + } + *flags&=~CWIN_WILD; + + if(ws=SCREEN->n_workspaces) + ws=WORKSPACE_CURRENT; *frame_id_ret=frame_id; *ws_ret=ws; + } + return frameprop; } @@ -320,10 +374,12 @@ int mflags) { WFrame *frame=NULL, *above=NULL; - int frame_id=0, state=NormalState, frameflags=0; + int frame_id=0, prop_id=0, state=NormalState, frameflags=0; int ws=-1; - int w, h; + int w, h, respect; Window win=cwin->client_win; + WWinProp *winprop = NULL; + WFrameProp *frameprop = NULL; if(XGetTransientForHint(wglobal.dpy, win, &(cwin->transient_for))){ above=find_win_frame(cwin->transient_for); @@ -335,9 +391,13 @@ get_mwm_hints(win, &(cwin->flags)); #endif - get_initial_winprops(win, &frame_id, &ws, &(cwin->flags)); + winprop=get_initial_winprops(win, &frame_id, &ws, &prop_id, &(cwin->flags)); + frameprop=get_initial_frameprops(win, prop_id, &frame_id, &ws, &(cwin->flags), attr); frameflags|=cwin->flags&(WFRAME_NO_BORDER|WFRAME_NO_BAR); + if (frameprop && winprop) + frameprop_placement(winprop, frameprop, ws, &frame_id, &prop_id, attr); + #ifndef CF_NO_WILD_WINDOWS if(CWIN_IS_WILD(cwin)){ frameflags|=(WFRAME_NO_BORDER|WFRAME_NO_BAR); @@ -350,9 +410,10 @@ if(frame==NULL){ if((attr->x!=0 || attr->y!=0 || - cwin->size_hints.win_gravity!=ForgetGravity) + cwin->size_hints.win_gravity!=ForgetGravity) || + (frameprop && frameprop->geometry) #ifdef CF_IGNORE_NONTRANSIENT_LOCATION - && cwin->transient_for!=None + && (cwin->transient_for!=None) #endif ){ mflags|=MANAGE_RESPECT_POS; @@ -368,10 +429,13 @@ } frame=create_frame(attr->x, attr->y, attr->width, attr->height, - frame_id, frameflags); + frame_id, prop_id, frameflags); if(frame==NULL) return FALSE; + + if (frameprop && frameprop->geometry) + XResizeWindow(wglobal.dpy, cwin->client_win, attr->width, attr->height); if(above==NULL) add_winobj((WWinObj*)frame, ws, LVL_NORMAL); diff -Naur pwm-1.0/config.txt pwm-1.0-p11/config.txt --- pwm-1.0/config.txt Fri Nov 14 14:34:32 2003 +++ pwm-1.0-p11/config.txt Sun Dec 7 13:33:07 2003 @@ -80,6 +80,10 @@ # Menu entry font menu_font "fontname" + # Menu entry position when using shortcuts + # Default : 1, 1 + menu_pos x, y + # border width: total width of frame border # bevel width: 3d-bevel width border_w , @@ -93,13 +97,19 @@ # # act_tab_sel_colors: Active frame/selected tab # act_tab_colors: Active frame/tab - # act_base_colors: Active frame or menu - # act_sel_colors: Active menu/selected item + # act_base_colors: Active frame + # act_sel_colors: Active selected item + # act_menu_tit_colors: Active menu title + # act_menu_sel_colors: Active menu selected item + # act_menu_base_colors: Active menu base color # # tab_sel_colors: Inactive frame/selected tab # tab_colors: Inactive frame/tab # base_colors: Inactive frame or menu # sel_colors: Inactive menu/selected item + # menu_tit_colors: Inactive menu title + # menu_sel_colors: Inactive menu selected item + # menu_base_colors: Inactive menu base color # # The colors (highlight, shadow, background, foreground) # are normal X color specifications. See the manual page @@ -120,10 +130,95 @@ # is 0 for vertical and 1 for horizontal. dock "position", + # Set dock elements size + # Default is 64, 64 + dock_s , + + # Set dock stacking style + # Stacking styles are : + # + # above : dock is always above other windows + # normal : dock behave just like any other window + # below : dockt is always below other windows + # + # Default is above + dock_stacking + + # Set dock sticky + # Default is yes + dock_sticky + # Set opaque move percent (i.e. windows that take less than # this percentage of screen space are moved opaquely). # Default is 100 - all moves are opaque. opaque_move + + # Set sound player for sound events. + # No default. + "player" + + # Sound groups names : + # + # start_sound + # finish_sound + # appstart_sound (not well implemented) + # appexit_sound (not well implemented) + # shade_sound + # unshade_sound + # maximize_sound + # unmaximize_sound + # stick_sound + # unstick_sound + # attach_sound + # detach_sound + # + # Sound files are files that the previous sound player can + # read. There are no defaults. + "sound_file" + } + + +Frame properties: + + # Initial settings for frame frameprop_id + + frameprop frameprop_id { + + # The frame to initially place windows in. Numbers in + # range [1, 255] can be used. 0 is default, create + # new frame. All windows belonging to that frameprop will be + # put int that frame. + frame + + # Initial workspace for this frame. 0 is the first workspace, + # -1 current and -2 sticky. + workspace + + # Draw borders for this frame + # Default : yes + border + + # Draw tab for this frame + # Default : yes + tab + + # Fixed geometry for this frame and all windows that will be + # put in it. + # No defaults + geometry "WxH+X+Y" + + # Specify what other frames are overlapped by this one. + # The entry is a text string with space-separated numeric ids. + # No defaults + overlaps "id1 id2 id3..." + + # Specify in wat order an app should try to put its frame if + # this one is already used. The same format as for overlaps is + # used. + # One can define multiple try orders but only the 1st is used + # by now. + # No Defaults + try_order "id1 id2 id3..." } @@ -135,10 +230,16 @@ winprop "class.instance" { # The frame to initially place this window in. Numbers in - # range [1, 255] ca be used. 0 is default, create + # range [1, 255] can be used. 0 is default, create # new frame. The property _PWM_FRAME_ID overrides this setting. frame + # The frame property to initially use for this window. Numbers + # in range [1, 255] can be used. 0 is default and uses no + # frameprop. Using a frameprop overwrites all other + # properties not related to frameprops. + frameprop + # Initial workspace for this window. 0 is the first workspace, # -1 current and -2 sticky. This setting is overridden by # the property _PWM_WORKSPACE_NUM. @@ -153,6 +254,35 @@ # app = use mwm hints (default), yes = force wildmode, # no = force normal mode (ignore mwm hints). wildmode + + # Draw borders for this window + # Default : yes + border + + # Draw tab for this window + # Default : yes + tab + + # Policy to use when creating the frame of type 'frameprop_id'. + # force : place the frame without checking for + # other frames + # insert : move overlapping frames so that this one + # does not overlap any other frame + # try_others : try another frameprop if the place is + # taken + # add_to_existing : add to an existing frame if the place is + # taken + # Default : force + add_policy + + # Policy to use when the add_policy cannot be acheived. + # All previous policy except try_others, though using + # 'add_to_existing' twice is not usefull :) + # 'add_' and 'fallback_' policies should be different. In any + # case, if the fallback_policy fails also, the 'force' policy + # is used. + # Default : force + fallback_policy } @@ -172,6 +302,7 @@ toggle_stick - Toggle stickyness toggle_decor - Toggle borders and title on/off + toggle_tab - Toggle tab title on/off toggle_maximize 1|2|3 Toggle maximization of the frame: 1 - vertical @@ -188,6 +319,16 @@ 2 - keep on top attach_tagged - Attach tagged windows to this frame. + change_to_frameprop_f x change frame to use frameprop x + using the 'force' policy. + change_to_frameprop_i x change frame to use frameprop x + using the 'insert' policy. The + other policies are not + necessary since 'attach_tagged' + can be used in place of + 'add_to_existing' and free + places are seen by the user for + 'try_others'. --------------------------------------------------------------------------- frame raise - menu lower - diff -Naur pwm-1.0/frame.c pwm-1.0-p11/frame.c --- pwm-1.0/frame.c Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/frame.c Sun Dec 7 13:33:07 2003 @@ -61,7 +61,7 @@ */ -WFrame* create_frame(int x, int y, int iw, int ih, int id, int flags) +WFrame* create_frame(int x, int y, int iw, int ih, int id, int fp_id, int flags) { WFrame *frame; int w, h; @@ -83,6 +83,7 @@ frame->flags=flags; frame->frame_id=(id==0 ? new_frame_id() : use_frame_id(id)); + frame->frameprop_id=fp_id; frame->frame_iw=iw; frame->frame_ih=ih; frame->frame_ix=frame->frame_iy=b; @@ -140,7 +141,7 @@ { WFrame *frame; - frame=create_frame(root_x, root_y, iiw, iih, 0, 0); + frame=create_frame(root_x, root_y, iiw, iih, 0, 0, 0); if(frame!=NULL) add_winobj((WWinObj*)frame, WORKSPACE_CURRENT, LVL_NORMAL); @@ -239,6 +240,40 @@ if(thing!=NULL) frame_switch_clientwin(frame, (WClientWin*)thing); +} + + +void do_frame_move_to_frameprop(WFrame *frame, WFrameProp *frameprop) +{ + if ((frameprop->flags&XValue) || (frameprop->flags&YValue)) { + set_frame_pos(frame, frameprop->x, frameprop->y); + } + if ((frameprop->flags&WidthValue) || (frameprop->flags&HeightValue)) { + set_frame_size(frame, frameprop->w, frameprop->h); + } + frame->frameprop_id = frameprop->propid; +} + + +void change_to_frameprop_f(WFrame *frame, int frameprop_id) +{ + WFrameProp *at = find_frameprop(frameprop_id); + do_frame_move_to_frameprop(frame, at); +} + + +void change_to_frameprop_i(WFrame *frame, int frameprop_id) +{ + WWinProp wp; + WFrameProp *fp = find_frameprop(frameprop_id); + int frame_id = frame->frame_id, prop_id = frameprop_id; + XWindowAttributes at; + + wp.add_policy = POLICY_INSERT; + + frame->frameprop_id = 0; + frameprop_placement(&wp, fp, SCREEN->current_workspace, &frame_id, &prop_id, &at); + do_frame_move_to_frameprop(frame, fp); } diff -Naur pwm-1.0/frame.h pwm-1.0-p11/frame.h --- pwm-1.0/frame.h Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/frame.h Sun Dec 7 13:33:07 2003 @@ -53,6 +53,7 @@ INHERIT_WWINOBJ; int frame_id; + int frameprop_id; /* Internal (client window) width and height and */ /* X and Y indent of client window within frame window */ @@ -77,7 +78,7 @@ /* */ -extern WFrame *create_frame(int x, int y, int iw, int ih, int id, int flags); +extern WFrame *create_frame(int x, int y, int iw, int ih, int id, int fp_id, int flags); extern WFrame *create_add_frame_simple(int x, int y, int iiw, int iih); extern void destroy_frame(WFrame *frame); @@ -91,6 +92,8 @@ extern void frame_switch_clientwin(WFrame *frame, struct _WClientWin *cwin); extern void frame_switch_nth(WFrame *frame, int cwinnum); extern void frame_switch_rot(WFrame *frame, int rotcnt); +extern void change_to_frameprop_f(WFrame *frame, int frameprop_id); +extern void change_to_frameprop_i(WFrame *frame, int frameprop_id); extern void activate_frame(WFrame *frame); extern void deactivate_frame(WFrame *frame); diff -Naur pwm-1.0/frameprops.c pwm-1.0-p11/frameprops.c --- pwm-1.0/frameprops.c Thu Jan 1 01:00:00 1970 +++ pwm-1.0-p11/frameprops.c Sun Dec 7 13:33:07 2003 @@ -0,0 +1,182 @@ +/* + * pwm/frameprops.c + * + * Copyright (c) Tuomo Valkonen 1999-2000. + * See the included file LICENSE for details. + */ + +#include + +#include "common.h" +#include "property.h" +#include "frameprops.h" + + +static WFrameProp *frameprop_list=NULL; + + +WFrameProp *find_frameprop(int propid) +{ + WFrameProp *prop=frameprop_list, *loosematch=NULL; + int match, bestmatch=0; + + /* I assume there will not be that many frameprops, so a naive algorithm + * and data structure should do. (linear search, linked list) + */ + + for(; prop!=NULL; prop=prop->next){ + match=0; + + if(prop->propid==0) + match+=1; + else if(prop->propid==propid) + match+=2; + else + continue; + + /* exact match? */ + if(match==2) + return prop; + + if(match>bestmatch){ + bestmatch=match; + loosematch=prop; + } + } + + return loosematch; +} + + +void free_fplist(WFPList *list) +{ + while (list) { + WFPList *next = list->next; + free(list); + list = next; + } +} + + +void free_frameprop(WFrameProp *frameprop) +{ + if(frameprop->prev!=NULL){ + UNLINK_ITEM(frameprop_list, frameprop, next, prev); + } + free_fplist(frameprop->overlaps); + while (frameprop->try_list) { + WTryOrder *next = frameprop->try_list->next; + free_fplist(frameprop->try_list->frames_list); + free(frameprop->try_list); + frameprop->try_list = next; + } + free(frameprop); +} + + +void free_all_frameprop() +{ + while (frameprop_list) free_frameprop(frameprop_list); +} + + +void register_frameprop(WFrameProp *frameprop) +{ + LINK_ITEM(frameprop_list, frameprop, next, prev); +} + + +void set_frameprop_geometry(WFrameProp *frameprop, const char *geom) +{ + uint create_w, create_h; + int create_x, create_y, flags; + + flags=XParseGeometry(geom, &create_x, &create_y, &create_w, &create_h); + + if(flags&XNegative){ + create_x+=SCREEN->width-create_w-(2*GRDATA->border_width); + }if(flags&YNegative){ + int t=frameprop->tab?GRDATA->bar_height:0; + create_y+=SCREEN->height-create_h-(2*GRDATA->border_width)-t; + } + frameprop->geometry=TRUE; + frameprop->flags=flags; + frameprop->x=create_x; + frameprop->y=create_y; + frameprop->w=create_w; + frameprop->h=create_h; +} + + +void get_frameprop_geometry(WFrameProp *frameprop, XWindowAttributes *attr) +{ + if ((frameprop->flags&XValue) || (frameprop->flags&YValue)) { + attr->x=frameprop->x; + attr->y=frameprop->y; + } + if ((frameprop->flags&WidthValue) || (frameprop->flags&HeightValue)) { + attr->width=frameprop->w; + attr->height=frameprop->h; + } +} + + +void add_frameprop_id_to_list(WFPList **list, int id) +{ + WFPList *ptr = *list; + + if (! ptr) { + ptr = ALLOC(WFPList); + *list = ptr; + } else { + while (ptr->next != NULL) ptr = ptr->next; + ptr->next = ALLOC(WFPList); + ptr = ptr->next; + } + ptr->frameprop_id = id; + ptr->next = NULL; +} + + +void frameprop_parse_idlist(WFPList **fplist, const char *str) +{ + char *list = strdup(str); + char *token; + + if (!list) return; + token = strtok(list, " "); + do { + int propid = atoi(token); + add_frameprop_id_to_list(fplist, propid); + token = strtok(NULL, " "); + } while (token != NULL); + free(list); +} + + +void set_frameprop_overlap(WFrameProp *frameprop, const char *over) +{ + frameprop_parse_idlist(&(frameprop->overlaps), over); +} + + +void set_frameprop_try_order(WFrameProp *frameprop, const char *order) +{ + WTryOrder *ptr = frameprop->try_list; + int prev = 0; + + if (! ptr) { + ptr = ALLOC(WTryOrder); + frameprop->try_list = ptr; + } else { + while (ptr->next != NULL) ptr = ptr->next; + prev = ptr->id; + ptr->next = ALLOC(WTryOrder); + ptr = ptr->next; + } + ptr->id = prev + 1; + ptr->frames_list = NULL; + frameprop_parse_idlist(&(ptr->frames_list), order); + ptr->next = NULL; +} + diff -Naur pwm-1.0/frameprops.h pwm-1.0-p11/frameprops.h --- pwm-1.0/frameprops.h Thu Jan 1 01:00:00 1970 +++ pwm-1.0-p11/frameprops.h Sun Dec 7 13:33:07 2003 @@ -0,0 +1,51 @@ +/* + * pwm/frameprops.h + * + * Copyright (c) Thomas Nemeth 2003. + * See the included file LICENSE for details. + */ + +#ifndef INCLUDED_FRAMEPROPS_H +#define INCLUDED_FRAMEPROPS_H + +#include "common.h" +#include "winobj.h" + +typedef struct _WFPList { + int frameprop_id; + struct _WFPList *next; +} WFPList; + +typedef struct _WTryOrder { + int id; + WFPList *frames_list; + struct _WTryOrder *next; +} WTryOrder; + +typedef struct _WFrameProp { + int propid; + int frame_id; + int workspace; + int border; + int tab; + int geometry; + int flags; + int x, y, w, h; + WFPList *overlaps; + WTryOrder *try_list; + + struct _WFrameProp *next, *prev; +} WFrameProp; + + +extern WFrameProp *find_frameprop(int propid); +extern void free_frameprop(WFrameProp *frameprop); +extern void free_all_frameprop(); +extern void register_frameprop(WFrameProp *frameprop); +extern void set_frameprop_geometry(WFrameProp *frameprop, const char *geom); +extern void get_frameprop_geometry(WFrameProp *frameprop, XWindowAttributes *attr); +extern void add_frameprop_id_to_list(WFPList **list, int id); +extern void set_frameprop_overlap(WFrameProp *frameprop, const char *over); +extern void set_frameprop_try_order(WFrameProp *frameprop, const char *order); + +#endif /* INCLUDED_FRAMEPROPS_H */ diff -Naur pwm-1.0/function.c pwm-1.0-p11/function.c --- pwm-1.0/function.c Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/function.c Sun Dec 7 13:33:07 2003 @@ -117,6 +117,8 @@ FN(frame_i, "switch_nth", frame_switch_nth), FN(frame_i, "switch_rot", frame_switch_rot), FN(frame_i, "set_stack_lvl", wrap_set_stack_lvl), + FN(frame_i, "chg_to_frameprop_f", change_to_frameprop_f), + FN(frame_i, "chg_to_frameprop_i", change_to_frameprop_i), /* winobj */ FN(winobj, "raise", raise_winobj), diff -Naur pwm-1.0/main.c pwm-1.0-p11/main.c --- pwm-1.0/main.c Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/main.c Sun Dec 7 13:33:07 2003 @@ -26,6 +26,8 @@ #include "readconfig.h" #include "winlist.h" #include "sound.h" +#include "winprops.h" +#include "frameprops.h" static bool initialize(const char *display, const char *cfgfile, @@ -256,6 +258,8 @@ return; deinit_screen(); + free_all_winprop(); + free_all_frameprop(); dpy=wglobal.dpy; wglobal.dpy=NULL; diff -Naur pwm-1.0/placement.c pwm-1.0-p11/placement.c --- pwm-1.0/placement.c Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/placement.c Sun Dec 7 13:33:07 2003 @@ -11,6 +11,7 @@ #include "placement.h" #include "screen.h" #include "frame.h" +#include "frameid.h" #include "pointer.h" @@ -285,5 +286,439 @@ *xret=0; *yret=0; random_placement(SCREEN->width-w, SCREEN->height-h, xret, yret); +} + + +/********************************************************************** + * HERE IS THOMAS' NEW PLACEMENT POLICY + ********************************************************************** + * + * ADD/REMOVE fprintf : + * :.,$s§fprintf\(.*\);§AAfprintf\1;BB§ + * :.,$s§AAfprinf\(.*\);BB§fprintf\1;§ + * + * WITH + * AA == begin of comment + * BB == end of comment + * + * Don't forget the XXX below. + */ + + +/* Get the map element concerning a frameprop. Creates it if it does not + * exist. + * returns the map element + */ +static WSUsage *get_wsu(WSUsage **wsu, int id) { + WSUsage *ptr = *wsu, *prev = NULL; + + if (! ptr) { + ptr = ALLOC(WSUsage); + ptr->frameprop = find_frameprop(id); + ptr->next = NULL; + ptr->occupying_frames = NULL; + ptr->overlapping_frames = NULL; + *wsu = ptr; + } else { + int fid = ptr->frameprop->propid; + prev = ptr; + while ((fid != id) && ptr) { + prev = ptr; + ptr = ptr->next; + fid = ptr ? ptr->frameprop->propid : 0; + } + if (! ptr) { + prev->next = ALLOC(WSUsage); + ptr = prev->next; + ptr->frameprop = find_frameprop(id); + ptr->next = NULL; + ptr->occupying_frames = NULL; + ptr->overlapping_frames = NULL; + } + } + return ptr; +} + + +/* Check if a frameprop is in conflict with another + */ +static bool fp_is_occupied(WFrameProp *reqfp, int curfp_id) { + bool occ = FALSE; + WFPList *l = reqfp ? reqfp->overlaps : NULL; + + if (!reqfp) return occ; + if (reqfp->propid == curfp_id) { + /*fprintf(stderr, " rqst fp (%d) is occupied by current\n", reqfp->propid);*/ + occ = TRUE; + } + while (l && (!occ)) { + if (l->frameprop_id == curfp_id) { + /*fprintf(stderr, " rqst SUB fp (%d) is occupied by current\n", l->frameprop_id);*/ + occ = TRUE; + } + l = l->next; + } + /*fprintf(stderr, " (r %d / c %d) -> %s\n", reqfp ? reqfp->propid : -1, curfp_id, occ ? "OCC" : "free");*/ + return occ; +} + + +/* Adds a frame to the workspace usage map + * returns TRUE if the requested frameprop is occupied/overlapped + */ +static bool add_frame_to_wsu(WFrame *frame, WFrameProp *fp, WSUsage **wsu) { + WSUsage *ptr = NULL; + WFPList *over; + bool occ = FALSE; + + /*fprintf(stderr, "(RQFP: %d) Frame in workspace (id) : %d\n", fp ? fp->propid : -1, frame->frame_id);*/ + /* Get the 'current' frame description on workspace usage */ + ptr = get_wsu(wsu, frame->frameprop_id); + /* Add the 'current' frame to the description in 'occupying' + */ + add_frameprop_id_to_list(&(ptr->occupying_frames), frame->frame_id); + if (fp_is_occupied(fp, frame->frameprop_id)) occ = TRUE; + + /* Do the same for all the frameprops this frame overlaps */ + over = ptr->frameprop->overlaps; + while (over) { + /*fprintf(stderr, " overlaps %d.\n", over->frameprop_id);*/ + ptr = get_wsu(wsu, over->frameprop_id); + add_frameprop_id_to_list(&(ptr->overlapping_frames), frame->frame_id); + if (fp_is_occupied(fp, over->frameprop_id)) occ = TRUE; + over = over->next; + } + return occ; +} + + +/* Remove a frame from the workspace usage */ +static void remove_frame_from_wsu(WFrame *frame, WSUsage *wsu) { + WSUsage *w = wsu; + + /*fprintf(stderr, " Removing frame %d from workspace...\n", frame->frame_id);*/ + while (w) { + WFPList *l = w->occupying_frames; + while (l) { + if (l->frameprop_id == frame->frame_id) { + l->frameprop_id = -1; + break; + } + l = l->next; + } + + l = w->overlapping_frames; + while (l) { + if (l->frameprop_id == frame->frame_id) { + l->frameprop_id = -1; + break; + } + l = l->next; + } + + w = w->next; + } +} + + +/* Creates a map of the current workspace usage by frames using frameprops + * returns TRUE if the requested frameprop is occupied/overlapped + */ +static bool get_ws_usage(int ws, WFrameProp *fp, WSUsage **wsu) { + WFrame *current; + bool occ = FALSE; + + current = (WFrame*)subthing((WThing*)SCREEN, WTHING_FRAME); + + for(current = (WFrame*)subthing((WThing*)SCREEN, WTHING_FRAME) ; + current != NULL ; + current = (WFrame*)next_thing((WThing*)current, WTHING_FRAME)) { + + if(current->workspace!=ws && current->workspace!=WORKSPACE_STICKY) + continue; + + if(!WWINOBJ_IS_MAPPED(current)) + continue; + + if(WTHING_IS(current, WTHING_FRAME) && !WFRAME_IS_SHADE(current)) { + /* Keep only the frames that have a frameprop_id */ + if (current->frameprop_id != 0) { + if (add_frame_to_wsu(current, fp, wsu)) + occ = TRUE; + } + } + } + + return occ; +} + + +/* PLACEMENT : look for a frame the same frameprop as requested + * returns TRUE if found, FALSE otherwise + */ +static bool add2E_placement(WSUsage *wsu, WFrameProp *fp, int *frame_id) { + WSUsage *ptr = wsu; /* start with the 1st frame found on the workspace */ + + /*fprintf(stderr, " Trying ADD_TO_EXISTING placement... ");*/ + while (ptr) { + /* if the current tested frame has the same frameprop_id than the + * requested one then use this frame by getting back its ID. */ + if ((ptr->frameprop->propid == fp->propid) && ptr->occupying_frames) { + *frame_id = ptr->occupying_frames->frameprop_id; + /*fprintf(stderr, "occupying frame : [%d]\n", *frame_id);*/ + return TRUE; + } + ptr = ptr->next; + } + /*fprintf(stderr, "no occupying frame.\n");*/ + return FALSE; +} + + +/* tells if a frame is the only one to overlap a frameprop */ +static bool frame_is_alone(int frame_id, WSUsage *occ_fp) { + /*fprintf(stderr, "+++ Overlapping frames of %d : ", frame_id);*/ + /*fprintf(stderr, "%s", occ_fp->overlapping_frames ? (occ_fp->overlapping_frames->next ? "MORE than one !" : "ONLY ONE") : "NONE");*/ + /*fprintf(stderr, " first -> %d (-1 for none)\n",occ_fp->overlapping_frames ? occ_fp->overlapping_frames->frameprop_id : -1);*/ + if ( ( + (occ_fp->overlapping_frames == NULL) || + ((occ_fp->overlapping_frames->frameprop_id == frame_id) && + (occ_fp->overlapping_frames->next == NULL)) + ) && (occ_fp->occupying_frames == NULL) + ) + return TRUE; + return FALSE; +} + + +/* Check if the tested frameprop is free or not + * frameprop_id is the frameprop we would like to use + * frame_id is the frame id of the frame being moved (or 0) + * avoid is a frameprop to be avoided (or NULL) + */ +static bool check_fp(int frameprop_id, WSUsage *wsu, int frame_id, WFrameProp *avoid) { + WSUsage *occ_fp = wsu; + + /*fprintf(stderr, " testing overlapped frameprop %d : ", frameprop_id);*/ + /* test if the overlapped frameprop is to be avoided */ + if (fp_is_occupied(avoid, frameprop_id)) { + /*fprintf(stderr, " AVOIDED.\n");*/ + return FALSE; + } + while (occ_fp) { + /* if the wsu frame'id is the one we want to be free + * then the place is not free */ + if (occ_fp->frameprop->propid == frameprop_id) { + /* but if the only frame that overlaps that frameprop is + * the one that is to be relocated, take that frameprop as + * free + * else the frameprop is occupied anyway */ + if (frame_id != 0) { + if (! frame_is_alone(frame_id, occ_fp)) { + /*fprintf(stderr, " OCCUPIED.\n");*/ + return FALSE; + } + } else { + /*fprintf(stderr, " OCCUPIED.\n");*/ + return FALSE; + } + } + occ_fp = occ_fp->next; + } + /*fprintf(stderr, " FREE !\n");*/ + return TRUE; +} + + +/* Check all the frameprops in the try_order list for a given frameprop */ +static bool check_fplist(WFPList *test_fp, WSUsage *wsu, int frame_id, WFrameProp *avoid) { + while (test_fp) { + if (!check_fp(test_fp->frameprop_id, wsu, frame_id, avoid)) + return FALSE; + test_fp = test_fp->next; + } + return TRUE; +} + + +/* PLACEMENT : try other frameprops + * returns TRUE if a place is found, FALSE otherwise + */ +static bool try_others_placement(WSUsage *wsu, WFrameProp *fp, int frame_id, + WFrameProp *avoid, int *prop_id, XWindowAttributes *attr) { + /* begin with the 1st frameprop to try */ + WFPList *try_fp_elt = fp->try_list ? fp->try_list->frames_list : NULL; + + /*fprintf(stderr, " Trying TRY_OTHERS placement...\n");*/ + while (try_fp_elt) { + /* Assume the place is free */ + bool libre = TRUE; + /* Get the tryed frameprop by it's id */ + WFrameProp *try_fp = find_frameprop(try_fp_elt->frameprop_id); + + /* Test all the frameprops the tryed one overlaps */ + /*fprintf(stderr, " - Trying frameprop %d :\n", try_fp_elt->frameprop_id);*/ + + /* Look for all the frames that have frameprops in the workspace + * and that conflicts with the tryed one */ + libre = check_fp(try_fp->propid, wsu, frame_id, avoid); + + /*fprintf(stderr, " Trying sub-frameprops (overlapped by) of %d :\n", try_fp_elt->frameprop_id);*/ + if (libre) + libre = check_fplist(try_fp->overlaps, wsu, frame_id, avoid); + /*fprintf(stderr, " done for %d.\n", try_fp_elt->frameprop_id);*/ + + /* after testing all the frames that are overlapped by the tryed one, + * if the place is free, stop testing other 'to try' frames : + * this tested frameprop is the one we'll use */ + if (libre) { + /*fprintf(stderr, " FOUND (frameprop %d) !\n", try_fp->propid);*/ + *prop_id = try_fp->propid; + get_frameprop_geometry(try_fp, attr); + return TRUE; + } + try_fp_elt = try_fp_elt->next; + } + + return FALSE; +} + + +/* Look for a suitable place for an already mapped frame. + * Love it if place is found. Leave it otherwise. + */ +static void move_frames(WSUsage *wsu, WFPList *list, WFrameProp *avoidfp) { + WFPList *frames_list = list; + + while (frames_list) { + /* Look for a free place for that frame */ + /* Get the frame from its ID (frameprop_id is in fact the frame_id) */ + WFrame *frame_obj = find_frame_by_id(frames_list->frameprop_id); + WFrameProp *pfp; + XWindowAttributes at; + int new_propid; + + /* If this frame has already been moved, pass on */ + if (frames_list->frameprop_id == -1) { + frames_list = frames_list->next; + continue; + } + + pfp = find_frameprop(frame_obj->frameprop_id); + + /*fprintf(stderr, " + Frame %d (frameprop %d) :\n", frames_list->frameprop_id, pfp ? pfp->propid : -1);*/ + + /* Use the try_others policy but avoid fp->propid */ + if (pfp && try_others_placement(wsu, pfp, frame_obj->frame_id, avoidfp, &new_propid, &at)) { + + /* Move frame to that position */ + /*fprintf(stderr, " -> moving to frameprop %d... ", new_propid);*/ + remove_frame_from_wsu(frame_obj, wsu); + change_to_frameprop_f(frame_obj, new_propid); + add_frame_to_wsu(frame_obj, NULL, &wsu); + /*fprintf(stderr, "done.\n");*/ + /*} else { XXX */ + /* if not placed, keep it as it is */ + /*fprintf(stderr, " -> could not move.\n");*/ + } + frames_list = frames_list->next; + } +} + + +/* PLACEMENT : insert a frame in the workspace, moving all overlapped or + * overlapping already mapped frames + */ +static bool insert_placement(WSUsage *wsu, WFrameProp *fp, XWindowAttributes *attr) { + WSUsage *ptr = wsu; /* Start with the 1st frame found on the workspace */ + + /*fprintf(stderr, " Trying INSERT_FRAME placement...\n");*/ + while (ptr) { + + /* if the current frameprop used on the screen has the same ID as the + * requested one then */ + int occupying_fp = fp_is_occupied(fp, ptr->frameprop->propid); + if (occupying_fp) { + + /* Move all the occupying frames to another position */ + /*fprintf(stderr, " -> moving frameprop %d occupying frames (for %d).\n", fp->propid, ptr->frameprop->propid);*/ + move_frames(wsu, ptr->occupying_frames, fp); + + /* And move all the overlapping frames also */ + /*fprintf(stderr, " -> moving frameprop %d overlapping frames (for %d).\n", fp->propid, ptr->frameprop->propid);*/ + move_frames(wsu, ptr->overlapping_frames, fp); + /* job's done */ + /*return TRUE;*/ + } + ptr = ptr->next; + } + return TRUE; +} + + +/* PLACEMENT : main placement function + */ +void frameprop_placement(WWinProp *wp, WFrameProp *fp, int ws, int *frame_id, int *prop_id, XWindowAttributes *attr) { + bool placed = FALSE; + WSUsage *wsu = NULL; + + if (ws < 0) ws = SCREEN->current_workspace; + + /*fprintf(stderr, "+++ Placing clientwin...\n");*/ + if (wp->add_policy != POLICY_FORCE) { + bool occupied = get_ws_usage(ws, fp, &wsu); + if (occupied) { + /*fprintf(stderr, " ==> place already used !\n");*/ + switch (wp->add_policy) { + case POLICY_ADD_TO_EXISTING: + placed = add2E_placement(wsu, fp, frame_id); + break; + case POLICY_TRY_OTHERS: + placed = try_others_placement(wsu, fp, 0, NULL, prop_id, attr); + break; + case POLICY_INSERT: + placed = insert_placement(wsu, fp, attr); + break; + default: break; + } + } else { + placed = TRUE; + /*fprintf(stderr, " ==> place ok !\n");*/ + } + } else { + placed = TRUE; + /*fprintf(stderr, " ==> place ok !\n");*/ + } + + if (! placed) { + switch (wp->fallback_policy) { + case POLICY_ADD_TO_EXISTING: + placed = add2E_placement(wsu, fp, frame_id); + break; + case POLICY_INSERT: + placed = insert_placement(wsu, fp, attr); + break; + default: break; + } + } + + while (wsu) { + WSUsage *next = wsu->next; + WFPList *list = wsu->occupying_frames; + while (list) { + WFPList *nfp = list->next; + free(list); + list = nfp; + } + list = wsu->overlapping_frames; + while (list) { + WFPList *nfp = list->next; + free(list); + list = nfp; + } + free(wsu); + wsu = next; + } + /*fprintf(stderr, "--- Placing done !\n");*/ } diff -Naur pwm-1.0/placement.h pwm-1.0-p11/placement.h --- pwm-1.0/placement.h Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/placement.h Sun Dec 7 13:33:07 2003 @@ -8,6 +8,17 @@ #ifndef INCLUDED_PLACEMENT_H #define INCLUDED_PLACEMENT_H +#include "frameprops.h" +#include "winprops.h" + +typedef struct _WSUsage{ + WFrameProp *frameprop; + WFPList *occupying_frames; + WFPList *overlapping_frames; + struct _WSUsage *next; +} WSUsage; + extern void calc_placement(int w, int h, int ws, int *xret, int *yret); +extern void frameprop_placement(WWinProp *wp, WFrameProp *fp, int ws, int *frame_id, int *prop_id, XWindowAttributes *attr); #endif /* INCLUDED_PLACEMENT_H */ diff -Naur pwm-1.0/readconfig.c pwm-1.0-p11/readconfig.c --- pwm-1.0/readconfig.c Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/readconfig.c Sun Dec 7 13:33:07 2003 @@ -14,6 +14,7 @@ #include "readconfig.h" #include "function.h" #include "binding.h" +#include "frameprops.h" #include "winprops.h" #include "frameid.h" #include "dock.h" @@ -22,6 +23,7 @@ static uint default_mod=0; static WScreen *tmp_screen; static WMenuData *tmp_menudata=NULL; +static WFrameProp *tmp_frameprop=NULL; static WWinProp *tmp_winprop=NULL; static int tmp_actx=0; static uint tmp_state=0; @@ -871,6 +873,170 @@ /* + * Frame props + */ + + +static bool opt_frameprop_frame(Tokenizer *tokz, int n, Token *toks) +{ + int f=TOK_LONG_VAL(&(toks[1])); + + if(f>FRAME_ID_START_CLIENT){ + warn_obj_line(tokz->name, toks[1].line, "Frame ID should be < %d\n", + FRAME_ID_START_CLIENT); + return FALSE; + } + + tmp_frameprop->frame_id=f; + + return TRUE; +} + + +static bool opt_frameprop_workspace(Tokenizer *tokz, int n, Token *toks) +{ + int w=TOK_LONG_VAL(&(toks[1])); + + if(wname, toks[1].line, "Invalid workspace number"); + return FALSE; + } + + tmp_frameprop->workspace=w; + + return TRUE; +} + + +static bool opt_frameprop_border(Tokenizer *tokz, int n, Token *toks) +{ + char *s=TOK_STRING_VAL(&(toks[1])); + + if(strcmp(s, "yes")==0){ + tmp_frameprop->border=TRUE; + }else if(strcmp(s, "no")==0){ + tmp_frameprop->border=FALSE; + }else{ + warn_obj_line(tokz->name, toks[1].line, "Invalid border (yes/no)"); + return FALSE; + } + + return TRUE; +} + + +static bool opt_frameprop_tab(Tokenizer *tokz, int n, Token *toks) +{ + char *s=TOK_STRING_VAL(&(toks[1])); + + if(strcmp(s, "yes")==0){ + tmp_frameprop->tab=TRUE; + }else if(strcmp(s, "no")==0){ + tmp_frameprop->tab=FALSE; + }else{ + warn_obj_line(tokz->name, toks[1].line, "Invalid tab (yes/no)"); + return FALSE; + } + + return TRUE; +} + + +static bool opt_frameprop_geometry(Tokenizer *tokz, int n, Token *toks) +{ + char *s=TOK_STRING_VAL(&(toks[1])); + + if(s!=NULL){ + set_frameprop_geometry(tmp_frameprop, s); + }else{ + warn_obj_line(tokz->name, toks[1].line, "Invalid geometry"); + return FALSE; + } + + return TRUE; +} + + +static bool opt_frameprop_overlaps(Tokenizer *tokz, int n, Token *toks) +{ + char *s=TOK_STRING_VAL(&(toks[1])); + + if(s!=NULL){ + set_frameprop_overlap(tmp_frameprop, s); + }else{ + warn_obj_line(tokz->name, toks[1].line, "Invalid overlaps"); + return FALSE; + } + + return TRUE; +} + + +static bool opt_frameprop_try_order(Tokenizer *tokz, int n, Token *toks) +{ + char *s=TOK_STRING_VAL(&(toks[1])); + + if(s!=NULL){ + set_frameprop_try_order(tmp_frameprop, s); + }else{ + warn_obj_line(tokz->name, toks[1].line, "Invalid overlaps"); + return FALSE; + } + + return TRUE; +} + + +static bool begin_frameprop(Tokenizer *tokz, int n, Token *toks) +{ + char s[10]; + tmp_frameprop=ALLOC(WFrameProp); + + if(tmp_frameprop==NULL){ + warn_err(); + return FALSE; + } + + tmp_frameprop->propid=TOK_LONG_VAL(&(toks[1])); + tmp_frameprop->frame_id=0; + tmp_frameprop->workspace=-3; + tmp_frameprop->border=TRUE; + tmp_frameprop->tab=TRUE; + tmp_frameprop->geometry=FALSE; + tmp_frameprop->x=0; + tmp_frameprop->y=0; + tmp_frameprop->w=0; + tmp_frameprop->h=0; + tmp_frameprop->overlaps=NULL; + tmp_frameprop->try_list=NULL; + /* + snprintf(s, 9, "%d", tmp_frameprop->propid); + set_frameprop_overlap(tmp_frameprop, s); + */ + + return TRUE; +} + + +static bool end_frameprop(Tokenizer *tokz, int n, Token *toks) +{ + register_frameprop(tmp_frameprop); + tmp_frameprop=NULL; + + return TRUE; +} + + +static bool cancel_frameprop(Tokenizer *tokz, int n, Token *toks) +{ + free_frameprop(tmp_frameprop); + tmp_frameprop=NULL; + + return TRUE; +} + + +/* * Window props */ @@ -891,6 +1057,22 @@ } +static bool opt_winprop_frameprop(Tokenizer *tokz, int n, Token *toks) +{ + int f=TOK_LONG_VAL(&(toks[1])); + + if(f>FRAME_ID_START_CLIENT){ + warn_obj_line(tokz->name, toks[1].line, "Frame ID should be < %d\n", + FRAME_ID_START_CLIENT); + return FALSE; + } + + tmp_winprop->frameprop_id=f; + + return TRUE; +} + + static bool opt_winprop_workspace(Tokenizer *tokz, int n, Token *toks) { int w=TOK_LONG_VAL(&(toks[1])); @@ -969,6 +1151,46 @@ } +static bool opt_winprop_add_policy(Tokenizer *tokz, int n, Token *toks) +{ + char *s=TOK_STRING_VAL(&(toks[1])); + + if(strcmp(s, "force")==0){ + tmp_winprop->add_policy=POLICY_FORCE; + }else if(strcmp(s, "add_to_existing")==0){ + tmp_winprop->add_policy=POLICY_ADD_TO_EXISTING; + }else if(strcmp(s, "insert")==0){ + tmp_winprop->add_policy=POLICY_INSERT; + }else if(strcmp(s, "try_others")==0){ + tmp_winprop->add_policy=POLICY_TRY_OTHERS; + }else{ + warn_obj_line(tokz->name, toks[1].line, "Invalid policy"); + return FALSE; + } + + return TRUE; +} + + +static bool opt_winprop_fallback_policy(Tokenizer *tokz, int n, Token *toks) +{ + char *s=TOK_STRING_VAL(&(toks[1])); + + if(strcmp(s, "force")==0){ + tmp_winprop->fallback_policy=POLICY_FORCE; + }else if(strcmp(s, "add_to_existing")==0){ + tmp_winprop->fallback_policy=POLICY_ADD_TO_EXISTING; + }else if(strcmp(s, "insert")==0){ + tmp_winprop->fallback_policy=POLICY_INSERT; + }else{ + warn_obj_line(tokz->name, toks[1].line, "Invalid policy"); + return FALSE; + } + + return TRUE; +} + + static bool begin_winprop(Tokenizer *tokz, int n, Token *toks) { WWinProp *wrop; @@ -983,8 +1205,11 @@ tmp_winprop->init_workspace=WORKSPACE_CURRENT; tmp_winprop->init_frame=0; + tmp_winprop->frameprop_id=0; tmp_winprop->border=TRUE; tmp_winprop->tab=TRUE; + tmp_winprop->add_policy=POLICY_FORCE; + tmp_winprop->fallback_policy=POLICY_FORCE; tmp_winprop->data=wclass=TOK_TAKE_STRING_VAL(&(toks[1])); @@ -1107,13 +1332,32 @@ }; +static ConfOpt frameprop_opts[]={ + {"frame", "l", opt_frameprop_frame, NULL}, + {"workspace", "l", opt_frameprop_workspace, NULL}, + {"border", "i", opt_frameprop_border, NULL}, + {"tab", "i", opt_frameprop_tab, NULL}, + {"geometry", "s", opt_frameprop_geometry, NULL}, + {"overlaps", "s", opt_frameprop_overlaps, NULL}, + {"try_order", "s", opt_frameprop_try_order, NULL}, + + {"#end", NULL, end_frameprop, NULL}, + {"#cancel", NULL, cancel_frameprop, NULL}, + + {NULL, NULL, NULL, NULL} +}; + + static ConfOpt winprop_opts[]={ {"frame", "l", opt_winprop_frame, NULL}, + {"frameprop", "l", opt_winprop_frameprop, NULL}, {"workspace", "l", opt_winprop_workspace, NULL}, {"dockpos", "l", opt_winprop_dockpos, NULL}, {"wildmode", "i", opt_winprop_wildmode, NULL}, {"border", "i", opt_winprop_border, NULL}, {"tab", "i", opt_winprop_tab, NULL}, + {"add_policy", "s", opt_winprop_add_policy, NULL}, + {"fallback_policy", "s", opt_winprop_fallback_policy, NULL}, {"#end", NULL, end_winprop, NULL}, {"#cancel", NULL, cancel_winprop, NULL}, @@ -1139,6 +1383,9 @@ {"screen", "l+", begin_screen, screen_opts}, {"dblclick_delay", "l", opt_dblclick_delay, NULL}, + + /* frame props */ + {"frameprop" , "l", begin_frameprop, frameprop_opts}, /* window props */ {"winprop" , "s", begin_winprop, winprop_opts}, diff -Naur pwm-1.0/winprops.c pwm-1.0-p11/winprops.c --- pwm-1.0/winprops.c Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/winprops.c Sun Dec 7 13:33:07 2003 @@ -87,6 +87,13 @@ if(winprop->data!=NULL) free(winprop->data); + free(winprop); +} + + +void free_all_winprop() +{ + while (winprop_list) free_winprop(winprop_list); } diff -Naur pwm-1.0/winprops.h pwm-1.0-p11/winprops.h --- pwm-1.0/winprops.h Fri Nov 14 14:34:33 2003 +++ pwm-1.0-p11/winprops.h Sun Dec 7 13:33:07 2003 @@ -16,6 +16,13 @@ WILDMODE_YES=1, WILDMODE_NO=2 }; + +enum{ + POLICY_FORCE=0, + POLICY_ADD_TO_EXISTING=1, + POLICY_INSERT=2, + POLICY_TRY_OTHERS=3 +}; typedef struct _WWinProp { char *data; @@ -23,11 +30,14 @@ char *winstance; int init_frame; + int frameprop_id; int init_workspace; int dockpos; int wildmode; int border; int tab; + int add_policy; + int fallback_policy; struct _WWinProp *next, *prev; } WWinProp; @@ -35,6 +45,7 @@ extern WWinProp *find_winprop(const char *wclass, const char *winstance); extern WWinProp *find_winprop_win(Window win); extern void free_winprop(WWinProp *winprop); +extern void free_all_winprop(); extern void register_winprop(WWinProp *winprop); #endif /* INCLUDED_WINPROPS_H */