From f869221ce49f0fb7cca48eee28daff8684305963 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 22 Dec 2007 00:49:26 +0000 Subject: [PATCH] [svn-upgrade] Integrating new upstream version, ion3 (20071220) --- ChangeLog | 101 ++++++++++++++ LICENSE | 31 +++-- Makefile | 3 + README | 8 +- RELNOTES | 7 + build/rules.mk | 4 + etc/cfg_ioncore.lua | 19 ++- etc/cfg_query.lua | 3 + exact-version | 4 +- ion/Makefile | 3 +- ion/ion.c | 25 +++- ioncore/Makefile | 5 +- ioncore/activity.c | 3 +- ioncore/attach.c | 37 ++++- ioncore/attach.h | 5 + ioncore/basicpholder.c | 9 +- ioncore/binding.c | 4 +- ioncore/classes.h | 2 + ioncore/clientwin.c | 24 +++- ioncore/detach.c | 7 +- ioncore/focus.c | 8 +- ioncore/focus.h | 2 +- ioncore/frame-draw.c | 38 +++--- ioncore/frame-draw.h | 2 +- ioncore/frame.c | 231 +++++++++----------------------- ioncore/frame.h | 4 - ioncore/framedpholder.c | 63 ++++++--- ioncore/framedpholder.h | 3 +- ioncore/group-cw.c | 78 ++++++++--- ioncore/group-ws.c | 42 +++--- ioncore/group.c | 93 ++++++++++--- ioncore/group.h | 2 +- ioncore/groupedpholder.c | 195 --------------------------- ioncore/groupedpholder.h | 38 ------ ioncore/grouppholder.c | 211 ++++++++++++++++++++++++----- ioncore/grouppholder.h | 9 +- ioncore/ioncore.c | 1 - ioncore/ioncore_ext.lua | 1 + ioncore/ioncore_quasiact.lua | 74 ++++++++++ ioncore/ioncore_wd.lua | 17 +-- ioncore/manage.c | 31 +++-- ioncore/manage.h | 2 + ioncore/mplex.c | 137 +++++++++---------- ioncore/mplex.h | 2 +- ioncore/mplexpholder.c | 214 +++++++++++++++-------------- ioncore/mplexpholder.h | 6 +- ioncore/names.c | 6 +- ioncore/pholder.c | 76 ++--------- ioncore/pholder.h | 9 +- ioncore/pointer.c | 95 ++++++++++--- ioncore/return.c | 15 +++ ioncore/saveload.c | 45 +++---- ioncore/saveload.h | 8 +- ioncore/tags.c | 3 +- libextl/exact-version | 7 + libextl/private.h | 5 +- libtu/Makefile | 2 +- libtu/exact-version | 3 + libtu/prefix.c | 61 +++++++++ libtu/prefix.h | 17 +++ man/Makefile | 16 ++- mod_query/input.c | 6 +- mod_query/input.h | 2 +- mod_query/main.c | 9 +- mod_query/main.h | 1 + mod_query/mod_query.lua | 12 +- mod_statusbar/statusbar.c | 3 +- mod_tiling/tiling.c | 5 +- pwm/Makefile | 3 +- pwm/pwm.c | 27 ++-- system.mk | 5 +- utils/ion-completeman.in | 6 +- utils/ion-statusd/Makefile | 5 +- utils/ion-statusd/ion-statusd.c | 18 ++- version.h | 2 +- 75 files changed, 1303 insertions(+), 977 deletions(-) delete mode 100644 ioncore/groupedpholder.c delete mode 100644 ioncore/groupedpholder.h create mode 100644 ioncore/ioncore_quasiact.lua create mode 100644 libtu/prefix.c create mode 100644 libtu/prefix.h diff --git a/ChangeLog b/ChangeLog index cfe4c84..dee0e0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,107 @@ +2007-12-20 18:45 UTC Tuomo Valkonen + tagged ion-3rc-20071220 + +2007-12-20 18:13 UTC Tuomo Valkonen + * Split relocation code into libtu + +2007-11-09 19:14 UTC Tuomo Valkonen + * Build hacks for relocatable binary + +2007-11-09 19:02 UTC Tuomo Valkonen + * Fixed textdomain setup in reloc. binary + +2007-11-09 15:56 UTC Tuomo Valkonen + * Support for relocatable package/binary + +2007-12-20 17:35 UTC Tuomo Valkonen + * Release notes + +2007-12-20 17:31 UTC Tuomo Valkonen + * Simplifications in definition of significant change + +2007-12-19 18:45 UTC Tuomo Valkonen + * Added missing checks for attempts of between-root reparenting. + (Stupid artificially restricted XReparentWindow.) + +2007-12-19 00:09 UTC Tuomo Valkonen + * Changed stacking level setting on detach + +2007-12-19 00:06 UTC Tuomo Valkonen + * Moved detach binding to WMPlex.toplevel from WMPlex. + (Transient are detached with their full original frames now, instead + of being recreated on.) + +2007-12-15 14:58 UTC Tuomo Valkonen + * Use LuaFileSystem instead of LuaPosix (if available) for directory existence checks. + It seems to be the better supported approach. + +2007-12-15 14:42 UTC Tuomo Valkonen + * Fixed quasiactivity (broken by recent placeholder changes). + Also implemented it on the Lua side in the same go, maintaining + the activation link structure being so much less pain than in C. + +2007-12-15 11:28 UTC Tuomo Valkonen + * Mention gettext in dependencies in README, etc. + +2007-12-14 20:27 UTC Tuomo Valkonen + * Added missing substrcompl option to mod_query. + +2007-12-14 20:08 UTC Tuomo Valkonen + * Simplify & comment + +2007-12-14 19:24 UTC Tuomo Valkonen + * Fixed and improved layout restore under session manager. + +2007-12-13 20:41 UTC Tuomo Valkonen + * More placeholder fixes/improvs/simplifications + +2007-12-12 21:51 UTC Tuomo Valkonen + * Doc. details + +2007-12-12 18:29 UTC Tuomo Valkonen + * Handle placeholders in the mplex rescue code + +2007-12-12 18:20 UTC Tuomo Valkonen + * Removed unused stdisp_watch_handler + +2007-12-12 18:00 UTC Tuomo Valkonen + * Removed deprecated pholder_root stuff + +2007-12-11 20:38 UTC Tuomo Valkonen + * Removed generic placeholder redirects + +2007-12-07 10:18 UTC Tuomo Valkonen + * Fixed shape update on style change + +2007-12-07 10:18 UTC Tuomo Valkonen + * Size hints weren't appropriately set when shading non-shaped frames. + +2007-12-02 20:17 UTC Tuomo Valkonen + * Better language + +2007-12-01 17:46 UTC Tuomo Valkonen + * More sophisticated pointer event hack. + Apparently the old one was needed, after all, for actions on transients. + So now we do like this: if the subwindow from the event listens to the + button/modifier combination in question at all, then we let it handle it, + blocking the parent. Otherwise the parent handles it. + + 2007-11-30 17:25 UTC Tuomo Valkonen tagged ion-3rc-20071130 +2007-11-29 19:48 UTC Tuomo Valkonen + UNDO: Removed pointer event subwindow forwarding hack. + Only useful use cases seem to be handled by not grabbing modifierless + bindings. This was stopping global (WScreen) grabs of buttons from + being handled if there was a frame in the way. (Note that modifierless + pointing device bindings are never grabbed, on purpose, so they still + don't work through frames or client windows.) + +2007-11-30 19:43 UTC Tuomo Valkonen + * Oops, tilings were resetting frame modes incorrectly. + (Copy-paste...) + 2007-11-30 17:24 UTC Tuomo Valkonen * Some release notes diff --git a/LICENSE b/LICENSE index f8e3c54..21d506e 100644 --- a/LICENSE +++ b/LICENSE @@ -33,7 +33,7 @@ reproduced below), extended and modified with the following terms: is to be understood to refer to the LGPL extended with these terms and, where applicable, possible similar terms related to the names of other works forming a whole. Sections 3 and 13 of the LGPL are void. Where - contradictory, these additional terms are primary to the LGPL. + contradictory, these additional terms take precedence over the LGPL. End of terms. @@ -53,24 +53,23 @@ trademark or other laws. copyright holder nor the Ion project: "Foo for Ion" instead of "Ion Foo", etc. -Significant change: Bug fixes are a priori insignificant as additions. -Basic changes that are needed to install or run the software on a target -platform are a priori insignificant. Additionally, basic configuration -changes to better integrate the software with the target platform, -without obstructing the standard behaviour, are a priori insignificant. -Everything else is significant. The copyright holder reserves the right -to refine the definition of significant changes on a per-case basis. -Please consult when in doubt. +Significant change: Bug fixes are insignificant as additions. Basic changes +that are needed to install or run the software on a target platform, are +insignificant. Additionally, basic/small configuration changes to better +integrate the software with the target platform, without obstructing the +standard behaviour, are insignificant. Everything else is significant, +unless expressly declared otherwise by the copyright holder. Distributions: For example, suppose an aggregate distribution of software provides an `installpkg` command for installing packages. Then the action -`installpkg ion3` (resp. `installpkg ion`) should after 28 days provide the -latest release of Ion3 (resp. the latest stable release), or prominently -notify the user that the provided version is (likely to be) obsolete and -unsupported. Specific versions (including modified versions) may be provided -if the user explicitly requests for those, within the constraints set above. -The latest release being provided by default, or prominently appearing in -a listing, constitutes prominent marking of earlier releases as obsolete. +`installpkg ion3` (resp. `installpkg ion`) should provide the latest release +of Ion3 (resp. the latest stable release) 28 days from release date at the +latest, or prominently notify the user that the provided version is (likely +to be) obsolete and unsupported. The latest release being provided by +default, or prominently appearing in a listing, constitutes prominent +marking of earlier releases as obsolete. Specific versions (including +modified versions) may be provided if the user explicitly requests for +those, within the constraints set above. The intent of these terms is to curb the power that "distributions", as the primary sources of software for many users, have in defining what diff --git a/Makefile b/Makefile index 6f7c06a..89562f8 100644 --- a/Makefile +++ b/Makefile @@ -34,3 +34,6 @@ _install: for i in $(DOCS); do \ $(INSTALL) -m $(DATA_MODE) $$i $(DOCDIR); \ done + +relocatable_build: + $(MAKE) RELOCATABLE=1 PREFIX= diff --git a/README b/README index 2d066b5..c588b95 100644 --- a/README +++ b/README @@ -12,10 +12,12 @@ tuomov at iki.fi Building and installing ----------------------- -1. Make sure you have the following tools and libraries installed: +1. Make sure you have the following tools and libraries installed (along + with, of course, standard X11 and libc stuff). - * GNU make - * Lua 5.1 (see ). + * GNU make + * Lua 5.1 + * gettext 2. Edit `system.mk` to suit your system. Most GNU/Linux users should need very few changes. diff --git a/RELNOTES b/RELNOTES index 56e8c55..97c57e6 100644 --- a/RELNOTES +++ b/RELNOTES @@ -1,4 +1,11 @@ +ion-3rc-20071220 +---------------- + +There are a few minor fixes in this RC, plus a major one related to +layout restore under a session manager. + + ion-3rc-20071130 ---------------- diff --git a/build/rules.mk b/build/rules.mk index b61e2f6..f4f18d1 100644 --- a/build/rules.mk +++ b/build/rules.mk @@ -2,6 +2,10 @@ ## Some make rules ## +ifdef RELOCATABLE +DEFINES += -DCF_RELOCATABLE +endif + ifdef MODULE ifeq ($(PRELOAD_MODULES),1) MODULE_TARGETS := $(MODULE).a $(MODULE).lc diff --git a/etc/cfg_ioncore.lua b/etc/cfg_ioncore.lua index a643e44..406cc1a 100644 --- a/etc/cfg_ioncore.lua +++ b/etc/cfg_ioncore.lua @@ -129,19 +129,9 @@ defbindings("WGroupCW", { defbindings("WMPlex", { bdoc("Close current object."), kpress_wait(META.."C", "WRegion.rqclose_propagate(_, _sub)"), - - submap(META.."K", { - bdoc("Detach (float) or reattach an object to its previous location."), - -- By using _chld instead of _sub, we can detach/reattach queries - -- attached to a group. The detach code checks if the parameter - -- (_chld) is a group 'bottom' and detaches the whole group in that - -- case. - kpress("D", "ioncore.detach(_chld, 'toggle')", "_chld:non-nil"), - }), }) -- Frames for transient windows ignore this bindmap - defbindings("WMPlex.toplevel", { bdoc("Toggle tag of current object."), kpress(META.."T", "WRegion.set_tagged(_sub, 'toggle')", "_sub:non-nil"), @@ -181,6 +171,15 @@ defbindings("WMPlex.toplevel", { bdoc("Display context menu."), --kpress(META.."M", "mod_menu.menu(_, _sub, 'ctxmenu')"), kpress(META.."M", "mod_query.query_menu(_, _sub, 'ctxmenu', 'Context menu:')"), + + submap(META.."K", { + bdoc("Detach (float) or reattach an object to its previous location."), + -- By using _chld instead of _sub, we can detach/reattach queries + -- attached to a group. The detach code checks if the parameter + -- (_chld) is a group 'bottom' and detaches the whole group in that + -- case. + kpress("D", "ioncore.detach(_chld, 'toggle')", "_chld:non-nil"), + }), }) diff --git a/etc/cfg_query.lua b/etc/cfg_query.lua index 6abc8a5..0b1d75a 100644 --- a/etc/cfg_query.lua +++ b/etc/cfg_query.lua @@ -117,5 +117,8 @@ mod_query.set{ -- Case-insensitive completion? (Some queries only.) caseicompl=true, + + -- Sub-string completion? (Some queries only.) + caseicompl=true, } --]] diff --git a/exact-version b/exact-version index 69a0964..61cbfd3 100644 --- a/exact-version +++ b/exact-version @@ -1,5 +1,5 @@ Context: -[TAG ion-3rc-20071130 -Tuomo Valkonen **20071130172504] +[TAG ion-3rc-20071220 +Tuomo Valkonen **20071220184549] diff --git a/ion/Makefile b/ion/Makefile index 823ab7f..1f1037e 100644 --- a/ion/Makefile +++ b/ion/Makefile @@ -40,7 +40,8 @@ EXT_OBJS += ../ioncore/ioncore.a DEFINES += -DETCDIR=\"$(ETCDIR)\" -DSHAREDIR=\"$(SHAREDIR)\" \ -DEXTRABINDIR=\"$(EXTRABINDIR)\" -DMODULEDIR=\"$(MODULEDIR)\" \ - -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" + -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" \ + -DION3_LOCATION=\"$(BINDIR)/ion3\" CFLAGS += $(XOPEN_SOURCE) $(C99_SOURCE) diff --git a/ion/ion.c b/ion/ion.c index 9dc0c93..23dce0c 100644 --- a/ion/ion.c +++ b/ion/ion.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -146,17 +147,27 @@ int main(int argc, char*argv[]) char *efnam=NULL; bool may_continue=FALSE; bool noerrorlog=FALSE; + char *localedir; libtu_init(argv[0]); - - if(!ioncore_init("ion3", argc, argv, LOCALEDIR)) + +#ifdef CF_RELOCATABLE + prefix_set(argv[0], ION3_LOCATION); +#endif + + localedir=prefix_add(LOCALEDIR); + + if(!ioncore_init("ion3", argc, argv, localedir)) return EXIT_FAILURE; + + if(localedir!=NULL) + free(localedir); - extl_add_searchdir(EXTRABINDIR); /* ion-completefile */ - extl_add_searchdir(MODULEDIR); - extl_add_searchdir(ETCDIR); - extl_add_searchdir(SHAREDIR); - extl_add_searchdir(LCDIR); + prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR); /* ion-completefile */ + prefix_wrap_simple(extl_add_searchdir, MODULEDIR); + prefix_wrap_simple(extl_add_searchdir, ETCDIR); + prefix_wrap_simple(extl_add_searchdir, SHAREDIR); + prefix_wrap_simple(extl_add_searchdir, LCDIR); extl_set_userdirs("ion3"); optparser_init(argc, argv, OPTP_MIDLONG, ion_opts); diff --git a/ioncore/Makefile b/ioncore/Makefile index ccf7c36..de7529d 100644 --- a/ioncore/Makefile +++ b/ioncore/Makefile @@ -23,13 +23,14 @@ SOURCES=binding.c conf-bindings.c cursor.c event.c exec.c focus.c \ kbresize.c rectangle.c xwindow.c presize.c extlrx.c \ pholder.c mplexpholder.c llist.c basicpholder.c sizepolicy.c \ stacking.c group.c grouppholder.c group-cw.c navi.c \ - group-ws.c float-placement.c groupedpholder.c framedpholder.c \ + group-ws.c float-placement.c framedpholder.c \ return.c detach.c screen-notify.c LUA_SOURCES=\ ioncore_ext.lua ioncore_luaext.lua ioncore_bindings.lua \ ioncore_winprops.lua ioncore_misc.lua ioncore_efbb.lua \ - ioncore_wd.lua ioncore_menudb.lua ioncore_tabnum.lua + ioncore_wd.lua ioncore_menudb.lua ioncore_tabnum.lua \ + ioncore_quasiact.lua ifeq ($(PRELOAD_MODULES),1) CFLAGS += -DCF_PRELOAD_MODULES diff --git a/ioncore/activity.c b/ioncore/activity.c index 25e2a5a..3eba697 100644 --- a/ioncore/activity.c +++ b/ioncore/activity.c @@ -122,7 +122,8 @@ bool region_is_activity_r(WRegion *reg) /*EXTL_DOC * Iterate over activity list until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE diff --git a/ioncore/attach.c b/ioncore/attach.c index 5d81222..52d0998 100644 --- a/ioncore/attach.c +++ b/ioncore/attach.c @@ -116,10 +116,14 @@ static WRegion *doit_reparent(WRegion *mgr, } -static WRegion *wrap_load(WWindow *par, const WFitParams *fp, - ExtlTab *tab) +typedef struct{ + ExtlTab tab; + WPHolder **sm_ph_p; +} WLP; + +static WRegion *wrap_load(WWindow *par, const WFitParams *fp, WLP *p) { - return create_region_load(par, fp, *tab); + return create_region_load(par, fp, p->tab, p->sm_ph_p); } @@ -129,11 +133,11 @@ WRegion *ioncore_newly_created=NULL; static WRegion *doit_load(WRegion *mgr, WWindow *par, const WFitParams *fp, WRegionDoAttachFn *cont, void *cont_param, - ExtlTab tab) + const WRegionAttachData *data) { WRegion *reg=NULL; - if(extl_table_gets_o(tab, "reg", (Obj**)®)){ + if(extl_table_gets_o(data->u.tab, "reg", (Obj**)®)){ if(!OBJ_IS(reg, WRegion)) return FALSE; }/*else if(extl_table_is_bool_set(tab, "reg_use_new")){ @@ -145,11 +149,30 @@ static WRegion *doit_load(WRegion *mgr, if(reg!=NULL){ return doit_reparent(mgr, par, fp, cont, cont_param, reg); }else{ + WLP p; + p.tab=data->u.tab; + p.sm_ph_p=NULL; + return doit_new(mgr, par, fp, cont, cont_param, - (WRegionCreateFn*)wrap_load, &tab); + (WRegionCreateFn*)wrap_load, &p); } } + +WRegion *region_attach_load_helper(WRegion *mgr, + WWindow *par, const WFitParams *fp, + WRegionDoAttachFn *fn, void *fn_param, + ExtlTab tab, WPHolder **sm_ph) +{ + WLP p; + p.tab=tab; + p.sm_ph_p=sm_ph; + + return doit_new(mgr, par, fp, fn, fn_param, + (WRegionCreateFn*)wrap_load, &p); +} + + WRegion *region_attach_helper(WRegion *mgr, WWindow *par, const WFitParams *fp, WRegionDoAttachFn *fn, void *fn_param, @@ -159,7 +182,7 @@ WRegion *region_attach_helper(WRegion *mgr, return doit_new(mgr, par, fp, fn, fn_param, data->u.n.fn, data->u.n.param); }else if(data->type==REGION_ATTACH_LOAD){ - return doit_load(mgr, par, fp, fn, fn_param, data->u.tab); + return doit_load(mgr, par, fp, fn, fn_param, data); }else if(data->type==REGION_ATTACH_REPARENT){ return doit_reparent(mgr, par, fp, fn, fn_param, data->u.reg); }else{ diff --git a/ioncore/attach.h b/ioncore/attach.h index ec518ae..ca144fe 100644 --- a/ioncore/attach.h +++ b/ioncore/attach.h @@ -51,6 +51,11 @@ extern WRegion *region_attach_helper(WRegion *mgr, WRegionDoAttachFn *fn, void *fn_param, const WRegionAttachData *data); +extern WRegion *region_attach_load_helper(WRegion *mgr, + WWindow *par, const WFitParams *fp, + WRegionDoAttachFn *fn, void *fn_param, + ExtlTab tab, WPHolder **sm_ph); + extern bool region_ancestor_check(WRegion *dst, WRegion *reg); extern void region_postdetach_dispose(WRegion *reg, WRegion *disposeroot); diff --git a/ioncore/basicpholder.c b/ioncore/basicpholder.c index 77e863d..f452781 100644 --- a/ioncore/basicpholder.c +++ b/ioncore/basicpholder.c @@ -16,13 +16,6 @@ /*{{{ Init/deinit */ -static void basicpholder_watch_handler(Watch *watch, Obj *reg) -{ - WBasicPHolder *ph=FIELD_TO_STRUCT(WBasicPHolder, reg_watch, watch); - pholder_redirect(&(ph->ph), (WRegion*)reg); -} - - bool basicpholder_init(WBasicPHolder *ph, WRegion *reg, WBasicPHolderHandler *hnd) { @@ -32,7 +25,7 @@ bool basicpholder_init(WBasicPHolder *ph, WRegion *reg, watch_init(&(ph->reg_watch)); - if(!watch_setup(&(ph->reg_watch), (Obj*)reg, basicpholder_watch_handler)){ + if(!watch_setup(&(ph->reg_watch), (Obj*)reg, NULL)){ pholder_deinit(&(ph->ph)); return FALSE; } diff --git a/ioncore/binding.c b/ioncore/binding.c index 740e67b..cad47d3 100644 --- a/ioncore/binding.c +++ b/ioncore/binding.c @@ -381,7 +381,7 @@ void binding_grab_on(const WBinding *binding, Window win) binding->act!=BINDING_BUTTONMOTION) return; - if(binding->state==0) + if(binding->state==0 || binding->area!=0) return; #ifndef CF_HACK_IGNORE_EVIL_LOCKS @@ -412,7 +412,7 @@ void binding_ungrab_on(const WBinding *binding, Window win) binding->act!=BINDING_BUTTONMOTION) return; - if(binding->state==0) + if(binding->state==0 || binding->area!=0) return; #ifndef CF_HACK_IGNORE_EVIL_LOCKS diff --git a/ioncore/classes.h b/ioncore/classes.h index b1bce1b..58698a7 100644 --- a/ioncore/classes.h +++ b/ioncore/classes.h @@ -31,6 +31,8 @@ INTRCLASS(WGroupWS); INTRCLASS(WPHolder); INTRCLASS(WMPlexPHolder); INTRCLASS(WFramedPHolder); +INTRCLASS(WGroupPHolder); +INTRCLASS(WGroupedPHolder); INTRSTRUCT(WStacking); INTRSTRUCT(WLListNode); diff --git a/ioncore/clientwin.c b/ioncore/clientwin.c index 7c3880e..1b85dfc 100644 --- a/ioncore/clientwin.c +++ b/ioncore/clientwin.c @@ -1319,6 +1319,25 @@ static ExtlTab clientwin_get_configuration(WClientWin *cwin) } +static void do_sm(ExtlTab tab) +{ + SMAddCallback *add_cb; + SMCfgCallback *cfg_cb; + WPHolder *ph; + + ioncore_get_sm_callbacks(&add_cb, &cfg_cb); + + if(add_cb!=NULL){ + ph=ioncore_get_load_pholder(); + + if(ph!=NULL){ + if(!add_cb(ph, tab)) + destroy_obj((Obj*)ph); + } + } +} + + WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab) { double wind=0; @@ -1345,7 +1364,7 @@ WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab) &real_chkc); if(!got_chkc || real_chkc!=chkc){ - ioncore_clientwin_load_missing(); + do_sm(tab); return NULL; } @@ -1356,6 +1375,9 @@ WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab) return NULL; } + if(attr.root!=region_root_of((WRegion*)par)) + return NULL; + if(attr.override_redirect || (ioncore_g.opmode==IONCORE_OPMODE_INIT && attr.map_state!=IsViewable)){ warn(TR("Saved client window does not want to be managed.")); diff --git a/ioncore/detach.c b/ioncore/detach.c index 21997ec..8a86640 100644 --- a/ioncore/detach.c +++ b/ioncore/detach.c @@ -87,10 +87,13 @@ static bool ioncore_do_detach(WRegion *reg, WGroup *grp, WFrameMode framemode, ap.szplcy=st->szplcy; ap.szplcy_set=TRUE; - ap.level_set=TRUE; - ap.level=maxof(st->level, STACKING_LEVEL_NORMAL); + /*ap.level_set=TRUE; + ap.level=maxof(st->level, STACKING_LEVEL_NORMAL);*/ } + ap.level_set=TRUE; + ap.level=framelevel+1; + ap.geom_set=TRUE; get_relative_geom(&ap.geom, reg, (WRegion*)grp); diff --git a/ioncore/focus.c b/ioncore/focus.c index 573dceb..baada3e 100644 --- a/ioncore/focus.c +++ b/ioncore/focus.c @@ -101,7 +101,8 @@ WRegion *ioncore_goto_previous() /*EXTL_DOC * Iterate over focus history until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_EXPORT @@ -300,9 +301,10 @@ void region_lost_focus(WRegion *reg) */ EXTL_SAFE EXTL_EXPORT_MEMBER -bool region_is_active(WRegion *reg) +bool region_is_active(WRegion *reg, bool pseudoact_ok) { - return REGION_IS_ACTIVE(reg); + return (REGION_IS_ACTIVE(reg) || + (pseudoact_ok && REGION_IS_PSEUDOACTIVE(reg))); } diff --git a/ioncore/focus.h b/ioncore/focus.h index 9f16415..fe0b120 100644 --- a/ioncore/focus.h +++ b/ioncore/focus.h @@ -41,7 +41,7 @@ extern void region_lost_focus(WRegion *reg); extern bool region_may_control_focus(WRegion *reg); /* Does reg have focus? */ -extern bool region_is_active(WRegion *reg); +extern bool region_is_active(WRegion *reg, bool pseudoact_ok); /* Focus history */ extern void region_focuslist_remove_with_mgrs(WRegion *reg); diff --git a/ioncore/frame-draw.c b/ioncore/frame-draw.c index 925a858..8591f2a 100644 --- a/ioncore/frame-draw.c +++ b/ioncore/frame-draw.c @@ -42,8 +42,6 @@ GR_DEFATTR(dragged); GR_DEFATTR(not_dragged); GR_DEFATTR(activity); GR_DEFATTR(no_activity); -GR_DEFATTR(quasiactive); -GR_DEFATTR(not_quasiactive); static void ensure_create_attrs() @@ -59,8 +57,6 @@ static void ensure_create_attrs() GR_ALLOCATTR(not_dragged); GR_ALLOCATTR(no_activity); GR_ALLOCATTR(activity); - GR_ALLOCATTR(quasiactive); - GR_ALLOCATTR(not_quasiactive); GR_ALLOCATTR_END; } @@ -187,6 +183,22 @@ void frame_managed_geom(const WFrame *frame, WRectangle *geom) } +int frame_shaded_height(const WFrame *frame) +{ + if(frame->barmode==FRAME_BAR_NONE){ + return 0; + }else if(!BAR_INSIDE_BORDER(frame)){ + return frame->bar_h; + }else { + GrBorderWidths bdw; + + grbrush_get_border_widths(frame->brush, &bdw); + + return frame->bar_h+bdw.top+bdw.bottom; + } +} + + void frame_set_shape(WFrame *frame) { WRectangle gs[2]; @@ -302,6 +314,8 @@ void frame_recalc_bar(WFrame *frame, bool complete) if(frame->barmode==FRAME_BAR_SHAPED) frame_shaped_recalc_bar_size(frame, complete); + else if(complete) + frame_clear_shape(frame); i=0; @@ -576,21 +590,5 @@ void frame_activated(WFrame *frame) } -void frame_quasiactivity_change(WFrame *frame) -{ - bool is=(frame->quasiact_source!=NULL); - - ensure_create_attrs(); - - if(is){ - gr_stylespec_set(&frame->baseattr, GR_ATTR(quasiactive)); - gr_stylespec_unset(&frame->baseattr, GR_ATTR(not_quasiactive)); - }else{ - gr_stylespec_set(&frame->baseattr, GR_ATTR(not_quasiactive)); - gr_stylespec_unset(&frame->baseattr, GR_ATTR(quasiactive)); - } -} - - /*}}}*/ diff --git a/ioncore/frame-draw.h b/ioncore/frame-draw.h index 5654389..0acc21d 100644 --- a/ioncore/frame-draw.h +++ b/ioncore/frame-draw.h @@ -20,6 +20,7 @@ extern void frame_border_geom(const WFrame *frame, WRectangle *geom); extern void frame_border_inner_geom(const WFrame *frame, WRectangle *geom); extern void frame_brushes_updated(WFrame *frame); extern void frame_managed_geom(const WFrame *frame, WRectangle *geom); +extern int frame_shaded_height(const WFrame *frame); extern void frame_initialise_gr(WFrame *frame); extern void frame_release_brushes(WFrame *frame); @@ -38,6 +39,5 @@ extern void frame_setup_dragwin_style(WFrame *frame, GrStyleSpec *spec, int tab) extern void frame_inactivated(WFrame *frame); extern void frame_activated(WFrame *frame); -extern void frame_quasiactivity_change(WFrame *frame); #endif /* ION_IONCORE_FRAME_DRAW_H */ diff --git a/ioncore/frame.c b/ioncore/frame.c index f85a296..ee666bc 100644 --- a/ioncore/frame.c +++ b/ioncore/frame.c @@ -102,7 +102,6 @@ bool frame_init(WFrame *frame, WWindow *parent, const WFitParams *fp, frame->mode=mode; frame->tab_min_w=0; frame->bar_max_width_q=1.0; - frame->quasiact_source=NULL; gr_stylespec_init(&frame->baseattr); @@ -185,14 +184,10 @@ void frame_set_mode(WFrame *frame, WFrameMode mode) region_remove_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap); frame->mode=mode; - - frame_add_mode_bindmaps(frame); - frame_initialise_gr(frame); + frame_add_mode_bindmaps(frame); - mplex_fit_managed(&frame->mplex); - frame_recalc_bar(frame, TRUE); - frame_set_background(frame, TRUE); + frame_updategr(frame); } @@ -432,7 +427,8 @@ bool frame_fitrep(WFrame *frame, WWindow *par, const WFitParams *fp) old_geom=REGION_GEOM(frame); - window_do_fitrep(&(frame->mplex.win), par, &(fp->g)); + if(!window_fitrep(&(frame->mplex.win), par, fp)) + return FALSE; mplex_managed_geom((WMPlex*)frame, &mg); @@ -516,13 +512,14 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret) hints_ret->min_width+=woff; hints_ret->min_height+=hoff; - if(frame->barmode==FRAME_BAR_SHAPED){ + /* shaded */ { int f=frame->flags&(FRAME_SHADED|FRAME_SHADED_TOGGLE); if(f==FRAME_SHADED || f==FRAME_SHADED_TOGGLE){ - hints_ret->min_height=frame->bar_h; - hints_ret->max_height=frame->bar_h; - hints_ret->base_height=frame->bar_h; + int h=frame_shaded_height(frame); + hints_ret->min_height=h; + hints_ret->max_height=h; + hints_ret->base_height=h; if(!hints_ret->max_set){ hints_ret->max_width=INT_MAX; hints_ret->max_set=TRUE; @@ -535,97 +532,6 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret) /*}}}*/ -/*{{{ Focus */ - - -static void frame_quasiactivation(WFrame *frame, Obj *src, bool act) -{ - if(frame->quasiact_source==src || act){ - bool was, is; - - was=(frame->quasiact_source!=NULL); - - frame->quasiact_source=(act ? src : NULL); - - is=(frame->quasiact_source!=NULL); - - if(was!=is){ - frame_quasiactivity_change(frame); - if(!REGION_IS_ACTIVE(frame)) - window_draw((WWindow*)frame, FALSE); - } - } -} - - -static bool actinact(WRegion *reg, bool act) -{ - WPHolder *returnph=region_get_return(reg); - WFrame *frame=NULL; - Obj *src=NULL; - WRegion *tgt; - - if(returnph==NULL || pholder_stale(returnph)) - return FALSE; - - tgt=pholder_target(returnph); - - frame=OBJ_CAST(tgt, WFrame); - - if(frame!=NULL){ - src=(Obj*)returnph; - }else{ - /* Show quasiactivation for stuff detached from - * groups contained in the frame as well. - */ - WGroup *grp=OBJ_CAST(tgt, WGroup); - if(grp!=NULL){ - frame=REGION_MANAGER_CHK(grp, WFrame); - src=(Obj*)grp; - } - } - - if(frame!=NULL) - frame_quasiactivation(frame, src, act); - - return TRUE; -} - - -static bool activated(WRegion *reg) -{ - return actinact(reg, TRUE); -} - - -static bool inactivated(WRegion *reg) -{ - return actinact(reg, FALSE); -} - - -void ioncore_frame_quasiactivation_notify(WRegion *reg, - WRegionNotify how) -{ - if(how==ioncore_g.notifies.activated || - how==ioncore_g.notifies.pseudoactivated){ - activated(reg); - }else if(how==ioncore_g.notifies.inactivated || - how==ioncore_g.notifies.pseudoinactivated){ - inactivated(reg); - }else if(how==ioncore_g.notifies.set_return){ - if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg)) - activated(reg); - }else if(how==ioncore_g.notifies.unset_return){ - if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg)) - inactivated(reg); - } -} - - -/*}}}*/ - - /*{{{ Client window rqgeom */ @@ -695,75 +601,78 @@ static void frame_managed_rqgeom_absolute(WFrame *frame, WRegion *sub, /*{{{ Frame recreate pholder stuff */ -static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame) +static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame, WPHolder *rph) { - WPHolder *ph; - WFramedPHolder *fph; WFramedParam fparam=FRAMEDPARAM_INIT; + WFramedPHolder *fph=NULL; - ph=region_make_return_pholder((WRegion*)frame); - - if(ph==NULL){ - return NULL; - } - - fparam.mode=frame->mode; + if(rph!=NULL){ + fparam.mode=frame->mode; - fph=create_framedpholder(ph, &fparam); + fph=create_framedpholder(rph, &fparam); - if(fph==NULL){ - destroy_obj((Obj*)ph); - return NULL; + if(fph==NULL) + destroy_obj((Obj*)rph); } return fph; } -static void mplex_flatten_phs(WMPlex *mplex) +static void mplex_migrate_phs_to_fph(WMPlex *mplex, WFramedPHolder *fph) { - WLListNode *node; - WLListIterTmp tmp; - - FOR_ALL_NODES_ON_LLIST(node, mplex->mx_list, tmp){ - WMPlexPHolder *last=(mplex->mx_phs==NULL ? NULL : mplex->mx_phs->prev); - mplex_move_phs(mplex, node, last, NULL); - } -} - - -static void frame_modify_pholders(WFrame *frame) -{ - WFramedPHolder *fph; WMPlexPHolder *phs, *ph; - mplex_flatten_phs(&frame->mplex); - - if(frame->mplex.mx_phs==NULL) - return; - - fph=frame_make_recreate_pholder(frame); - - if(fph==NULL) - return; - - phs=frame->mplex.mx_phs; - frame->mplex.mx_phs=NULL; + phs=mplex->misc_phs; + mplex->misc_phs=NULL; phs->recreate_pholder=fph; for(ph=phs; ph!=NULL; ph=ph->next) - watch_reset(&ph->mplex_watch); + ph->mplex=NULL; } + bool frame_rescue_clientwins(WFrame *frame, WRescueInfo *info) { - frame_modify_pholders(frame); - return mplex_rescue_clientwins(&frame->mplex, info); + bool ret; + + ret=mplex_rescue_clientwins(&frame->mplex, info); + + /* Now, do placeholders. + * We can't currently be arsed to keep them ordered with regions... + * First we check if we can simply recreate this frame, which takes + * care of e.g. floating frames being destroyed when entering full + * screen mode. If not, we check if the target would be a WMPlex, and + * migrate there. This takes care of frames destroyed in tilings. + */ + mplex_flatten_phs(&frame->mplex); + + if(frame->mplex.misc_phs!=NULL){ + WPHolder *ret_ph=region_make_return_pholder((WRegion*)frame); + WFramedPHolder *fph=frame_make_recreate_pholder(frame, ret_ph); + + if(fph!=NULL){ + mplex_migrate_phs_to_fph(&frame->mplex, fph); + }else{ + WPHolder *rescueph=rescueinfo_pholder(info); + if(rescueph!=NULL){ + WRegion *target=pholder_target(rescueph); + WMPlex *other_mplex=OBJ_CAST(target, WMPlex); + + if(other_mplex!=NULL){ + assert(other_mplex!=&frame->mplex); + mplex_migrate_phs(&frame->mplex, other_mplex); + } + } + } + } + + return ret; } - + /*}}}*/ @@ -789,17 +698,9 @@ bool frame_set_shaded(WFrame *frame, int sp) return FALSE; rq.geom.h=frame->saved_h; }else{ - if(frame->barmode==FRAME_BAR_NONE){ + if(frame->barmode==FRAME_BAR_NONE) return FALSE; - }else if(frame->barmode==FRAME_BAR_SHAPED){ - rq.geom.h=frame->bar_h; - }else{ - WRectangle tmp; - - frame_border_inner_geom(frame, &tmp); - - rq.geom.h=rq.geom.h-tmp.h; - } + rq.geom.h=frame_shaded_height(frame); } frame->flags|=FRAME_SHADED_TOGGLE; @@ -920,14 +821,6 @@ static void frame_managed_changed(WFrame *frame, int mode, bool sw, { bool need_draw=TRUE; - if(mode==MPLEX_CHANGE_REMOVE && (Obj*)reg==frame->quasiact_source){ - /* Reset indirect quasiactivation through group that - * is being removed. - */ - frame->quasiact_source=NULL; - frame_quasiactivity_change(frame); - } - if(mode!=MPLEX_CHANGE_SWITCHONLY) frame_initialise_titles(frame); else @@ -1054,6 +947,14 @@ WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab) frame_do_load(frame, tab); if(DEST_EMPTY(frame) && frame->mplex.mgd==NULL){ + if(frame->mplex.misc_phs!=NULL){ + /* Session management hack */ + WFramedPHolder *fph; + fph=frame_make_recreate_pholder(frame, ioncore_get_load_pholder()); + if(fph!=NULL) + mplex_migrate_phs_to_fph(&frame->mplex, fph); + } + destroy_obj((Obj*)frame); return NULL; } diff --git a/ioncore/frame.h b/ioncore/frame.h index 44cc7bf..7d5da74 100644 --- a/ioncore/frame.h +++ b/ioncore/frame.h @@ -119,15 +119,11 @@ extern int frame_default_index(WFrame *frame); extern void frame_managed_notify(WFrame *frame, WRegion *sub, WRegionNotify how); extern bool frame_managed_rqdispose(WFrame *frame, WRegion *reg); -extern void ioncore_frame_quasiactivation_notify(WRegion *reg, WRegionNotify how); - extern WPHolder *frame_prepare_manage_transient(WFrame *frame, const WClientWin *transient, const WManageParams *param, int unused); -extern bool frame_rescue_clientwins(WFrame *frame, WRescueInfo *info); - /* Save/load */ extern ExtlTab frame_get_configuration(WFrame *frame); extern WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab); diff --git a/ioncore/framedpholder.c b/ioncore/framedpholder.c index de437a2..a2cd2c5 100644 --- a/ioncore/framedpholder.c +++ b/ioncore/framedpholder.c @@ -28,6 +28,8 @@ bool framedpholder_init(WFramedPHolder *ph, WPHolder *cont, ph->cont=cont; ph->param=*param; + watch_init(&ph->frame_watch); + return TRUE; } @@ -47,6 +49,7 @@ void framedpholder_deinit(WFramedPHolder *ph) } pholder_deinit(&(ph->ph)); + watch_reset(&ph->frame_watch); } @@ -59,6 +62,7 @@ void framedpholder_deinit(WFramedPHolder *ph) typedef struct{ WRegionAttachData *data; WFramedParam *param; + WRegion *reg_ret; } AP; @@ -119,6 +123,8 @@ WRegion *framed_handler(WWindow *par, reg=mplex_do_attach(&frame->mplex, &mp, ap->data); + ap->reg_ret=reg; + if(reg==NULL){ destroy_obj((Obj*)frame); return NULL; @@ -143,6 +149,7 @@ WRegion *region_attach_framed(WRegion *reg, WFramedParam *param, ap.data=data; ap.param=param; + ap.reg_ret=NULL; return fn(reg, fn_param, &data2); } @@ -152,8 +159,16 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags, WRegionAttachData *data) { WRegionAttachData data2; + WFrame *frame; AP ap; + frame=(WFrame*)ph->frame_watch.obj; + + if(frame!=NULL){ + WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT; + return mplex_do_attach(&frame->mplex, &mp, data); + } + if(ph->cont==NULL) return FALSE; @@ -163,8 +178,16 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags, ap.data=data; ap.param=&ph->param; + ap.reg_ret=NULL; - return pholder_do_attach(ph->cont, flags, &data2); + frame=(WFrame*)pholder_do_attach(ph->cont, flags, &data2); + + if(frame!=NULL){ + assert(OBJ_IS(frame, WFrame)); + watch_setup(&ph->frame_watch, (Obj*)frame, NULL); + } + + return ap.reg_ret; } @@ -176,32 +199,34 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags, bool framedpholder_do_goto(WFramedPHolder *ph) { - return (ph->cont!=NULL - ? pholder_goto(ph->cont) - : FALSE); + WRegion *frame=(WRegion*)ph->frame_watch.obj; + + if(frame!=NULL) + return region_goto((WRegion*)frame); + else if(ph->cont!=NULL) + return pholder_goto(ph->cont); + else + return FALSE; } WRegion *framedpholder_do_target(WFramedPHolder *ph) { - return (ph->cont!=NULL - ? pholder_target(ph->cont) - : NULL); + WRegion *frame=(WRegion*)ph->frame_watch.obj; + + return (frame!=NULL + ? frame + : (ph->cont!=NULL + ? pholder_target(ph->cont) + : NULL)); } -WPHolder *framedpholder_do_root(WFramedPHolder *ph) +bool framedpholder_stale(WFramedPHolder *ph) { - WPHolder *root; - - if(ph->cont==NULL) - return NULL; - - root=pholder_root(ph->cont); + WRegion *frame=(WRegion*)ph->frame_watch.obj; - return (root!=ph->cont - ? root - : &ph->ph); + return (frame==NULL && (ph->cont==NULL || pholder_stale(ph->cont))); } @@ -221,8 +246,8 @@ static DynFunTab framedpholder_dynfuntab[]={ {(DynFun*)pholder_do_target, (DynFun*)framedpholder_do_target}, - {(DynFun*)pholder_do_root, - (DynFun*)framedpholder_do_root}, + {(DynFun*)pholder_stale, + (DynFun*)framedpholder_stale}, END_DYNFUNTAB }; diff --git a/ioncore/framedpholder.h b/ioncore/framedpholder.h index 49becc2..43032b7 100644 --- a/ioncore/framedpholder.h +++ b/ioncore/framedpholder.h @@ -32,6 +32,7 @@ DECLCLASS(WFramedPHolder){ WPHolder ph; WPHolder *cont; WFramedParam param; + Watch frame_watch; }; @@ -45,7 +46,7 @@ extern void framedpholder_deinit(WFramedPHolder *ph); extern bool framedpholder_do_goto(WFramedPHolder *ph); -extern WPHolder *framedpholder_do_root(WFramedPHolder *ph); +extern bool framedpholder_stale(WFramedPHolder *ph); extern WRegion *framedpholder_do_target(WFramedPHolder *ph); diff --git a/ioncore/group-cw.c b/ioncore/group-cw.c index 6bb9c2f..d5b7396 100644 --- a/ioncore/group-cw.c +++ b/ioncore/group-cw.c @@ -22,6 +22,8 @@ #include "names.h" #include "framedpholder.h" #include "grouppholder.h" +#include "return.h" +#include "saveload.h" #define DFLT_SZPLCY SIZEPOLICY_FREE_GLUE__SOUTH @@ -209,6 +211,46 @@ void groupcw_bottom_set(WGroupCW *cwg) /*}}}*/ +/*{{{ Rescue */ + + +static void group_migrate_phs_to_ph(WGroup *group, WPHolder *rph) +{ + WGroupPHolder *phs, *ph; + + phs=group->phs; + group->phs=NULL; + + phs->recreate_pholder=rph; + + for(ph=phs; ph!=NULL; ph=ph->next) + ph->group=NULL; +} + + +bool groupcw_rescue_clientwins(WGroupCW *cwg, WRescueInfo *info) +{ + bool ret=group_rescue_clientwins(&cwg->grp, info); + + /* If this group can be recreated, arrange remaining placeholders + * to do so. This takes care of e.g. recreating client window groups + * when recreating layout delayedly under a session manager. + */ + if(cwg->grp.phs!=NULL){ + WPHolder *rph=region_make_return_pholder((WRegion*)cwg); + + if(rph!=NULL) + group_migrate_phs_to_ph(&cwg->grp, rph); + } + + return ret; +} + + +/*}}}*/ + + + /*{{{ WGroupCW class */ @@ -239,34 +281,29 @@ void groupcw_deinit(WGroupCW *cwg) WRegion *groupcw_load(WWindow *par, const WFitParams *fp, ExtlTab tab) { - WGroupCW *ws; + WGroupCW *cwg; ExtlTab substab, subtab; int i, n; - ws=create_groupcw(par, fp); + cwg=create_groupcw(par, fp); - if(ws==NULL) + if(cwg==NULL) return NULL; - - if(!extl_table_gets_t(tab, "managed", &substab)) - return (WRegion*)ws; - - n=extl_table_get_n(substab); - for(i=1; i<=n; i++){ - if(extl_table_geti_t(substab, i, &subtab)){ - group_attach_new(&ws->grp, subtab); - extl_unref_table(subtab); - } - } - - extl_unref_table(substab); + + group_do_load(&cwg->grp, tab); - if(ws->grp.managed_list==NULL){ - destroy_obj((Obj*)ws); + if(cwg->grp.managed_list==NULL){ + if(cwg->grp.phs!=NULL){ + /* Session management hack */ + WPHolder *ph=ioncore_get_load_pholder(); + if(ph!=NULL) + group_migrate_phs_to_ph(&cwg->grp, ph); + } + destroy_obj((Obj*)cwg); return NULL; } - return (WRegion*)ws; + return (WRegion*)cwg; } @@ -307,6 +344,9 @@ static DynFunTab groupcw_dynfuntab[]={ {group_bottom_set, groupcw_bottom_set}, + + {(DynFun*)region_rescue_clientwins, + (DynFun*)groupcw_rescue_clientwins}, END_DYNFUNTAB }; diff --git a/ioncore/group-ws.c b/ioncore/group-ws.c index 3fd8cb7..c12d8ec 100644 --- a/ioncore/group-ws.c +++ b/ioncore/group-ws.c @@ -22,7 +22,6 @@ #include "group-ws.h" #include "group-cw.h" #include "grouppholder.h" -#include "groupedpholder.h" #include "framedpholder.h" #include "float-placement.h" #include "resize.h" @@ -171,8 +170,21 @@ static WPHolder *groupws_do_prepare_manage(WGroupWS *ws, if(ph!=NULL) ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph); - if(ph!=NULL) - ph=pholder_either((WPHolder*)create_groupedpholder((WPHolder*)ph), ph); + if(ph!=NULL){ + WGroupPHolder *gph; + WGroupAttachParams gp=GROUPATTACHPARAMS_INIT; + + gp.switchto_set=1; + gp.switchto=1; + gp.bottom=1; + + gph=create_grouppholder(NULL, NULL, &gp); + + if(gph!=NULL){ + gph->recreate_pholder=ph; + return (WPHolder*)gph; + } + } return ph; } @@ -256,27 +268,6 @@ WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin, } -WPHolder *groupws_get_rescue_pholder_for(WGroupWS *ws, - WRegion *forwhat) -{ - WGroupAttachParams ap=GROUPATTACHPARAMS_INIT; - WFramedParam fp=FRAMEDPARAM_INIT; - WPHolder *ph; - - ap.geom_set=TRUE; - ap.geom=REGION_GEOM(forwhat); - - ap.geom_weak_set=1; - ap.geom_weak=(REGION_PARENT(forwhat)!=REGION_PARENT(ws) - ? REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y - : 0); - - ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap); - - return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph); -} - - static bool group_empty_for_bottom_stdisp(WGroup *ws) { WGroupIterTmp tmp; @@ -364,9 +355,6 @@ static DynFunTab groupws_dynfuntab[]={ {(DynFun*)region_handle_drop, (DynFun*)groupws_handle_drop}, - {(DynFun*)region_get_rescue_pholder_for, - (DynFun*)groupws_get_rescue_pholder_for}, - {region_manage_stdisp, group_manage_stdisp}, diff --git a/ioncore/group.c b/ioncore/group.c index 5cff1d0..886913f 100644 --- a/ioncore/group.c +++ b/ioncore/group.c @@ -356,6 +356,7 @@ bool group_init(WGroup *ws, WWindow *par, const WFitParams *fp) ws->managed_stdisp=NULL; ws->bottom=NULL; ws->managed_list=NULL; + ws->phs=NULL; ws->dummywin=XCreateWindow(ioncore_g.dpy, par->win, fp->g.x, fp->g.y, 1, 1, 0, @@ -406,12 +407,14 @@ void group_deinit(WGroup *ws) XDeleteContext(ioncore_g.dpy, ws->dummywin, ioncore_g.win_context); XDestroyWindow(ioncore_g.dpy, ws->dummywin); ws->dummywin=None; - + + while(ws->phs!=NULL) + grouppholder_do_unlink(ws->phs); + region_deinit(&ws->reg); } - bool group_rescue_clientwins(WGroup *ws, WRescueInfo *info) { WGroupIterTmp tmp; @@ -424,6 +427,39 @@ bool group_rescue_clientwins(WGroup *ws, WRescueInfo *info) } +WPHolder *group_get_rescue_pholder_for(WGroup *ws, + WRegion *forwhat) +{ + WGroupAttachParams ap=GROUPATTACHPARAMS_INIT; + WFramedParam fp=FRAMEDPARAM_INIT; + WPHolder *ph; + + ap.geom_set=TRUE; + ap.geom=REGION_GEOM(forwhat); + + ap.geom_weak_set=1; + + if(REGION_PARENT(forwhat)==REGION_PARENT(ws)){ + ap.geom.x-=REGION_GEOM(ws).x; + ap.geom.y-=REGION_GEOM(ws).y; + }else{ + ap.geom_weak=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y; + } + + /* frame mode */ + /*{ + WFrame *frame=OBJ_CAST(forwhat, WFrame); + if(frame!=NULL) + fp.mode=frame->mode; + }*/ + + ph=(WPHolder*)create_grouppholder(ws, NULL, &ap); + + return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph); +} + + + /*}}}*/ @@ -669,12 +705,24 @@ bool group_do_attach_final(WGroup *ws, } +static void group_attach_fp(WGroup *ws, const WGroupAttachParams *param, + WFitParams *fp) +{ + if(param->geom_set){ + geom_group_to_parent(ws, ¶m->geom, &fp->g); + fp->mode=REGION_FIT_EXACT; + }else{ + fp->g=REGION_GEOM(ws); + fp->mode=REGION_FIT_BOUNDS|REGION_FIT_WHATEVER; + } +} + + WRegion *group_do_attach(WGroup *ws, /*const*/ WGroupAttachParams *param, WRegionAttachData *data) { WFitParams fp; - WWindow *par; WRegion *reg; if(ws->bottom!=NULL && param->bottom){ @@ -682,18 +730,9 @@ WRegion *group_do_attach(WGroup *ws, return NULL; } - par=REGION_PARENT(ws); - assert(par!=NULL); - - if(param->geom_set){ - geom_group_to_parent(ws, ¶m->geom, &fp.g); - fp.mode=REGION_FIT_EXACT; - }else{ - fp.g=REGION_GEOM(ws); - fp.mode=REGION_FIT_BOUNDS|REGION_FIT_WHATEVER; - } + group_attach_fp(ws, param, &fp); - return region_attach_helper((WRegion*) ws, par, &fp, + return region_attach_helper((WRegion*) ws, REGION_PARENT(ws), &fp, (WRegionDoAttachFn*)group_do_attach_final, /*(const WRegionAttachParams*)*/param, data); /* ^^^^ doesn't seem to work. */ @@ -1175,7 +1214,8 @@ bool group_managed_rqorder(WGroup *grp, WRegion *reg, WRegionOrder order) /*EXTL_DOC * Iterate over managed regions of \var{ws} until \var{iterfn} returns * \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE @@ -1295,7 +1335,7 @@ static ExtlTab group_get_configuration(WGroup *ws) return tab; } - + void group_do_load(WGroup *ws, ExtlTab tab) { ExtlTab substab, subtab; @@ -1305,7 +1345,23 @@ void group_do_load(WGroup *ws, ExtlTab tab) n=extl_table_get_n(substab); for(i=1; i<=n; i++){ if(extl_table_geti_t(substab, i, &subtab)){ - group_attach_new(ws, subtab); + WGroupAttachParams par=GROUPATTACHPARAMS_INIT; + WRegionAttachData data; + WFitParams fp; + WPHolder *ph; + + group_get_attach_params(ws, subtab, &par); + group_attach_fp(ws, &par, &fp); + + ph=(WPHolder*)create_grouppholder(ws, NULL, &par); + + region_attach_load_helper((WRegion*)ws, REGION_PARENT(ws), &fp, + (WRegionDoAttachFn*)group_do_attach_final, + (void*)&par, subtab, &ph); + + if(ph!=NULL) + destroy_obj((Obj*)ph); + extl_unref_table(subtab); } } @@ -1399,6 +1455,9 @@ static DynFunTab group_dynfuntab[]={ {(DynFun*)region_managed_rqorder, (DynFun*)group_managed_rqorder}, + + {(DynFun*)region_get_rescue_pholder_for, + (DynFun*)group_get_rescue_pholder_for}, END_DYNFUNTAB }; diff --git a/ioncore/group.h b/ioncore/group.h index 1966ba2..d09ba9f 100644 --- a/ioncore/group.h +++ b/ioncore/group.h @@ -17,7 +17,6 @@ #include #include #include -#include INTRSTRUCT(WGroupAttachParams); @@ -54,6 +53,7 @@ DECLCLASS(WGroup){ WStacking *current_managed; WStacking *bottom; Window dummywin; + WGroupPHolder *phs; }; diff --git a/ioncore/groupedpholder.c b/ioncore/groupedpholder.c deleted file mode 100644 index cce1a16..0000000 --- a/ioncore/groupedpholder.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * ion/ioncore/groupedpholder.c - * - * Copyright (c) Tuomo Valkonen 2005-2007. - * - * See the included file LICENSE for details. - */ - -#include -#include - -#include "group.h" -#include "group-cw.h" -#include "groupedpholder.h" - - -/*{{{ Init/deinit */ - - -bool groupedpholder_init(WGroupedPHolder *ph, WPHolder *cont) -{ - assert(cont!=NULL); - - pholder_init(&(ph->ph)); - - ph->cont=cont; - - return TRUE; -} - - -WGroupedPHolder *create_groupedpholder(WPHolder *cont) -{ - CREATEOBJ_IMPL(WGroupedPHolder, groupedpholder, (p, cont)); -} - - -void groupedpholder_deinit(WGroupedPHolder *ph) -{ - if(ph->cont!=NULL){ - destroy_obj((Obj*)ph->cont); - ph->cont=NULL; - } - - pholder_deinit(&(ph->ph)); -} - - -/*}}}*/ - - -/*{{{ Attach */ - - -static bool grouped_do_attach_final(WGroupCW *cwg, - WRegion *reg, - WGroupAttachParams *param) -{ - if(!param->geom_set){ - /* Comm. hack */ - REGION_GEOM(cwg)=REGION_GEOM(reg); - } - - param->geom_set=1; - param->geom.x=0; - param->geom.y=0; - param->geom.w=REGION_GEOM(reg).w; - param->geom.h=REGION_GEOM(reg).h; - param->szplcy=SIZEPOLICY_FULL_EXACT; - param->szplcy_set=TRUE; - - return group_do_attach_final(&cwg->grp, reg, param); -} - - -WRegion *grouped_handler(WWindow *par, - const WFitParams *fp, - void *frp_) -{ - WRegionAttachData *data=(WRegionAttachData*)frp_; - WGroupAttachParams param=GROUPATTACHPARAMS_INIT; - WGroupCW *cwg; - WRegion *reg; - WStacking *st; - - cwg=create_groupcw(par, fp); - - if(cwg==NULL) - return NULL; - - param.level_set=1; - param.level=STACKING_LEVEL_BOTTOM; - param.switchto_set=1; - param.switchto=1; - param.bottom=1; - - if(!(fp->mode®ION_FIT_WHATEVER)){ - /* Comm. hack */ - param.geom_set=TRUE; - } - - reg=region_attach_helper((WRegion*)cwg, par, fp, - (WRegionDoAttachFn*)grouped_do_attach_final, - ¶m, data); - - if(reg==NULL){ - destroy_obj((Obj*)cwg); - return NULL; - } - - return (WRegion*)cwg; -} - - -WRegion *groupedpholder_do_attach(WGroupedPHolder *ph, int flags, - WRegionAttachData *data) -{ - WRegionAttachData data2; - - if(ph->cont==NULL) - return FALSE; - - data2.type=REGION_ATTACH_NEW; - data2.u.n.fn=grouped_handler; - data2.u.n.param=data; - - return pholder_do_attach(ph->cont, flags, &data2); -} - - -/*}}}*/ - - -/*{{{ Other dynfuns */ - - -bool groupedpholder_do_goto(WGroupedPHolder *ph) -{ - return (ph->cont!=NULL - ? pholder_goto(ph->cont) - : FALSE); -} - - -WRegion *groupedpholder_do_target(WGroupedPHolder *ph) -{ - return (ph->cont!=NULL - ? pholder_target(ph->cont) - : NULL); -} - - -WPHolder *groupedpholder_do_root(WGroupedPHolder *ph) -{ - WPHolder *root; - - if(ph->cont==NULL) - return NULL; - - root=pholder_root(ph->cont); - - return (root!=ph->cont - ? root - : &ph->ph); -} - - -/*}}}*/ - - -/*{{{ Class information */ - - -static DynFunTab groupedpholder_dynfuntab[]={ - {(DynFun*)pholder_do_attach, - (DynFun*)groupedpholder_do_attach}, - - {(DynFun*)pholder_do_goto, - (DynFun*)groupedpholder_do_goto}, - - {(DynFun*)pholder_do_target, - (DynFun*)groupedpholder_do_target}, - - {(DynFun*)pholder_do_root, - (DynFun*)groupedpholder_do_root}, - - END_DYNFUNTAB -}; - -IMPLCLASS(WGroupedPHolder, WPHolder, groupedpholder_deinit, - groupedpholder_dynfuntab); - - -/*}}}*/ - diff --git a/ioncore/groupedpholder.h b/ioncore/groupedpholder.h deleted file mode 100644 index d0edf68..0000000 --- a/ioncore/groupedpholder.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * ion/ioncore/groupedpholder.h - * - * Copyright (c) Tuomo Valkonen 2005-2007. - * - * See the included file LICENSE for details. - */ - -#ifndef ION_IONCORE_GROUPEDPHOLDER_H -#define ION_IONCORE_GROUPEDPHOLDER_H - -#include "common.h" -#include "pholder.h" -#include "attach.h" - -INTRCLASS(WGroupedPHolder); - -DECLCLASS(WGroupedPHolder){ - WPHolder ph; - WPHolder *cont; -}; - -extern WGroupedPHolder *create_groupedpholder(WPHolder *cont); - -extern bool groupedpholder_init(WGroupedPHolder *ph, WPHolder *cont); - -extern void groupedpholder_deinit(WGroupedPHolder *ph); - -extern bool groupedpholder_do_goto(WGroupedPHolder *ph); - -extern WRegion *groupedpholder_do_target(WGroupedPHolder *ph); - -extern WPHolder *groupedpholder_do_root(WGroupedPHolder *ph); - -extern WRegion *groupedpholder_do_attach(WGroupedPHolder *ph, int flags, - WRegionAttachData *data); - -#endif /* ION_IONCORE_GROUPEDPHOLDER_H */ diff --git a/ioncore/grouppholder.c b/ioncore/grouppholder.c index 3c2ed30..afd8ac6 100644 --- a/ioncore/grouppholder.c +++ b/ioncore/grouppholder.c @@ -9,26 +9,93 @@ #include #include #include +#include #include #include "group.h" +#include "group-cw.h" #include "grouppholder.h" static void group_watch_handler(Watch *watch, Obj *ws); -/*{{{ Init/deinit */ +/*{{{ Primitives */ + + +void grouppholder_do_link(WGroupPHolder *ph, WGroup *group, WRegion *stack_above) +{ + ph->group=group; + + if(group!=NULL){ + LINK_ITEM_FIRST(group->phs, ph, next, prev); + }else{ + /* This seems very crucial for detached pholders... */ + ph->next=NULL; + ph->prev=ph; + } + + /* We must move stack_above pointer into a Watch. */ + if(stack_above!=NULL) + watch_setup(&(ph->stack_above_watch), (Obj*)stack_above, NULL); +} + + +static WGroupPHolder *get_head(WGroupPHolder *ph) +{ + while(1){ + /* ph->prev==NULL should not happen.. */ + if(ph->prev==NULL || ph->prev->next==NULL) + break; + ph=ph->prev; + } + + return ph; +} -static void group_watch_handler(Watch *watch, Obj *ws) +void grouppholder_do_unlink(WGroupPHolder *ph) { - WGroupPHolder *ph=FIELD_TO_STRUCT(WGroupPHolder, - group_watch, watch); - pholder_redirect(&(ph->ph), (WRegion*)ws); + WGroup *group=ph->group; + + watch_reset(&(ph->stack_above_watch)); + + if(ph->recreate_pholder!=NULL){ + if(ph->next!=NULL){ + ph->next->recreate_pholder=ph->recreate_pholder; + }else{ + /* It might be in use in attach chain! So defer. */ + mainloop_defer_destroy((Obj*)ph->recreate_pholder); + } + ph->recreate_pholder=NULL; + } + + if(group!=NULL){ + UNLINK_ITEM(group->phs, ph, next, prev); + }else{ + WGroupPHolder *next=ph->next; + + if(ph->prev!=NULL) + ph->prev->next=next; + + if(next==NULL){ + next=get_head(ph); + assert(next->prev==ph); + } + next->prev=ph->prev; + } + + ph->group=NULL; + ph->next=NULL; + ph->prev=NULL; } +/*}}}*/ + + +/*{{{ Init/deinit */ + static WGroupAttachParams dummy_param=GROUPATTACHPARAMS_INIT; @@ -36,22 +103,17 @@ bool grouppholder_init(WGroupPHolder *ph, WGroup *ws, const WStacking *st, const WGroupAttachParams *param) { + WRegion *stack_above=NULL; + pholder_init(&(ph->ph)); - watch_init(&(ph->group_watch)); watch_init(&(ph->stack_above_watch)); - - if(ws!=NULL){ - if(!watch_setup(&(ph->group_watch), (Obj*)ws, - group_watch_handler)){ - pholder_deinit(&(ph->ph)); - return FALSE; - } - } - - if(param==NULL) - param=&dummy_param; - + ph->next=NULL; + ph->prev=NULL; + ph->group=NULL; + ph->recreate_pholder=NULL; + ph->param=(param==NULL ? dummy_param : *param); + if(st!=NULL){ /* TODO? Just link to the stacking structure to remember * stacking order? @@ -71,22 +133,18 @@ bool grouppholder_init(WGroupPHolder *ph, WGroup *ws, ph->param.stack_above=st->above->reg; ph->param.bottom=(st==ws->bottom); - }else{ - ph->param=*param; } - + ph->param.switchto_set=FALSE; - - if(ph->param.stack_above!=NULL){ - /* We must move stack_above pointer into a Watch. */ - watch_setup(&(ph->stack_above_watch), - (Obj*)ph->param.stack_above, NULL); - ph->param.stack_above=NULL; - } + + stack_above=ph->param.stack_above; + ph->param.stack_above=NULL; + + grouppholder_do_link(ph, ws, stack_above); return TRUE; } - + WGroupPHolder *create_grouppholder(WGroup *ws, const WStacking *st, @@ -98,8 +156,8 @@ WGroupPHolder *create_grouppholder(WGroup *ws, void grouppholder_deinit(WGroupPHolder *ph) { - watch_reset(&(ph->group_watch)); - watch_reset(&(ph->stack_above_watch)); + grouppholder_do_unlink(ph); + pholder_deinit(&(ph->ph)); } @@ -110,15 +168,96 @@ void grouppholder_deinit(WGroupPHolder *ph) /*{{{ Dynfuns */ +static WPHolder *get_recreate_ph(WGroupPHolder *ph) +{ + return get_head(ph)->recreate_pholder; +} + + +typedef struct{ + WGroupPHolder *ph, *ph_head; + WRegionAttachData *data; + WRegion *reg_ret; +} RP; + + +static WRegion *recreate_handler(WWindow *par, + const WFitParams *fp, + void *rp_) +{ + WGroupPHolder *phtmp; + RP *rp=(RP*)rp_; + WGroup *grp; + + grp=(WGroup*)create_groupcw(par, fp); + + if(grp==NULL) + return NULL; + + rp->reg_ret=group_do_attach(grp, &rp->ph->param, rp->data); + + if(rp->reg_ret==NULL){ + destroy_obj((Obj*)grp); + return NULL; + }else{ + grp->phs=rp->ph_head; + + for(phtmp=grp->phs; phtmp!=NULL; phtmp=phtmp->next) + phtmp->group=grp; + } + + return (WRegion*)grp; +} + + + +static WRegion *grouppholder_attach_recreate(WGroupPHolder *ph, int flags, + WRegionAttachData *data) +{ + WRegionAttachData data2; + WPHolder *root, *rph; + WGroup *grp; + RP rp; + + rp.ph_head=get_head(ph); + + assert(rp.ph_head!=NULL); + + rph=rp.ph_head->recreate_pholder; + + if(rph==NULL) + return NULL; + + rp.ph=ph; + rp.data=data; + rp.reg_ret=NULL; + + data2.type=REGION_ATTACH_NEW; + data2.u.n.fn=recreate_handler; + data2.u.n.param=&rp; + + grp=(WGroup*)pholder_do_attach(rph, flags, &data2); + + if(grp!=NULL){ + assert(OBJ_IS(grp, WGroup)); + rp.ph_head->recreate_pholder=NULL; + /* It might be in use in attach chain! So defer. */ + mainloop_defer_destroy((Obj*)rph); + } + + return rp.reg_ret; +} + + WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags, WRegionAttachData *data) { - WGroup *ws=(WGroup*)ph->group_watch.obj; + WGroup *ws=ph->group; WRegion *reg; if(ws==NULL) - return FALSE; - + return grouppholder_attach_recreate(ph, flags, data); + ph->param.switchto_set=1; ph->param.switchto=(flags&PHOLDER_ATTACH_SWITCHTO ? 1 : 0); @@ -135,7 +274,7 @@ WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags, bool grouppholder_do_goto(WGroupPHolder *ph) { - WGroup *ws=(WGroup*)ph->group_watch.obj; + WGroup *ws=ph->group; if(ws!=NULL) return region_goto((WRegion*)ws); @@ -146,7 +285,7 @@ bool grouppholder_do_goto(WGroupPHolder *ph) WRegion *grouppholder_do_target(WGroupPHolder *ph) { - return (WRegion*)ph->group_watch.obj; + return (WRegion*)ph->group; } diff --git a/ioncore/grouppholder.h b/ioncore/grouppholder.h index 86974ad..c829537 100644 --- a/ioncore/grouppholder.h +++ b/ioncore/grouppholder.h @@ -13,13 +13,14 @@ #include #include "group.h" -INTRCLASS(WGroupPHolder); DECLCLASS(WGroupPHolder){ WPHolder ph; - Watch group_watch; + WGroup *group; Watch stack_above_watch; WGroupAttachParams param; + WGroupPHolder *next, *prev; + WPHolder *recreate_pholder; }; extern WGroupPHolder *create_grouppholder(WGroup *group, @@ -43,4 +44,8 @@ extern WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags, extern WGroupPHolder *group_managed_get_pholder(WGroup *group, WRegion *mgd); +extern void grouppholder_do_unlink(WGroupPHolder *ph); +extern void grouppholder_do_link(WGroupPHolder *ph, WGroup *group, + WRegion *stack_above); + #endif /* ION_IONCORE_GROUPPHOLDER_H */ diff --git a/ioncore/ioncore.c b/ioncore/ioncore.c index e66f5cd..8974780 100644 --- a/ioncore/ioncore.c +++ b/ioncore/ioncore.c @@ -281,7 +281,6 @@ static bool init_hooks() INIT_HOOK_(ioncore_submap_ungrab_hook); INIT_HOOK_(region_notify_hook); - ADD_HOOK_(region_notify_hook, ioncore_frame_quasiactivation_notify); ADD_HOOK_(region_notify_hook, ioncore_screen_activity_notify); INIT_HOOK(clientwin_do_manage_alt, clientwin_do_manage_default); diff --git a/ioncore/ioncore_ext.lua b/ioncore/ioncore_ext.lua index dde9195..8f1bfab 100644 --- a/ioncore/ioncore_ext.lua +++ b/ioncore/ioncore_ext.lua @@ -26,6 +26,7 @@ dopath('ioncore_misc') dopath('ioncore_wd') dopath('ioncore_menudb') dopath('ioncore_tabnum') +dopath('ioncore_quasiact') -- Modifier setup compatibility kludge local oldindex diff --git a/ioncore/ioncore_quasiact.lua b/ioncore/ioncore_quasiact.lua new file mode 100644 index 0000000..ce4116d --- /dev/null +++ b/ioncore/ioncore_quasiact.lua @@ -0,0 +1,74 @@ +-- +-- ion/share/ioncore_quasiact.lua -- Frame quasiactivation support +-- +-- Copyright (c) Tuomo Valkonen 2007. +-- +-- See the included file LICENSE for details. +-- + +local qa_source={} +local qa_target={} + +local function quasi_activated(frame, src) + local old=qa_source[frame] + if old then + qa_target[old]=nil + end + qa_source[frame]=src + qa_target[src]=frame + ioncore.defer(function() frame:set_grattr("quasiactive", "set") end) +end + +local function quasi_inactivated(frame, src) + qa_source[frame]=nil + qa_target[src]=nil + ioncore.defer(function() frame:set_grattr("quasiactive", "unset") end) +end + +local function activated(src) + local tgt=src:__return_target() + if obj_is(tgt, "WFrame") then + quasi_activated(tgt, src) + elseif obj_is(tgt, "WGroup") then + local mgr=tgt:manager() + if obj_is(mgr, "WFrame") then + quasi_activated(mgr, src) + end + end +end + +local function inactivated(src) + local tgt=qa_target[src] + if tgt then + quasi_inactivated(tgt, src) + return true + end +end + +local function deinit(tgt) + local src=qa_source[tgt] + if src then + qa_target[src]=nil + qa_source[tgt]=nil + end +end + +local function quasiact_notify(reg, how) + if how=="activated" or how=="pseudoactivated" then + activated(reg) + elseif how=="inactivated" or how=="pseudoinactivated" then + inactivated(reg) + elseif how=="set_return" then + if reg:is_active(true--[[pseudoact--]]) then + activated(reg) + end + elseif how=="unset_return" then + inactivated(reg) + elseif how=="deinit" then + inactivated(reg) + deinit(reg) + end +end + + +ioncore.get_hook("region_notify_hook"):add(quasiact_notify) diff --git a/ioncore/ioncore_wd.lua b/ioncore/ioncore_wd.lua index d69a9eb..c0b42e5 100644 --- a/ioncore/ioncore_wd.lua +++ b/ioncore/ioncore_wd.lua @@ -8,26 +8,19 @@ local savefile="saved_wd" local dirs={} -local px +local lfs -if pcall(function() return require('posix') end) then - px=posix +if pcall(function() return require('lfs') end) then + lfs=_G["lfs"] end local function checkdir(d) - if not px then + if not lfs then return true else - local t, err=px.stat(d, "type") + local t, err=lfs.attributes(d, "mode") if not t then return nil, err - elseif t=="link" then - local d2, err=px.readlink(d) - if not d2 then - return nil, err - else - return checkdir(d2) - end elseif t=="directory" then return true else diff --git a/ioncore/manage.c b/ioncore/manage.c index 69b7711..f1b04c6 100644 --- a/ioncore/manage.c +++ b/ioncore/manage.c @@ -339,6 +339,23 @@ bool region_rescue_child_clientwins(WRegion *reg, WRescueInfo *info) } +WPHolder *rescueinfo_pholder(WRescueInfo *info) +{ + if(info->test) + return NULL; + + if(info->ph==NULL){ + info->ph=region_get_rescue_pholder(info->get_rescue); + if(info->ph==NULL){ + info->failed_get=TRUE; + return NULL; + } + } + + return info->ph; +} + + /* Bah, unsplitissä oikestaan pitäisi tehä non-deep rescue */ bool region_do_rescue_this(WRegion *tosave_, WRescueInfo *info, int ph_flags) @@ -359,19 +376,13 @@ bool region_do_rescue_this(WRegion *tosave_, WRescueInfo *info, int ph_flags) if(tosave==NULL){ return region_rescue_clientwins(tosave_, info); - }else if(info->test){ - return FALSE; }else{ int phf=(info->flags®ION_RESCUE_PHFLAGS_OK ? ph_flags : 0); + WPHolder *ph=rescueinfo_pholder(info); - if(info->ph==NULL){ - info->ph=region_get_rescue_pholder(info->get_rescue); - if(info->ph==NULL){ - info->failed_get=TRUE; - return FALSE; - } - } - return pholder_attach(info->ph, phf, tosave); + return (ph==NULL + ? FALSE + : pholder_attach(info->ph, phf, tosave)); } } diff --git a/ioncore/manage.h b/ioncore/manage.h index dbe09ac..f745d66 100644 --- a/ioncore/manage.h +++ b/ioncore/manage.h @@ -103,6 +103,8 @@ extern WPHolder *region_prepare_manage_transient_default(WRegion *reg, INTRSTRUCT(WRescueInfo); +extern WPHolder *rescueinfo_pholder(WRescueInfo *info); + /* if ph is given, it is used, otherwise one is looked for when needed */ extern bool region_rescue(WRegion *reg, WPHolder *ph, int flags); extern bool region_rescue_needed(WRegion *reg); diff --git a/ioncore/mplex.c b/ioncore/mplex.c index 239d46f..8af9148 100644 --- a/ioncore/mplex.c +++ b/ioncore/mplex.c @@ -33,13 +33,13 @@ #include "saveload.h" #include "xwindow.h" #include "mplexpholder.h" +#include "grouppholder.h" #include "llist.h" #include "names.h" #include "sizepolicy.h" #include "stacking.h" #include "group.h" #include "navi.h" -#include "groupedpholder.h" #define SUBS_MAY_BE_MAPPED(MPLEX) \ @@ -98,7 +98,7 @@ bool mplex_do_init(WMPlex *mplex, WWindow *parent, mplex->mx_list=NULL; mplex->mx_current=NULL; - mplex->mx_phs=NULL; + mplex->misc_phs=NULL; mplex->mx_count=0; mplex->mgd=NULL; @@ -147,8 +147,8 @@ void mplex_deinit(WMPlex *mplex) assert(mplex->mgd==NULL); assert(mplex->mx_list==NULL); - while(mplex->mx_phs!=NULL){ - assert(mplexpholder_move(mplex->mx_phs, NULL, NULL, NULL)); + while(mplex->misc_phs!=NULL){ + assert(mplexpholder_move(mplex->misc_phs, NULL, NULL, NULL)); } window_deinit((WWindow*)mplex); @@ -246,7 +246,8 @@ WRegion *mplex_mx_nth(WMPlex *mplex, uint n) /*EXTL_DOC * Iterate over numbered/mutually exclusive region list of \var{mplex} * until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE @@ -263,7 +264,8 @@ bool mplex_mx_i(WMPlex *mplex, ExtlFn iterfn) /*EXTL_DOC * Iterate over managed regions of \var{mplex} until \var{iterfn} returns * \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE @@ -432,7 +434,8 @@ bool mplex_fitrep(WMPlex *mplex, WWindow *par, const WFitParams *fp) bool wchg=(REGION_GEOM(mplex).w!=fp->g.w); bool hchg=(REGION_GEOM(mplex).h!=fp->g.h); - window_do_fitrep(&(mplex->win), par, &(fp->g)); + if(!window_fitrep(&(mplex->win), par, fp)) + return FALSE; if(wchg || hchg){ mplex_fit_managed(mplex); @@ -1339,18 +1342,24 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph) } +static void mplex_attach_fp(WMPlex *mplex, const WMPlexAttachParams *param, + WFitParams *fp) +{ + if(param->flags&MPLEX_ATTACH_GEOM) + fp->g=param->geom; + else + mplex_managed_geom(mplex, &(fp->g)); + + fp->mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS; +} + + WRegion *mplex_do_attach_pholder(WMPlex *mplex, WMPlexPHolder *ph, WRegionAttachData *data) { - WMPlexAttachParams *param=&(ph->param); WFitParams fp; - if(param->flags&MPLEX_ATTACH_GEOM) - fp.g=param->geom; - else - mplex_managed_geom(mplex, &(fp.g)); - - fp.mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS; + mplex_attach_fp(mplex, &ph->param, &fp); return region_attach_helper((WRegion*)mplex, (WWindow*)mplex, &fp, @@ -1598,9 +1607,19 @@ WPHolder *mplex_prepare_manage(WMPlex *mplex, const WClientWin *cwin, mph=create_mplexpholder(mplex, NULL, &ap); if(mph!=NULL){ - WGroupedPHolder *gph=create_groupedpholder((WPHolder*)mph); - if(gph!=NULL) + WGroupPHolder *gph; + WGroupAttachParams gp=GROUPATTACHPARAMS_INIT; + + gp.switchto_set=1; + gp.switchto=1; + gp.bottom=1; + + gph=create_grouppholder(NULL, NULL, &gp); + + if(gph!=NULL){ + gph->recreate_pholder=(WPHolder*)mph; return (WPHolder*)gph; + } } return (WPHolder*)mph; @@ -1683,13 +1702,29 @@ void mplex_managed_remove(WMPlex *mplex, WRegion *sub) } +void mplex_child_removed(WMPlex *mplex, WRegion *sub) +{ + if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){ + watch_reset(&(mplex->stdispwatch)); + mplex_set_stdisp(mplex, NULL, NULL); + } +} + + +/*}}}*/ + + +/*{{{ Rescue */ + + bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info) { bool ret1, ret2; WMPlexIterTmp tmp; WLListIterTmp ltmp; WLListNode *lnode, *was_current=mplex->mx_current; - + + /* First all mx stuff to move them nicely to another mplex (when that * is the case), switching to the current region in the target if * allowed by ph_flags_mask region_rescue. @@ -1712,40 +1747,11 @@ bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info) } - -void mplex_child_removed(WMPlex *mplex, WRegion *sub) -{ - if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){ - watch_reset(&(mplex->stdispwatch)); - mplex_set_stdisp(mplex, NULL, NULL); - } -} - - /*}}}*/ /*{{{ Status display support */ -#ifndef offsetof -# define offsetof(T,F) ((size_t)((char*)&((T*)0L)->F-(char*)0L)) -#endif - -#define STRUCTOF(T, F, FADDR) \ - ((T*)((char*)(FADDR)-offsetof(T, F))) - - -static void stdisp_watch_handler(Watch *watch, Obj *obj) -{ - /*WMPlex *mplex=STRUCTOF(WMPlex, stdispinfo, - STRUCTOF(WMPlexSTDispInfo, regwatch, watch)); - WMPlexSTDispInfo *di=&(mplex->stdispinfo); - WGenWS *ws=OBJ_CAST(REGION_MANAGER(obj), WGenWS); - * - if(ioncore_g.opmode!=IONCORE_OPMODE_DEINIT && ws!=NULL) - genws_unmanage_stdisp(ws, TRUE, FALSE);*/ -} - bool mplex_set_stdisp(WMPlex *mplex, WRegion *reg, const WMPlexSTDispInfo *din) @@ -1776,7 +1782,7 @@ bool mplex_set_stdisp(WMPlex *mplex, WRegion *reg, region_detach_manager(oldstdisp); } }else{ - watch_setup(&(mplex->stdispwatch), (Obj*)reg, stdisp_watch_handler); + watch_setup(&(mplex->stdispwatch), (Obj*)reg, NULL); mplex_remanage_stdisp(mplex); } @@ -1870,7 +1876,7 @@ WRegion *mplex_set_stdisp_extl(WMPlex *mplex, ExtlTab t) data.type=REGION_ATTACH_LOAD; data.u.tab=t; - + stdisp=region_attach_helper((WRegion*)mplex, (WWindow*)mplex, &fp, do_attach_stdisp, NULL, @@ -2113,16 +2119,6 @@ ExtlTab mplex_get_configuration(WMPlex *mplex) } -static WMPlex *tmp_mplex=NULL; -static WMPlexAttachParams *tmp_par=NULL; - -static WPHolder *pholder_callback() -{ - assert(tmp_mplex!=NULL); - return (WPHolder*)create_mplexpholder(tmp_mplex, NULL, tmp_par); -} - - void mplex_load_contents(WMPlex *mplex, ExtlTab tab) { ExtlTab substab, subtab; @@ -2138,27 +2134,26 @@ void mplex_load_contents(WMPlex *mplex, ExtlTab tab) n=extl_table_get_n(substab); for(i=1; i<=n; i++){ if(extl_table_geti_t(substab, i, &subtab)){ - /*mplex_attach_new(mplex, subtab);*/ WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT; - WRegionAttachData data; - char *tmp=NULL; + WFitParams fp; + WPHolder *ph; get_params(mplex, subtab, 0, &par); + mplex_attach_fp(mplex, &par, &fp); par.flags|=MPLEX_ATTACH_INDEX; par.index=LLIST_INDEX_LAST; - tmp_par=∥ - tmp_mplex=mplex; - - data.type=REGION_ATTACH_LOAD; - data.u.tab=subtab; + ph=(WPHolder*)create_mplexpholder(mplex, NULL, &par); - ioncore_set_sm_pholder_callback(pholder_callback); - - mplex_do_attach(mplex, &par, &data); - - tmp_mplex=NULL; + if(ph!=NULL){ + region_attach_load_helper((WRegion*)mplex, (WWindow*)mplex, &fp, + (WRegionDoAttachFn*)mplex_do_attach_final, + (void*)ph, subtab, &ph); + + if(ph!=NULL) + destroy_obj((Obj*)ph); + } extl_unref_table(subtab); } diff --git a/ioncore/mplex.h b/ioncore/mplex.h index 7bc833f..aced27f 100644 --- a/ioncore/mplex.h +++ b/ioncore/mplex.h @@ -94,7 +94,7 @@ DECLCLASS(WMPlex){ int mx_count; WLListNode *mx_current; WLListNode *mx_list; - WMPlexPHolder *mx_phs; + WMPlexPHolder *misc_phs; Watch stdispwatch; WMPlexSTDispInfo stdispinfo; diff --git a/ioncore/mplexpholder.c b/ioncore/mplexpholder.c index 8bb7ddb..3cbf5fd 100644 --- a/ioncore/mplexpholder.c +++ b/ioncore/mplexpholder.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "common.h" #include "mplex.h" @@ -18,9 +19,6 @@ #include "basicpholder.h" -static void mplex_watch_handler(Watch *watch, Obj *mplex); - - /*{{{ Primitives */ @@ -35,7 +33,7 @@ static void mplexpholder_do_link(WMPlexPHolder *ph, WMPlexPHolder *after, WLListNode *or_after) { - assert(mplex==(WMPlex*)ph->mplex_watch.obj && mplex!=NULL); + assert(mplex==(WMPlex*)ph->mplex && mplex!=NULL); if(after!=NULL){ assert(after->after==or_after); @@ -43,44 +41,60 @@ static void mplexpholder_do_link(WMPlexPHolder *ph, if(after->after!=NULL){ LINK_ITEM_AFTER(after->after->phs, after, ph, next, prev); }else{ - assert(on_ph_list(mplex->mx_phs, after)); - LINK_ITEM_AFTER(mplex->mx_phs, after, ph, next, prev); + assert(on_ph_list(mplex->misc_phs, after)); + LINK_ITEM_AFTER(mplex->misc_phs, after, ph, next, prev); } ph->after=after->after; }else if(or_after!=NULL){ LINK_ITEM_FIRST(or_after->phs, ph, next, prev); ph->after=or_after; }else{ - LINK_ITEM_FIRST(mplex->mx_phs, ph, next, prev); + LINK_ITEM_FIRST(mplex->misc_phs, ph, next, prev); ph->after=NULL; } } +static WMPlexPHolder *get_head(WMPlexPHolder *ph) +{ + while(1){ + /* ph->prev==NULL should not happen.. */ + if(ph->prev==NULL || ph->prev->next==NULL) + break; + ph=ph->prev; + } + + return ph; +} + + void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex) { if(ph->recreate_pholder!=NULL){ - if(ph->prev!=NULL) - ph->prev->recreate_pholder=ph->recreate_pholder; - else - destroy_obj((Obj*)ph->recreate_pholder); + if(ph->next!=NULL){ + ph->next->recreate_pholder=ph->recreate_pholder; + }else{ + /* It might be in use in attach chain! So defer. */ + mainloop_defer_destroy((Obj*)ph->recreate_pholder); + } ph->recreate_pholder=NULL; } if(ph->after!=NULL){ UNLINK_ITEM(ph->after->phs, ph, next, prev); - }else if(mplex!=NULL && on_ph_list(mplex->mx_phs, ph)){ - UNLINK_ITEM(mplex->mx_phs, ph, next, prev); + }else if(mplex!=NULL && on_ph_list(mplex->misc_phs, ph)){ + UNLINK_ITEM(mplex->misc_phs, ph, next, prev); }else{ WMPlexPHolder *next=ph->next; - - assert((ph->next==NULL && ph->prev==NULL) - || ph->mplex_watch.obj==NULL); - if(ph->next!=NULL) - ph->next->prev=ph->prev; if(ph->prev!=NULL) ph->prev->next=next; + + if(next==NULL){ + next=get_head(ph); + assert(next->prev==ph); + } + next->prev=ph->prev; } ph->after=NULL; @@ -95,14 +109,6 @@ void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex) /*{{{ Init/deinit */ -static void mplex_watch_handler(Watch *watch, Obj *mplex) -{ - WMPlexPHolder *ph=FIELD_TO_STRUCT(WMPlexPHolder, mplex_watch, watch); - mplexpholder_do_unlink(ph, (WMPlex*)mplex); - pholder_redirect(&(ph->ph), (WRegion*)mplex); -} - - static void mplex_get_attach_params(WMPlex *mplex, WStacking *st, WMPlexAttachParams *param) { @@ -120,27 +126,24 @@ static void mplex_get_attach_params(WMPlex *mplex, WStacking *st, bool mplexpholder_init(WMPlexPHolder *ph, WMPlex *mplex, WStacking *st, WMPlexAttachParams *param) { + WLListNode *or_after=NULL; + WMPlexPHolder *after=NULL; + pholder_init(&(ph->ph)); - watch_init(&(ph->mplex_watch)); + ph->mplex=mplex; ph->after=NULL; ph->next=NULL; ph->prev=NULL; ph->param.flags=0; ph->recreate_pholder=NULL; - - if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler)){ - pholder_deinit(&(ph->ph)); - return FALSE; - } if(st!=NULL){ mplex_get_attach_params(mplex, st, &ph->param); if(st->lnode!=NULL){ - mplexpholder_do_link(ph, mplex, - LIST_LAST(st->lnode->phs, next, prev), - st->lnode); + after=LIST_LAST(st->lnode->phs, next, prev); + or_after=st->lnode; } }else{ static WMPlexAttachParams dummy_param={0, 0, {0, 0, 0, 0}, 0, 0}; @@ -154,18 +157,17 @@ bool mplexpholder_init(WMPlexPHolder *ph, WMPlex *mplex, WStacking *st, int index=(param->flags&MPLEX_ATTACH_INDEX ? param->index : mplex_default_index(mplex)); - WLListNode *or_after=llist_index_to_after(mplex->mx_list, - mplex->mx_current, - index); - WMPlexPHolder *after=(index==LLIST_INDEX_LAST - ? (or_after!=NULL - ? LIST_LAST(or_after->phs, next, prev) - : LIST_LAST(mplex->mx_phs, next, prev)) - : NULL); - - mplexpholder_do_link(ph, mplex, after, or_after); + or_after=llist_index_to_after(mplex->mx_list, + mplex->mx_current, index); + after=(index==LLIST_INDEX_LAST + ? (or_after!=NULL + ? LIST_LAST(or_after->phs, next, prev) + : LIST_LAST(mplex->misc_phs, next, prev)) + : NULL); } } + + mplexpholder_do_link(ph, mplex, after, or_after); return TRUE; } @@ -181,8 +183,7 @@ WMPlexPHolder *create_mplexpholder(WMPlex *mplex, void mplexpholder_deinit(WMPlexPHolder *ph) { - mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj); - watch_reset(&(ph->mplex_watch)); + mplexpholder_do_unlink(ph, ph->mplex); pholder_deinit(&(ph->ph)); } @@ -197,18 +198,18 @@ typedef struct{ WMPlexPHolder *ph, *ph_head; WRegionAttachData *data; WFramedParam *param; + WRegion *reg_ret; } RP; -WRegion *recreate_handler(WWindow *par, - const WFitParams *fp, - void *rp_) +static WRegion *recreate_handler(WWindow *par, + const WFitParams *fp, + void *rp_) { RP *rp=(RP*)rp_; WMPlexPHolder *ph=rp->ph, *ph_head=rp->ph_head, *phtmp; WFramedParam *param=rp->param; WFrame *frame; - WRegion *reg; frame=create_frame(par, fp, param->mode); @@ -216,49 +217,37 @@ WRegion *recreate_handler(WWindow *par, return NULL; /* Move pholders to frame */ - frame->mplex.mx_phs=ph_head; + frame->mplex.misc_phs=ph_head; - for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next) - watch_setup(&(phtmp->mplex_watch), (Obj*)frame, mplex_watch_handler); + for(phtmp=frame->mplex.misc_phs; phtmp!=NULL; phtmp=phtmp->next) + phtmp->mplex=&frame->mplex; /* Attach */ if(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER)) ph->param.flags|=MPLEX_ATTACH_WHATEVER; - reg=mplex_do_attach_pholder(&frame->mplex, ph, rp->data); + rp->reg_ret=mplex_do_attach_pholder(&frame->mplex, ph, rp->data); ph->param.flags&=~MPLEX_ATTACH_WHATEVER; - if(reg==NULL){ + if(rp->reg_ret==NULL){ /* Try to recover */ - for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next) - watch_reset(&(phtmp->mplex_watch)); - frame->mplex.mx_phs=NULL; + for(phtmp=frame->mplex.misc_phs; phtmp!=NULL; phtmp=phtmp->next) + phtmp->mplex=NULL; + + frame->mplex.misc_phs=NULL; destroy_obj((Obj*)frame); return NULL; }else{ - frame_adjust_to_initial(frame, fp, param, reg); + frame_adjust_to_initial(frame, fp, param, rp->reg_ret); return (WRegion*)frame; } } -static WMPlexPHolder *get_head(WMPlexPHolder *ph) -{ - while(1){ - /* ph->prev==NULL should not happen.. */ - if(ph->prev==NULL || ph->prev->next==NULL) - break; - ph=ph->prev; - } - - return ph; -} - - static WFramedPHolder *get_recreate_ph(WMPlexPHolder *ph) { return get_head(ph)->recreate_pholder; @@ -271,7 +260,7 @@ static WRegion *mplexpholder_attach_recreate(WMPlexPHolder *ph, int flags, WRegionAttachData data2; WFramedPHolder *fph; WPHolder *root; - WRegion *reg; + WRegion *frame; RP rp; rp.ph_head=get_head(ph); @@ -286,26 +275,28 @@ static WRegion *mplexpholder_attach_recreate(WMPlexPHolder *ph, int flags, rp.ph=ph; rp.data=data; rp.param=&fph->param; + rp.reg_ret=NULL; data2.type=REGION_ATTACH_NEW; data2.u.n.fn=recreate_handler; data2.u.n.param=&rp; - reg=pholder_do_attach(fph->cont, flags, &data2); /* == frame */ + frame=pholder_do_attach(fph->cont, flags, &data2); - if(reg!=NULL){ - destroy_obj((Obj*)fph); + if(frame!=NULL){ rp.ph_head->recreate_pholder=NULL; + /* It might be in use in attach chain! So defer. */ + mainloop_defer_destroy((Obj*)fph); } - - return reg; + + return rp.reg_ret; } WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags, WRegionAttachData *data) { - WMPlex *mplex=(WMPlex*)ph->mplex_watch.obj; + WMPlex *mplex=ph->mplex; if(mplex==NULL) return mplexpholder_attach_recreate(ph, flags, data); @@ -322,18 +313,14 @@ WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags, bool mplexpholder_move(WMPlexPHolder *ph, WMPlex *mplex, WMPlexPHolder *after, WLListNode *or_after) - { - mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj); + mplexpholder_do_unlink(ph, ph->mplex); - watch_reset(&(ph->mplex_watch)); - + ph->mplex=mplex; + if(mplex==NULL) return TRUE; - if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler)) - return FALSE; - mplexpholder_do_link(ph, mplex, after, or_after); return TRUE; @@ -342,7 +329,7 @@ bool mplexpholder_move(WMPlexPHolder *ph, WMPlex *mplex, bool mplexpholder_do_goto(WMPlexPHolder *ph) { - WRegion *reg=(WRegion*)ph->mplex_watch.obj; + WRegion *reg=(WRegion*)ph->mplex; if(reg!=NULL){ return region_goto(reg); @@ -358,7 +345,7 @@ bool mplexpholder_do_goto(WMPlexPHolder *ph) WRegion *mplexpholder_do_target(WMPlexPHolder *ph) { - WRegion *reg=(WRegion*)ph->mplex_watch.obj; + WRegion *reg=(WRegion*)ph->mplex; if(reg!=NULL){ return reg; @@ -372,24 +359,16 @@ WRegion *mplexpholder_do_target(WMPlexPHolder *ph) } -WPHolder *mplexpholder_do_root(WMPlexPHolder *ph) +bool mplexpholder_stale(WMPlexPHolder *ph) { - WRegion *reg=(WRegion*)ph->mplex_watch.obj; + WRegion *reg=(WRegion*)ph->mplex; if(reg!=NULL){ - return &ph->ph; + return FALSE; }else{ WFramedPHolder *fph=get_recreate_ph(ph); - WPHolder *root; - if(fph==NULL) - return NULL; - - root=pholder_root((WPHolder*)fph); - - return (root!=(WPHolder*)fph - ? root - : &ph->ph); + return (fph==NULL || pholder_stale((WPHolder*)fph)); } } @@ -427,7 +406,7 @@ void mplex_move_phs_before(WMPlex *mplex, WLListNode *node) after=(or_after!=NULL ? LIST_LAST(or_after->phs, next, prev) - : LIST_LAST(mplex->mx_phs, next, prev)); + : LIST_LAST(mplex->misc_phs, next, prev)); mplex_move_phs(mplex, node, after, or_after); } @@ -444,6 +423,33 @@ WMPlexPHolder *mplex_managed_get_pholder(WMPlex *mplex, WRegion *mgd) } +void mplex_flatten_phs(WMPlex *mplex) +{ + WLListNode *node; + WLListIterTmp tmp; + + FOR_ALL_NODES_ON_LLIST(node, mplex->mx_list, tmp){ + WMPlexPHolder *last=(mplex->misc_phs==NULL ? NULL : mplex->misc_phs->prev); + mplex_move_phs(mplex, node, last, NULL); + } +} + + +void mplex_migrate_phs(WMPlex *src, WMPlex *dst) +{ + WLListNode *or_after=LIST_LAST(dst->mx_list, next, prev); + WMPlexPHolder *after=(or_after!=NULL + ? LIST_LAST(or_after->phs, next, prev) + : LIST_LAST(dst->misc_phs, next, prev)); + + while(src->misc_phs!=NULL){ + WMPlexPHolder *ph=src->misc_phs; + mplexpholder_move(ph, dst, after, or_after); + after=ph; + } +} + + /*}}}*/ @@ -508,8 +514,8 @@ static DynFunTab mplexpholder_dynfuntab[]={ {(DynFun*)pholder_do_target, (DynFun*)mplexpholder_do_target}, - {(DynFun*)pholder_do_root, - (DynFun*)mplexpholder_do_root}, + {(DynFun*)pholder_stale, + (DynFun*)mplexpholder_stale}, END_DYNFUNTAB }; diff --git a/ioncore/mplexpholder.h b/ioncore/mplexpholder.h index a017641..aee4678 100644 --- a/ioncore/mplexpholder.h +++ b/ioncore/mplexpholder.h @@ -18,7 +18,7 @@ DECLCLASS(WMPlexPHolder){ WPHolder ph; - Watch mplex_watch; + WMPlex *mplex; WFramedPHolder *recreate_pholder; /* only on first of list */ WLListNode *after; WMPlexPHolder *next, *prev; @@ -43,7 +43,7 @@ extern WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags, extern bool mplexpholder_do_goto(WMPlexPHolder *ph); -extern WPHolder *mplexpholder_do_root(WMPlexPHolder *ph); +extern bool mplexpholder_stale(WMPlexPHolder *ph); extern WRegion *mplexpholder_do_target(WMPlexPHolder *ph); @@ -57,6 +57,8 @@ extern void mplex_move_phs(WMPlex *mplex, WLListNode *node, WMPlexPHolder *after, WLListNode *or_after); extern void mplex_move_phs_before(WMPlex *mplex, WLListNode *node); +extern void mplex_migrate_phs(WMPlex *src, WMPlex *dst); +extern void mplex_flatten_phs(WMPlex *mplex); extern WMPlexPHolder *mplex_managed_get_pholder(WMPlex *mplex, WRegion *mgd); diff --git a/ioncore/names.c b/ioncore/names.c index b7a8668..ce4d2ae 100644 --- a/ioncore/names.c +++ b/ioncore/names.c @@ -562,7 +562,8 @@ static bool do_list(ExtlFn fn, WNamespace *ns, const char *typenam) /*EXTL_DOC * Iterate over all non-client window regions with (inherited) class * \var{typenam} until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE @@ -575,7 +576,8 @@ bool ioncore_region_i(ExtlFn fn, const char *typenam) /*EXTL_DOC * Iterate over client windows until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE diff --git a/ioncore/pholder.c b/ioncore/pholder.c index f5f9aae..45c5d0b 100644 --- a/ioncore/pholder.c +++ b/ioncore/pholder.c @@ -15,15 +15,12 @@ bool pholder_init(WPHolder *ph) { - ph->redirect=NULL; return TRUE; } void pholder_deinit(WPHolder *ph) { - if(ph->redirect!=NULL) - destroy_obj((Obj*)ph->redirect); } @@ -37,20 +34,6 @@ WRegion *pholder_do_attach(WPHolder *ph, int flags, } -WRegion *pholder_attach_(WPHolder *ph, int flags, WRegionAttachData *data) -{ - WPHolder *root=pholder_root(ph); - - /* Use the root, so that extra containers are not added from - * stale chains. - */ - - return (root==NULL - ? NULL - : pholder_do_attach(root, flags, data)); -} - - bool pholder_attach(WPHolder *ph, int flags, WRegion *reg) { WRegionAttachData data; @@ -58,7 +41,7 @@ bool pholder_attach(WPHolder *ph, int flags, WRegion *reg) data.type=REGION_ATTACH_REPARENT; data.u.reg=reg; - return (pholder_attach_(ph, flags, &data)!=NULL); + return (pholder_do_attach(ph, flags, &data)!=NULL); } @@ -86,9 +69,7 @@ WRegion *pholder_do_target(WPHolder *ph) WRegion *pholder_target(WPHolder *ph) { - return (ph->redirect!=NULL - ? pholder_target(ph->redirect) - : pholder_do_target(ph)); + return pholder_do_target(ph); } @@ -112,10 +93,7 @@ DYNFUN bool pholder_do_check_reparent(WPHolder *ph, WRegion *reg) bool pholder_check_reparent(WPHolder *ph, WRegion *reg) { - if(ph->redirect!=NULL) - return pholder_check_reparent(ph->redirect, reg); - else - return pholder_do_check_reparent(ph, reg); + return pholder_do_check_reparent(ph, reg); } @@ -129,53 +107,21 @@ bool pholder_do_goto(WPHolder *ph) bool pholder_goto(WPHolder *ph) { - return (ph->redirect!=NULL - ? pholder_goto(ph->redirect) - : pholder_do_goto(ph)); -} - - -WPHolder *pholder_do_root_default(WPHolder *ph) -{ - return ph; -} - - -WPHolder *pholder_do_root(WPHolder *ph) -{ - WPHolder *ret=NULL; - CALL_DYN_RET(ret, WPHolder*, pholder_do_root, ph, (ph)); - return ret; + return pholder_do_goto(ph); } -WPHolder *pholder_root(WPHolder *ph) +bool pholder_stale_default(WPHolder *ph) { - return (ph->redirect!=NULL - ? pholder_root(ph->redirect) - : pholder_do_root(ph)); + return (pholder_target(ph)==NULL); } bool pholder_stale(WPHolder *ph) { - return (pholder_root(ph)!=ph); -} - - -bool pholder_redirect(WPHolder *ph, WRegion *old_target) -{ - WPHolder *ph2=region_get_rescue_pholder(old_target); - - if(ph2==NULL) - return FALSE; - - if(ph->redirect!=NULL) - destroy_obj((Obj*)ph->redirect); - - ph->redirect=ph2; - - return TRUE; + bool ret=TRUE; + CALL_DYN_RET(ret, bool, pholder_stale, ph, (ph)); + return ret; } @@ -231,8 +177,8 @@ static DynFunTab pholder_dynfuntab[]={ {(DynFun*)pholder_do_check_reparent, (DynFun*)pholder_do_check_reparent_default}, - {(DynFun*)pholder_do_root, - (DynFun*)pholder_do_root_default}, + {(DynFun*)pholder_stale, + (DynFun*)pholder_stale_default}, END_DYNFUNTAB }; diff --git a/ioncore/pholder.h b/ioncore/pholder.h index b2b4986..4d07f16 100644 --- a/ioncore/pholder.h +++ b/ioncore/pholder.h @@ -21,7 +21,6 @@ DECLCLASS(WPHolder){ Obj obj; - WPHolder *redirect; }; @@ -42,11 +41,7 @@ DYNFUN WRegion *pholder_do_target(WPHolder *ph); extern WRegion *pholder_target(WPHolder *ph); -extern WPHolder *pholder_do_root(WPHolder *ph); - -extern WPHolder *pholder_root(WPHolder *ph); - -extern bool pholder_stale(WPHolder *ph); +DYNFUN bool pholder_stale(WPHolder *ph); DYNFUN bool pholder_do_check_reparent(WPHolder *ph, WRegion *reg); @@ -56,8 +51,6 @@ DYNFUN bool pholder_do_goto(WPHolder *ph); extern bool pholder_goto(WPHolder *ph); -extern bool pholder_redirect(WPHolder *ph, WRegion *old_target); - extern WPHolder *pholder_either(WPHolder *a, WPHolder *b); DYNFUN WPHolder *region_managed_get_pholder(WRegion *reg, WRegion *mgd); diff --git a/ioncore/pointer.c b/ioncore/pointer.c index 4d5e26e..f4fae71 100644 --- a/ioncore/pointer.c +++ b/ioncore/pointer.c @@ -217,13 +217,30 @@ static void pointer_grab_killed(WRegion *unused) } -bool ioncore_do_handle_buttonpress(XButtonEvent *ev) +static bool listens_to(WRegion *reg, uint state, uint button, int area) +{ + static const int acts[]={BINDING_BUTTONMOTION, BINDING_BUTTONCLICK, + BINDING_BUTTONDBLCLICK}; + static const int n_acts=3; + int i; + + for(i=0; istate; button=ev->button; @@ -232,9 +249,37 @@ bool ioncore_do_handle_buttonpress(XButtonEvent *ev) if(reg==NULL) return FALSE; - + dblclick=(p_clickcnt==1 && time_in_threshold(ev->time) && - p_button==button && p_state==state && reg==p_reg); + p_button==button && p_state==state); + + if(dblclick && p_reg!=reg){ + if(sub) + return FALSE; + dblclick=FALSE; + } + + subreg=region_current(reg); + area=window_press((WWindow*)reg, ev, &subreg); + + if(dblclick){ + pressbind=region_lookup_binding(reg, BINDING_BUTTONDBLCLICK, state, + button, area); + } + + if(pressbind==NULL){ + pressbind=region_lookup_binding(reg, BINDING_BUTTONPRESS, state, + button, area); + } + + if(pressbind==NULL && sub){ + /* If subwindow doesn't listen to state/button(/area) at all, return and + * let the parent that has the event grabbed, handle it. Otherwise we + * fully block the parent. + */ + if(!dblclick && !listens_to(reg, state, button, area)) + return FALSE; + } p_motion=FALSE; p_motion_begin_handler=NULL; @@ -249,33 +294,44 @@ bool ioncore_do_handle_buttonpress(XButtonEvent *ev) p_orig_y=p_y=ev->y_root; p_time=ev->time; p_clickcnt=0; - - watch_setup(&p_regwatch, (Obj*)reg, NULL); + p_area=area; - subreg=region_current(reg); - p_area=window_press((WWindow*)reg, ev, &subreg); + watch_setup(&p_regwatch, (Obj*)reg, NULL); if(subreg!=NULL) watch_setup(&p_subregwatch, (Obj*)subreg, NULL); - if(dblclick){ - pressbind=region_lookup_binding(reg, BINDING_BUTTONDBLCLICK, state, - button, p_area); - } - - if(pressbind==NULL){ - pressbind=region_lookup_binding(reg, BINDING_BUTTONPRESS, state, - button, p_area); - } - ioncore_grab_establish(reg, handle_key, pointer_grab_killed, 0); p_grabstate=ST_HELD; - call_button(pressbind, ev); + if(pressbind!=NULL) + call_button(pressbind, ev); return TRUE; } +bool ioncore_do_handle_buttonpress(XButtonEvent *ev) +{ + /* Only one level of subwindows is supported... more would require + * searching through the trees thanks to grabbed events being reported + * relative to the outermost grabbing window. + */ + if(ev->subwindow!=None && ev->state!=0){ + XButtonEvent ev2=*ev; + ev2.window=ev->subwindow; + ev2.subwindow=None; + if(XTranslateCoordinates(ioncore_g.dpy, ev->window, ev2.window, + ev->x, ev->y, &(ev2.x), &(ev2.y), + &(ev2.subwindow))){ + if(ioncore_dodo_handle_buttonpress(&ev2, TRUE)) + return TRUE; + } + } + + return ioncore_dodo_handle_buttonpress(ev, FALSE); +} + + bool ioncore_do_handle_buttonrelease(XButtonEvent *ev) { WBinding *binding=NULL; @@ -288,7 +344,8 @@ bool ioncore_do_handle_buttonrelease(XButtonEvent *ev) p_clickcnt=1; binding=region_lookup_binding(p_reg, BINDING_BUTTONCLICK, p_state, p_button, p_area); - call_button(binding, ev); + if(binding!=NULL) + call_button(binding, ev); }else{ call_motion_end(ev); } diff --git a/ioncore/return.c b/ioncore/return.c index 092483c..9ebabc5 100644 --- a/ioncore/return.c +++ b/ioncore/return.c @@ -155,3 +155,18 @@ void region_unset_return(WRegion *reg) /*}}}*/ + +/*{{{ Internal Lua exports */ + + +EXTL_SAFE +EXTL_EXPORT_MEMBER +WRegion *region___return_target(WRegion *reg) +{ + WPHolder *ph=region_get_return(reg); + return (ph!=NULL ? pholder_target(ph) : NULL); +} + + +/*}}}*/ + diff --git a/ioncore/saveload.c b/ioncore/saveload.c index db8a12f..c76c68e 100644 --- a/ioncore/saveload.c +++ b/ioncore/saveload.c @@ -35,8 +35,6 @@ static bool layout_load_error=FALSE; static SMAddCallback *add_cb; static SMCfgCallback *cfg_cb; -static SMPHolderCallback *ph_cb; -static bool clientwin_was_missing=FALSE; void ioncore_set_sm_callbacks(SMAddCallback *add, SMCfgCallback *cfg) @@ -53,26 +51,29 @@ void ioncore_get_sm_callbacks(SMAddCallback **add, SMCfgCallback **cfg) } -void ioncore_set_sm_pholder_callback(SMPHolderCallback *phcb) -{ - ph_cb=phcb; -} +/*}}}*/ -void ioncore_clientwin_load_missing() -{ - clientwin_was_missing=TRUE; -} +/*{{{ Load support functions */ -/*}}}*/ +static WPHolder **current_ph_p=NULL; -/*{{{ Load support functions */ +WPHolder *ioncore_get_load_pholder() +{ + if(current_ph_p==NULL){ + return NULL; + }else{ + WPHolder *ph=*current_ph_p; + *current_ph_p=NULL; + return ph; + } +} WRegion *create_region_load(WWindow *par, const WFitParams *fp, - ExtlTab tab) + ExtlTab tab, WPHolder **sm_ph_p) { char *objclass=NULL, *name=NULL; WRegionLoadCreateFn* fn=NULL; @@ -80,6 +81,7 @@ WRegion *create_region_load(WWindow *par, const WFitParams *fp, WRegion *reg=NULL; bool grouped=FALSE; char *grouped_name=NULL; + WPHolder **old_ph_p; if(!extl_table_gets_s(tab, "type", &objclass)) return NULL; @@ -100,19 +102,14 @@ WRegion *create_region_load(WWindow *par, const WFitParams *fp, free(objclass); - clientwin_was_missing=FALSE; + old_ph_p=current_ph_p; + current_ph_p=sm_ph_p; reg=fn(par, fp, tab); - if(reg==NULL){ - if(clientwin_was_missing && add_cb!=NULL && ph_cb!=NULL){ - WPHolder *ph=ph_cb(); - if(ph!=NULL){ - if(!add_cb(ph, tab)) - destroy_obj((Obj*)ph); - } - } - }else{ + current_ph_p=old_ph_p; + + if(reg!=NULL){ if(!OBJ_IS(reg, WClientWin)){ if(extl_table_gets_s(tab, "name", &name)){ region_set_name(reg, name); @@ -121,8 +118,6 @@ WRegion *create_region_load(WWindow *par, const WFitParams *fp, } } - ph_cb=NULL; - return reg; } diff --git a/ioncore/saveload.h b/ioncore/saveload.h index d15992e..587dfbf 100644 --- a/ioncore/saveload.h +++ b/ioncore/saveload.h @@ -14,9 +14,10 @@ #include "region.h" #include "screen.h" #include "pholder.h" +#include "attach.h" extern WRegion *create_region_load(WWindow *par, const WFitParams *fp, - ExtlTab tab); + ExtlTab tab, WPHolder **sm_ph_p); extern bool region_supports_save(WRegion *reg); DYNFUN ExtlTab region_get_configuration(WRegion *reg); @@ -29,12 +30,11 @@ extern bool ioncore_save_layout(); typedef bool SMAddCallback(WPHolder *ph, ExtlTab tab); typedef void SMCfgCallback(WClientWin *cwin, ExtlTab tab); -typedef WPHolder *SMPHolderCallback(); extern void ioncore_set_sm_callbacks(SMAddCallback *add, SMCfgCallback *cfg); extern void ioncore_get_sm_callbacks(SMAddCallback **add, SMCfgCallback **cfg); -extern void ioncore_set_sm_pholder_callback(SMPHolderCallback *phcb); -extern void ioncore_clientwin_load_missing(); + +extern WPHolder *ioncore_get_load_pholder(); #endif /* ION_IONCORE_SAVELOAD_H */ diff --git a/ioncore/tags.c b/ioncore/tags.c index 6f1e029..2343e9d 100644 --- a/ioncore/tags.c +++ b/ioncore/tags.c @@ -107,7 +107,8 @@ WRegion *ioncore_tagged_first(bool untag) /*EXTL_DOC * Iterate over tagged regions until \var{iterfn} returns \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE diff --git a/libextl/exact-version b/libextl/exact-version index 24226a2..2ea85eb 100644 --- a/libextl/exact-version +++ b/libextl/exact-version @@ -1,6 +1,13 @@ Context: +[Do not remove proxy from cache in object destroy watch handler. +Tuomo Valkonen **20071215143858 + The GC can remove it. Just have the pointer to the actual object be + zeroed. We may still want to find the proxy to pass the Lua side as + a key, although exported functions may not be called. +] + [Use S if not copy Tuomo Valkonen **20070506140705] diff --git a/libextl/private.h b/libextl/private.h index b0f576b..de9400e 100644 --- a/libextl/private.h +++ b/libextl/private.h @@ -82,7 +82,7 @@ typedef Watch ExtlProxy; #define EXTL_BEGIN_PROXY_OBJ(PROXY, OBJ) \ watch_init(PROXY); \ - watch_setup(PROXY, OBJ, obj_dest_handler); \ + watch_setup(PROXY, OBJ, NULL); \ (OBJ)->flags|=OBJ_EXTL_CACHED; #define EXTL_END_PROXY_OBJ(PROXY, OBJ) \ @@ -94,12 +94,13 @@ typedef Watch ExtlProxy; extern void extl_uncache(Obj *obj); +/* static void obj_dest_handler(Watch *watch, Obj *obj) { extl_uncache(obj); obj->flags&=~OBJ_EXTL_CACHED; } - +*/ /* * Miscellaneous. diff --git a/libtu/Makefile b/libtu/Makefile index 88b7a28..c614c60 100644 --- a/libtu/Makefile +++ b/libtu/Makefile @@ -12,7 +12,7 @@ CFLAGS += $(C89_SOURCE) $(POSIX_SOURCE) SOURCES=misc.c output.c util.c optparser.c parser.c tokenizer.c \ map.c obj.c objlist.c errorlog.c ptrlist.c rb.c \ - stringstore.c iterable.c setparam.c + stringstore.c iterable.c setparam.c prefix.c ifdef LIBTU_NO_ERRMSG DEFINES += -DLIBTU_NO_ERRMSG diff --git a/libtu/exact-version b/libtu/exact-version index 5adae39..825c172 100644 --- a/libtu/exact-version +++ b/libtu/exact-version @@ -1,6 +1,9 @@ Context: +[Added prefix stuff +Tuomo Valkonen **20071220180414] + [CF_NO_GETTEXT Tuomo Valkonen **20070620202409] diff --git a/libtu/prefix.c b/libtu/prefix.c new file mode 100644 index 0000000..676ae2e --- /dev/null +++ b/libtu/prefix.c @@ -0,0 +1,61 @@ +/* + * libtu/prefix.c + * + * Copyright (c) Tuomo Valkonen 1999-2007. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#include +#include "misc.h" +#include "locale.h" +#include "output.h" + +static char *the_prefix=NULL; + +void prefix_set(const char *binloc, const char *dflt) +{ + int i=strlen(binloc); + int j=strlen(dflt); + + if(binloc[0]!='/') + die(TR("This relocatable binary should be started with an absolute path.")); + + while(i>0 && j>0){ + if(binloc[i-1]!=dflt[j-1]) + break; + i--; + j--; + } + + the_prefix=scopyn(binloc, i); + +} + + +char *prefix_add(const char *s) +{ + if(the_prefix==NULL) + return scopy(s); + else + return scat3(the_prefix, "/", s); +} + + +bool prefix_wrap_simple(bool (*fn)(const char *s), const char *s) +{ + bool ret=FALSE; + + if(the_prefix==NULL){ + ret=fn(s); + }else{ + char *s2=prefix_add(s); + if(s2!=NULL){ + ret=fn(s2); + free(s2); + } + } + + return ret; +} diff --git a/libtu/prefix.h b/libtu/prefix.h new file mode 100644 index 0000000..d9d2f21 --- /dev/null +++ b/libtu/prefix.h @@ -0,0 +1,17 @@ +/* + * libtu/prefix.h + * + * Copyright (c) Tuomo Valkonen 1999-2007. + * + * You may distribute and modify this library under the terms of either + * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. + */ + +#ifndef _LIBTU_PREFIX_H +#define _LIBTU_PREFIX_H + +extern void prefix_set(const char *binloc, const char *dflt); +extern char *prefix_add(const char *s); +extern bool prefix_wrap_simple(bool (*fn)(const char *s), const char *s); + +#endif /* _LIBTU_PREFIX_H */ diff --git a/man/Makefile b/man/Makefile index ed81982..7dbcbab 100644 --- a/man/Makefile +++ b/man/Makefile @@ -18,7 +18,13 @@ TARGETS=ion3.1 $(foreach tr, $(TRANSLATIONS), ion3.$(tr).1) \ pwm3.1 $(foreach tr, $(TRANSLATIONS), pwm3.$(tr).1) \ $(WELCOME_TARGETS) -MKMAN=$(LUA) ../build/mkman.lua +MKMAN=$(LUA) ../build/mkman.lua $(MKMAN_DEFS) +MKMAN_DEFS=-D ETCDIR $(REL)$(ETCDIR) -D DOCDIR $(REL)$(DOCDIR) + +ifeq ($(RELOCATABLE),1) +REL="/..." +endif + NROFF=nroff -man -Tlatin1 #FILTERCRAP=perl -p -i -e 's/.\10//g' FILTERCRAP=$(LUA) -e 'io.write((string.gsub(io.read("*a"), ".\8", "")))' @@ -41,16 +47,16 @@ include $(TOPDIR)/build/rules.mk ###################################### ion3.1: ion3.in $(CONFIGS) - $(MKMAN) -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(CONFIGS) + $(MKMAN) -i $< -o $@ $(CONFIGS) pwm3.1: pwm3.in $(PWM_CONFIGS) - $(MKMAN) -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(PWM_CONFIGS) + $(MKMAN) -i $< -o $@ $(PWM_CONFIGS) ion3.%.1: ion3.%.in $(CONFIGS) ../po/%.po - $(MKMAN) -po ../po/$*.po -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(CONFIGS) + $(MKMAN) -po ../po/$*.po -i $< -o $@ $(CONFIGS) pwm3.%.1: pwm3.%.in $(PWM_CONFIGS) ../po/%.po - $(MKMAN) -po ../po/$*.po -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(PWM_CONFIGS) + $(MKMAN) -po ../po/$*.po -i $< -o $@ $(PWM_CONFIGS) welcome%txt: welcome%head ion3%1 (cat welcome$*head; \ diff --git a/mod_query/input.c b/mod_query/input.c index 2cf1f25..53efd3c 100644 --- a/mod_query/input.c +++ b/mod_query/input.c @@ -76,10 +76,14 @@ void input_refit(WInput *input) } -void input_fitrep(WInput *input, WWindow *par, const WFitParams *fp) +bool input_fitrep(WInput *input, WWindow *par, const WFitParams *fp) { + if(par!=NULL && !region_same_rootwin((WRegion*)input, (WRegion*)par)) + return FALSE; input->last_fp=*fp; input_do_refit(input, par); + + return TRUE; } diff --git a/mod_query/input.h b/mod_query/input.h index 3a39b17..e3d06e5 100644 --- a/mod_query/input.h +++ b/mod_query/input.h @@ -25,7 +25,7 @@ DECLCLASS(WInput){ extern bool input_init(WInput *input, WWindow *par, const WFitParams *fp); extern void input_deinit(WInput *input); -extern void input_fitrep(WInput *input, WWindow *par, const WFitParams *fp); +extern bool input_fitrep(WInput *input, WWindow *par, const WFitParams *fp); extern void input_refit(WInput *input); extern void input_cancel(WInput *input); extern bool input_rqclose(WInput *input); diff --git a/mod_query/main.c b/mod_query/main.c index a360378..2d46cd5 100644 --- a/mod_query/main.c +++ b/mod_query/main.c @@ -53,7 +53,8 @@ WBindmap *mod_query_wedln_bindmap=NULL; ModQueryConfig mod_query_config={ 250, TRUE, - FALSE + FALSE, + TRUE }; @@ -68,6 +69,8 @@ ModQueryConfig mod_query_config={ * in milliseconds (default: 250). \\ * \var{caseicompl} & (boolean) Turn some completions case-insensitive * (default: false). \\ + * \var{substrcompl} & (boolean) Complete on sub-strings in some cases + * (default: ftrue). \\ * \end{tabularx} */ EXTL_EXPORT @@ -77,6 +80,7 @@ void mod_query_set(ExtlTab tab) extl_table_gets_b(tab, "autoshowcompl", &c->autoshowcompl); extl_table_gets_b(tab, "caseicompl", &c->caseicompl); + extl_table_gets_b(tab, "substrcompl", &c->substrcompl); if(extl_table_gets_i(tab, "autoshowcompl_delay", &c->autoshowcompl_delay)){ @@ -96,8 +100,9 @@ ExtlTab mod_query_get() ExtlTab tab=extl_create_table(); extl_table_sets_b(tab, "autoshowcompl", c->autoshowcompl); - extl_table_sets_b(tab, "caseicompl", c->caseicompl); extl_table_sets_i(tab, "autoshowcompl_delay", c->autoshowcompl_delay); + extl_table_sets_b(tab, "caseicompl", c->caseicompl); + extl_table_sets_b(tab, "substrcompl", c->substrcompl); return tab; } diff --git a/mod_query/main.h b/mod_query/main.h index 2fd127f..f09b765 100644 --- a/mod_query/main.h +++ b/mod_query/main.h @@ -18,6 +18,7 @@ DECLSTRUCT(ModQueryConfig){ int autoshowcompl_delay; bool autoshowcompl; bool caseicompl; + bool substrcompl; }; diff --git a/mod_query/mod_query.lua b/mod_query/mod_query.lua index 15b03c2..f4913f3 100644 --- a/mod_query/mod_query.lua +++ b/mod_query/mod_query.lua @@ -324,6 +324,8 @@ end local function mk_completion_test(str, sub_ok, casei_ok) + local settings=mod_query.get() + if not str then return function(s) return true end end @@ -337,9 +339,10 @@ local function mk_completion_test(str, sub_ok, casei_ok) end end - local casei=(casei_ok and mod_query.get().caseicompl) + casei_ok=(casei_ok and settings.caseicompl) + sub_ok=(sub_ok and settings.substrcompl) - if not casei then + if not casei_ok then return mk(str, sub_ok) else local fn=mk(string.lower(str), sub_ok) @@ -931,7 +934,7 @@ function mod_query.complete_ssh(str) end local res = {} - local tst = mk_completion_test(host, true, false) + local tst = mk_completion_test(host, true, true) for _, v in ipairs(mod_query.ssh_completions) do if tst(v) then @@ -1212,8 +1215,7 @@ function mod_query.query_menu(mplex, sub, themenu, prompt) local ntab=xform_menu({}, menu, "") local function complete(str) - -- casei_ok false, because everything is already in lower case - return mod_query.complete_keys(ntab, str, true, false) + return mod_query.complete_keys(ntab, str, true, true) end local function handle(mplex, str) diff --git a/mod_statusbar/statusbar.c b/mod_statusbar/statusbar.c index c43d2b0..838fd98 100644 --- a/mod_statusbar/statusbar.c +++ b/mod_statusbar/statusbar.c @@ -635,7 +635,8 @@ bool statusbar_fitrep(WStatusBar *sb, WWindow *par, const WFitParams *fp) bool wchg=(REGION_GEOM(sb).w!=fp->g.w); bool hchg=(REGION_GEOM(sb).h!=fp->g.h); - window_do_fitrep(&(sb->wwin), par, &(fp->g)); + if(!window_fitrep(&(sb->wwin), par, fp)) + return FALSE; if(wchg || hchg){ statusbar_calculate_xs(sb); diff --git a/mod_tiling/tiling.c b/mod_tiling/tiling.c index b9d454c..8d9346a 100644 --- a/mod_tiling/tiling.c +++ b/mod_tiling/tiling.c @@ -478,7 +478,7 @@ bool tiling_managed_add_default(WTiling *ws, WRegion *reg) frame=OBJ_CAST(reg, WFrame); if(frame!=NULL){ - if(framemode_unalt(frame_mode(frame))==FRAME_MODE_TILED) + if(framemode_unalt(frame_mode(frame))!=FRAME_MODE_TILED) frame_set_mode(frame, FRAME_MODE_TILED); } @@ -1109,7 +1109,8 @@ WRegion *tiling_current(WTiling *ws) /*EXTL_DOC * Iterate over managed regions of \var{ws} until \var{iterfn} returns * \code{false}. - * The function itself returns \code{true} if it reaches the end of list + * The function is called in protected mode. + * This routine returns \code{true} if it reaches the end of list * without this happening. */ EXTL_SAFE diff --git a/pwm/Makefile b/pwm/Makefile index 0bfbed5..83f3100 100644 --- a/pwm/Makefile +++ b/pwm/Makefile @@ -42,7 +42,8 @@ EXT_OBJS += ../ioncore/ioncore.a DEFINES += -DETCDIR=\"$(ETCDIR)\" -DSHAREDIR=\"$(SHAREDIR)\" \ -DEXTRABINDIR=\"$(EXTRABINDIR)\" -DMODULEDIR=\"$(MODULEDIR)\" \ - -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" + -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" \ + -DPWM3_LOCATION=\"$(BINDIR)/pwm3\" ifndef PWM_ETCDIR PWM_ETCDIR = $(ETCDIR) diff --git a/pwm/pwm.c b/pwm/pwm.c index a96e306..178cf76 100644 --- a/pwm/pwm.c +++ b/pwm/pwm.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -93,20 +94,30 @@ int main(int argc, char*argv[]) char *efnam=NULL; bool may_continue=FALSE; bool noerrorlog=FALSE; - + char *localedir; + libtu_init(argv[0]); - if(!ioncore_init("pwm3", argc, argv, LOCALEDIR)) +#ifdef CF_RELOCATABLE + prefix_set(argv[0], PWM3_LOCATION); +#endif + + localedir=prefix_add(LOCALEDIR); + + if(!ioncore_init("pwm3", argc, argv, localedir)) return EXIT_FAILURE; - extl_add_searchdir(EXTRABINDIR); /* ion-completefile */ - extl_add_searchdir(MODULEDIR); - extl_add_searchdir(ETCDIR); + if(localedir!=NULL) + free(localedir); + + prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR); /* ion-completefile */ + prefix_wrap_simple(extl_add_searchdir, MODULEDIR); + prefix_wrap_simple(extl_add_searchdir, ETCDIR); #ifdef PWM_ETCDIR - extl_add_searchdir(PWM_ETCDIR); + prefix_wrap_simple(extl_add_searchdir, PWM_ETCDIR); #endif - extl_add_searchdir(SHAREDIR); - extl_add_searchdir(LCDIR); + prefix_wrap_simple(extl_add_searchdir, SHAREDIR); + prefix_wrap_simple(extl_add_searchdir, LCDIR); extl_set_userdirs("pwm3"); optparser_init(argc, argv, OPTP_MIDLONG, pwm_opts); diff --git a/system.mk b/system.mk index 8a0d53c..26ea7f7 100644 --- a/system.mk +++ b/system.mk @@ -2,13 +2,16 @@ ## System settings ## - ## ## Installation paths ## PREFIX=/usr/local +# For relocatable build, use the following, and start with absolute path. +# RELOCATABLE=1 +# PREFIX= + # Unless you are creating a package conforming to some OS's standards, you # probably do not want to modify the following directories: diff --git a/utils/ion-completeman.in b/utils/ion-completeman.in index cfcaade..135efaf 100644 --- a/utils/ion-completeman.in +++ b/utils/ion-completeman.in @@ -107,7 +107,9 @@ if test "x$HOME" != x; then usercache="$HOME/.ion3/mancache" fi -syscache="@VARDIR@/mancache" +vardir=${ION_VAR_PATH-@VARDIR@} +syscache="$vardir/mancache" + case "$action" in complete) @@ -134,7 +136,7 @@ case "$action" in fi ;; mksyscache) - mkdir -p "@VARDIR@" + mkdir -p "$vardir" scan > "$syscache" ;; esac diff --git a/utils/ion-statusd/Makefile b/utils/ion-statusd/Makefile index 1ed1ac9..3df31f9 100644 --- a/utils/ion-statusd/Makefile +++ b/utils/ion-statusd/Makefile @@ -14,8 +14,9 @@ CFLAGS += $(XOPEN_SOURCE) $(C99_SOURCE) DEFINES += -DETCDIR=\"$(ETCDIR)\" -DSHAREDIR=\"$(SHAREDIR)\" \ -DEXTRABINDIR=\"$(EXTRABINDIR)\" -DMODULEDIR=\"$(MODULEDIR)\" \ - -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" - + -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" \ + -DSTATUSD_LOCATION=\"$(EXTRABINDIR)/ion-statusd\" + SOURCES = ion-statusd.c exec.c extlrx.c TARGETS = ion-statusd diff --git a/utils/ion-statusd/ion-statusd.c b/utils/ion-statusd/ion-statusd.c index da9e432..5822fe6 100644 --- a/utils/ion-statusd/ion-statusd.c +++ b/utils/ion-statusd/ion-statusd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -159,16 +160,21 @@ int main(int argc, char*argv[]) configtab=extl_table_none(); libtu_init(argv[0]); - extl_init(); +#ifdef CF_RELOCATABLE + prefix_set(argv[0], STATUSD_LOCATION); +#endif + + extl_init(); + if(!statusd_register_exports()) return EXIT_FAILURE; - extl_add_searchdir(EXTRABINDIR); - extl_add_searchdir(MODULEDIR); - extl_add_searchdir(ETCDIR); - extl_add_searchdir(SHAREDIR); - extl_add_searchdir(LCDIR); + prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR); + prefix_wrap_simple(extl_add_searchdir, MODULEDIR); + prefix_wrap_simple(extl_add_searchdir, ETCDIR); + prefix_wrap_simple(extl_add_searchdir, SHAREDIR); + prefix_wrap_simple(extl_add_searchdir, LCDIR); extl_set_userdirs("ion3"); optparser_init(argc, argv, OPTP_MIDLONG, ion_opts); diff --git a/version.h b/version.h index 9c3629b..2317f10 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ -#define ION_VERSION "3rc-20071130" +#define ION_VERSION "3rc-20071220" #define ION_API_VERSION "3" -- 2.39.2