+2007-12-20 18:45 UTC Tuomo Valkonen <tuomov@iki.fi>
+ tagged ion-3rc-20071220
+
+2007-12-20 18:13 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Split relocation code into libtu
+
+2007-11-09 19:14 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Build hacks for relocatable binary
+
+2007-11-09 19:02 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Fixed textdomain setup in reloc. binary
+
+2007-11-09 15:56 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Support for relocatable package/binary
+
+2007-12-20 17:35 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Release notes
+
+2007-12-20 17:31 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Simplifications in definition of significant change
+
+2007-12-19 18:45 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Added missing checks for attempts of between-root reparenting.
+ (Stupid artificially restricted XReparentWindow.)
+
+2007-12-19 00:09 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Changed stacking level setting on detach
+
+2007-12-19 00:06 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * 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 <tuomov@iki.fi>
+ * 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 <tuomov@iki.fi>
+ * 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 <tuomov@iki.fi>
+ * Mention gettext in dependencies in README, etc.
+
+2007-12-14 20:27 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Added missing substrcompl option to mod_query.
+
+2007-12-14 20:08 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Simplify & comment
+
+2007-12-14 19:24 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Fixed and improved layout restore under session manager.
+
+2007-12-13 20:41 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * More placeholder fixes/improvs/simplifications
+
+2007-12-12 21:51 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Doc. details
+
+2007-12-12 18:29 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Handle placeholders in the mplex rescue code
+
+2007-12-12 18:20 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Removed unused stdisp_watch_handler
+
+2007-12-12 18:00 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Removed deprecated pholder_root stuff
+
+2007-12-11 20:38 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Removed generic placeholder redirects
+
+2007-12-07 10:18 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Fixed shape update on style change
+
+2007-12-07 10:18 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Size hints weren't appropriately set when shading non-shaped frames.
+
+2007-12-02 20:17 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Better language
+
+2007-12-01 17:46 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * 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 <tuomov@iki.fi>
+ tagged ion-3rc-20071130
+
+2007-11-29 19:48 UTC Tuomo Valkonen <tuomov@iki.fi>
+ 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 <tuomov@iki.fi>
+ * Oops, tilings were resetting frame modes incorrectly.
+ (Copy-paste...)
+
+2007-11-30 17:24 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Some release notes
+
+2007-11-29 19:48 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * 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-29 17:56 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Oops, ion-completeman preferred system over user cache.
+
+2007-11-28 00:33 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * edge_resistance wasn't dynamically configurable.
+
+2007-11-27 23:56 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * 'exec' ion-runinxterm
+ (Simple case that doesn't clutter the configs etc.; the rest can be
+ configured by those with crappy shells.)
+
+2007-11-27 23:48 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Snap to base size
+
+2007-11-27 23:32 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Size hint usage tuning
+
+2007-11-25 15:38 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Removed redundant settings from lookcommon_*
+
+2007-11-25 15:37 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Added the -alt bit to all frame modes for completeness.
+
+2007-11-25 12:30 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * typo fixes
+
+2007-11-25 12:09 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Frame mode change shape setting fix
+
+2007-11-25 11:52 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Added missing header
+
+2007-11-25 01:27 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * reorg
+
+2007-11-25 00:00 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * License intro clarifications
+
+2007-11-24 23:22 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Further license simplification
+
+2007-11-23 17:50 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Minor clarification
+
+2007-11-23 17:39 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Try to prevent EnterWindow event triggered focus change when switchto=false.
+
+2007-11-22 16:43 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Added some missing variable initialisations.
+
+2007-11-21 23:00 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Fixes/improvements to dockapp detection kludges on startup.
+
+2007-11-21 15:16 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Clarifications
+
+2007-11-20 18:28 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Clarified the full ancestry of de/fontset.c.
+ (That can also be seen by examining 'changeset 956'.)
+
+2007-11-18 09:56 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Don't try to store working dir of dead/nameless objects
+
+2007-11-16 22:22 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Do not complain when attempting to nil non-existent binding.
+
+2007-11-09 18:20 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Winprop matching hack fix (?)
+
+2007-11-09 18:03 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Lua-posix dir. checking support fixes.
+
+2007-11-09 17:50 UTC Tuomo Valkonen <tuomov@iki.fi>
+ * Improvements to mod_query 'cd' and 'pwd' override hacks
+
2007-11-09 14:47 UTC Tuomo Valkonen <tuomov@iki.fi>
tagged ion-3rc-20071109
Copyright (c) Tuomo Valkonen 1999-2007.
-The code of this project is "essentially" licensed under the LGPL, version
-2.1, unless otherwise indicated in components taken from elsewhere. It is
-reproduced below. Additionally, the following terms apply to the use of
-the name of the project, Ion(tm), names of particular "branches" such as
-Ion3(tm), and other derived names, in relation to this software, including
-derived works:
+Unless otherwise indicated in components taken from elsewhere, this software
+is licensed under the GNU Lesser General Public License, version 2.1 ("LGPL",
+reproduced below), extended and modified with the following terms:
If the name Ion(tm) or other names that can be associated with the Ion
project are used to distribute this software, then:
- A version that does not significantly differ from one of the
- original author's versions must be provided by default.
+ copyright holder's releases, must be provided by default.
- - When there are no further prominent notices of possible out-datedness,
- and no prominent original author's version qualifiers present (resp.
- only branch qualifier is present), then the version distributed online
- may not significantly differ from the original author's latest stable
- release (resp. latest release on the branch) within a reasonable delay
- (normally 28 days). The holders of physical distribution media must
- be provided ways to upgrade to the latest release within this delay.
+ - Versions not based on the copyright holder's latest release (on
+ the corresponding "branch", such as Ion3(tm)), must within 28 days
+ of this release, be prominently marked as (potentially) obsolete
+ and unsupported.
- Significantly altered versions may be provided only if the user
explicitly requests for those modifications to be applied, and
is prominently notified that the software is no longer considered
- the standard version, and is not supported by the original author.
+ the standard version, and is not supported by the copyright holder.
The version string displayed by the program must describe these
modifications and the "support void" status.
- Derived works that do not satisfy the above terms must be renamed so
- that they can not be associated with the Ion project, their executables
- must be given names that do not conflict with the original author's
- version, and this author may not be referred to for support.
+ Versions for which the above conditions are not satisfied, must be
+ renamed so that they can not be associated with the Ion project, their
+ executables must be given names that do not conflict with the copyright
+ holder's version, and neither the copyright holder nor the Ion project
+ may be referred to for support.
- Modules and other (standalone) extensions to Ion must also be named
- so that they can not be confused to be supported by the original
- author. If "Ion" occurs in the name, it must be in the form
- "Foo for Ion" instead of "Ion Foo", etc.
+ In the text of sections 0-2, 4-12, and 14-16 of the LGPL, "this License"
+ 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 take precedence over the LGPL.
- This name policy notice may not be altered, and must be included in
- any altered versions and binary redistributions. It may only be
- removed when using small portions of the code in unrelated projects.
+End of terms.
- The original author and the Ion project retain the same rights to
- your modifications that it would have under the LGPL or GPL without
- these or similar additional terms.
- If you fail to follow these terms, you lose the rights granted to
- you by the LGPL.
+Explanations
-Explanations:
+Trademarks: With the terms above primarily appealing to copyright law,
+should any of the indicated trademarks be found invalid, does not excuse
+you from the conditions imposed by those terms. The use of these names
+in contexts other than redistribution of this software and modifications,
+is outside the scope of the terms above, and governed by applicable
+trademark or other laws.
-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 author reserves the right to refine
-the definition of significant changes on a per-case basis. Please consult
-when in doubt.
+ With regard to modules and other extensions to Ion(tm), the permission
+ is hereby granted to use "Ion" as part of the name, provided that it
+ occurs in a form suggesting that the work is supported by neither the
+ copyright holder nor the Ion project: "Foo for Ion" instead of "Ion Foo",
+ etc.
+
+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 within a reasonable
-delay install the latest release of Ion3 (resp. the latest stable release),
-or prominently notify the user that the provided version is not or may not
-be the latest. The action `installpkg ion-3ds-20070318` may at any date
-install this particular mentioned release. Likewise, the action `installpkg
---support-void-featurex ion3` may apply additional patches to the latest
-Ion3, within the further constraints set above.
+`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
for i in $(DOCS); do \
$(INSTALL) -m $(DATA_MODE) $$i $(DOCDIR); \
done
+
+relocatable_build:
+ $(MAKE) RELOCATABLE=1 PREFIX=
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 <http://www.lua.org/>).
+ * GNU make <http://www.gnu.org/software/make/>
+ * Lua 5.1 <http://www.lua.org/>
+ * gettext <http://www.gnu.org/software/gettext/>
2. Edit `system.mk` to suit your system. Most GNU/Linux users should
need very few changes.
`utils/ion-completefile/ion-completefile.c` is based on editline, (c)
1992 Simmule Turner and Rich Salz. See the file for details.
-The code that `de/fontset.c` is based on was apparently originally
-written by Tomohiro Kubota; see
-<http://www.debian.org/doc/manuals/intro-i18n/ch-examples.en.html#s13.4.5>.
+The code that `de/fontset.c` is based on seems to have been originally
+written by Tomohiro Kubota, but see the file for details.
Various (minor) patches have been contributed by other individuals
unlisted here. See the mailing list archives and the darcs source
+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
+----------------
+
+This RC features various minor fixes, and some clarifications and
+simplifications to the license, which people seem to have had trouble
+understanding.
+
+
ion-3rc-20071109
----------------
## Some make rules
##
+ifdef RELOCATABLE
+DEFINES += -DCF_RELOCATABLE
+endif
+
ifdef MODULE
ifeq ($(PRELOAD_MODULES),1)
MODULE_TARGETS := $(MODULE).a $(MODULE).lc
*
* This file contains routines to attempt to add fonts to a font pattern
* so that XCreateFontSet will not fail because the given font(s) do not
- * contain all the characters required by the locale. The original code
- * was apparently written by Tomohiro Kubota; see
+ * contain all the characters required by the locale.
+ *
+ * The original code was apparently written by Tomohiro Kubota; see
* <http://www.debian.org/doc/manuals/intro-i18n/ch-examples.en.html#s13.4.5>.
- *
+ *
+ * However, the code that this file is based on, was taken from:
+ *
+ * Screen.cc for Blackbox - an X11 Window manager
+ * Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
+ * Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
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"),
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"),
+ }),
})
-- Case-insensitive completion? (Some queries only.)
caseicompl=true,
+
+ -- Sub-string completion? (Some queries only.)
+ caseicompl=true,
}
--]]
spacing = 1,
})
-de.defstyle("frame-tiled-alt", {
- bar = "none",
-})
+--de.defstyle("frame-tiled-alt", {
+-- bar = "none",
+--})
de.defstyle("frame-floating", {
- bar = "shaped",
+ --bar = "shaped",
padding_pixels = 0,
})
de.defstyle("frame-transient", {
- bar = "none",
+ --bar = "none",
padding_pixels = 0,
})
padding_pixels = 1,
})
-de.defstyle("frame-tiled-alt", {
- bar = "none",
-})
+--de.defstyle("frame-tiled-alt", {
+-- bar = "none",
+--})
de.defstyle("frame-floating", {
- bar = "shaped",
+ --bar = "shaped",
spacing = 0,
})
de.defstyle("frame-transient", {
- bar = "none",
+ --bar = "none",
spacing = 0,
})
Context:
-[TAG ion-3rc-20071109
-Tuomo Valkonen <tuomov@iki.fi>**20071109144719]
+[TAG ion-3rc-20071220
+Tuomo Valkonen <tuomov@iki.fi>**20071220184549]
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)
#include <libtu/util.h>
#include <libtu/optparser.h>
#include <libtu/errorlog.h>
+#include <libtu/prefix.h>
#include <libextl/readconfig.h>
#include <libmainloop/exec.h>
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);
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
/*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
}
-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);
}
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")){
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,
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{
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);
/*{{{ 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)
{
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;
}
binding->act!=BINDING_BUTTONMOTION)
return;
- if(binding->state==0)
+ if(binding->state==0 || binding->area!=0)
return;
#ifndef CF_HACK_IGNORE_EVIL_LOCKS
binding->act!=BINDING_BUTTONMOTION)
return;
- if(binding->state==0)
+ if(binding->state==0 || binding->area!=0)
return;
#ifndef CF_HACK_IGNORE_EVIL_LOCKS
INTRCLASS(WPHolder);
INTRCLASS(WMPlexPHolder);
INTRCLASS(WFramedPHolder);
+INTRCLASS(WGroupPHolder);
+INTRCLASS(WGroupedPHolder);
INTRSTRUCT(WStacking);
INTRSTRUCT(WLListNode);
param.dockapp=FALSE;
-again:
/* Is the window already being managed? */
cwin=XWINDOW_REGION_OF_T(win, WClientWin);
if(cwin!=NULL)
*/
xwindow_unmanaged_selectinput(win, StructureNotifyMask);
+ if(!XGetWindowAttributes(ioncore_g.dpy, win, &attr)){
+ if(maprq)
+ warn(TR("Window %#x disappeared."), win);
+ goto fail2;
+ }
/* Is it a dockapp?
*/
hints=XGetWMHints(ioncore_g.dpy, win);
-
- if(hints!=NULL && hints->flags&StateHint)
- init_state=hints->initial_state;
- if(!param.dockapp && init_state==WithdrawnState &&
- hints->flags&IconWindowHint && hints->icon_window!=None){
- /* The dockapp might be displaying its "main" window if no
- * wm that understands dockapps has been managing it.
- */
- if(!maprq)
- XUnmapWindow(ioncore_g.dpy, win);
-
- xwindow_unmanaged_selectinput(win, 0);
-
- /* Copy WM_CLASS as _ION_DOCKAPP_HACK */
- {
- char **p=NULL;
- int n=0;
-
- p=xwindow_get_text_property(win, XA_WM_CLASS, &n);
+ if(hints!=NULL){
+ if(hints->flags&StateHint)
+ init_state=hints->initial_state;
+
+ if(!param.dockapp && init_state==WithdrawnState &&
+ hints->flags&IconWindowHint && hints->icon_window!=None){
+ Window icon_win=hints->icon_window;
+ XWindowAttributes icon_attr;
- if(p!=NULL){
- xwindow_set_text_property(hints->icon_window,
- ioncore_g.atom_dockapp_hack,
- (const char **)p, n);
- XFreeStringList(p);
+ if(!XGetWindowAttributes(ioncore_g.dpy, icon_win, &icon_attr)){
+ if(maprq)
+ warn(TR("Window %#x disappeared."), win);
+ XFree((void*)hints);
+ goto fail2;
+ }
+
+ if(!maprq){
+ if(attr.map_state==IsViewable){
+ /* The dockapp might be displaying its "main" window if no
+ * wm that understands dockapps has been managing it.
+ */
+ XUnmapWindow(ioncore_g.dpy, win);
+ param.dockapp=TRUE;
+ }else{
+ /* Main window is unmapped on initial scan, but icon window
+ * is mapped. Let's hope it's a dockapp left by e.g. us.
+ */
+ if(icon_attr.map_state==IsViewable)
+ param.dockapp=TRUE;
+ }
}else{
- const char *pdummy[2]={"unknowndockapp", "UnknownDockapp"};
- xwindow_set_text_property(hints->icon_window,
- ioncore_g.atom_dockapp_hack,
- pdummy, 2);
+ param.dockapp=TRUE;
+ }
+
+ if(param.dockapp){
+ char **p=NULL;
+ int n=0;
+
+ xwindow_unmanaged_selectinput(win, 0);
+ xwindow_unmanaged_selectinput(icon_win, StructureNotifyMask);
+
+ win=icon_win;
+ attr=icon_attr;
+
+ /* Copy WM_CLASS as _ION_DOCKAPP_HACK */
+
+ p=xwindow_get_text_property(win, XA_WM_CLASS, &n);
+
+ if(p!=NULL){
+ xwindow_set_text_property(icon_win, ioncore_g.atom_dockapp_hack,
+ (const char **)p, n);
+ XFreeStringList(p);
+ }else{
+ const char *pdummy[2]={"unknowndockapp", "UnknownDockapp"};
+ xwindow_set_text_property(icon_win, ioncore_g.atom_dockapp_hack,
+ pdummy, 2);
+ }
}
}
- /* It is a dockapp, do everything again from the beginning, now
- * with the icon window.
- */
- win=hints->icon_window;
- param.dockapp=TRUE;
- goto again;
- }
-
- if(hints!=NULL)
XFree((void*)hints);
-
- if(!XGetWindowAttributes(ioncore_g.dpy, win, &attr)){
- if(maprq)
- warn(TR("Window %#x disappeared."), win);
- goto fail2;
}
- attr.width=maxof(attr.width, 1);
- attr.height=maxof(attr.height, 1);
-
/* Do we really want to manage it? */
if(!param.dockapp && (attr.override_redirect ||
(!maprq && attr.map_state!=IsViewable))){
goto fail2;
}
+ attr.width=maxof(attr.width, 1);
+ attr.height=maxof(attr.height, 1);
+
/* Find root window */
FOR_ALL_ROOTWINS(rootwin){
if(WROOTWIN_ROOT(rootwin)==attr.root)
}
+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;
&real_chkc);
if(!got_chkc || real_chkc!=chkc){
- ioncore_clientwin_load_missing();
+ do_sm(tab);
return NULL;
}
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."));
binding.func=func;
if(bindmap_remove_binding(bindmap, &binding))
return TRUE;
- warn(TR("Unable to remove binding %s."), str);
+ /*warn(TR("Unable to remove binding %s."), str);*/
}
return FALSE;
* \var{kbresize_t_min} & (integer) See below. \\
* \var{kbresize_step} & (floating point) See below. \\
* \var{kbresize_maxacc} & (floating point) See below. \\
+ * \var{edge_resistance} & (integer) Resize edge resistance in pixels. \\
* \var{framed_transients} & (boolean) Put transients in nested frames. \\
* \var{float_placement_method} & (string) How to place floating frames.
* One of \codestr{udlr} (up-down, then left-right),
* See the included file LICENSE for details.
*/
+#include <string.h>
+
#include <libtu/objp.h>
#include <libtu/setparam.h>
#include <libtu/minmax.h>
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);
*mode=FRAME_MODE_FLOATING;
- if(OBJ_IS(mplex, WFrame)
- && frame_mode((WFrame*)mplex)==FRAME_MODE_TRANSIENT){
- *mode=FRAME_MODE_TRANSIENT;
+ if(OBJ_IS(mplex, WFrame)){
+ WFrameMode mode2=frame_mode((WFrame*)mplex);
+ if(framemode_unalt(mode2)==FRAME_MODE_TRANSIENT)
+ *mode=mode2;
}
return (WRegion*)mplex;
/*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
*/
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)));
}
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);
GR_DEFATTR(not_dragged);
GR_DEFATTR(activity);
GR_DEFATTR(no_activity);
-GR_DEFATTR(quasiactive);
-GR_DEFATTR(not_quasiactive);
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;
}
}
+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];
#define CF_TAB_MAX_TEXT_X_OFF 10
-static void frame_shaped_recalc_bar_size(WFrame *frame)
+static void frame_shaped_recalc_bar_size(WFrame *frame, bool complete)
{
int bar_w=0, textw=0, tmaxw=frame->tab_min_w, tmp=0;
WLListIterTmp itmp;
bar_w=frame->bar_max_width_q*REGION_GEOM(frame).w;
}
- if(frame->bar_w!=bar_w){
+ if(complete || frame->bar_w!=bar_w){
frame->bar_w=bar_w;
frame_set_shape(frame);
}
}
-void frame_recalc_bar(WFrame *frame)
+void frame_recalc_bar(WFrame *frame, bool complete)
{
int textw, i;
WLListIterTmp tmp;
return;
if(frame->barmode==FRAME_BAR_SHAPED)
- frame_shaped_recalc_bar_size(frame);
+ frame_shaped_recalc_bar_size(frame, complete);
+ else if(complete)
+ frame_clear_shape(frame);
i=0;
void frame_brushes_updated(WFrame *frame)
{
- WFrameBarMode barmode=FRAME_BAR_INSIDE;
+ WFrameBarMode barmode;
ExtlTab tab;
char *s;
if(frame->brush==NULL)
return;
- if(frame->mode==FRAME_MODE_FLOATING)
+ if(frame->mode==FRAME_MODE_FLOATING){
barmode=FRAME_BAR_SHAPED;
- else if(frame->mode==FRAME_MODE_TRANSIENT)
- barmode=FRAME_BAR_NONE;
- else if(frame->mode==FRAME_MODE_TILED_ALT)
+ }else if(frame->mode==FRAME_MODE_TILED || frame->mode==FRAME_MODE_UNKNOWN ||
+ frame->mode==FRAME_MODE_TRANSIENT_ALT){
+ barmode=FRAME_BAR_INSIDE;
+ }else{
barmode=FRAME_BAR_NONE;
+ }
if(grbrush_get_extra(frame->brush, "bar", 's', &s)){
if(strcmp(s, "inside")==0)
region_updategr_default((WRegion*)frame);
mplex_fit_managed(&frame->mplex);
- frame_recalc_bar(frame);
+ frame_recalc_bar(frame, TRUE);
frame_set_background(frame, TRUE);
}
-StringIntMap frame_tab_styles[]={
+static StringIntMap frame_tab_styles[]={
+ {"tab-frame-unknown", FRAME_MODE_UNKNOWN},
+ {"tab-frame-unknown-alt", FRAME_MODE_UNKNOWN_ALT},
{"tab-frame-tiled", FRAME_MODE_TILED},
{"tab-frame-tiled-alt", FRAME_MODE_TILED_ALT},
{"tab-frame-floating", FRAME_MODE_FLOATING},
+ {"tab-frame-floating-alt", FRAME_MODE_FLOATING_ALT},
{"tab-frame-transient", FRAME_MODE_TRANSIENT},
+ {"tab-frame-transient-alt", FRAME_MODE_TRANSIENT_ALT},
END_STRINGINTMAP
};
}
-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));
- }
-}
-
-
/*}}}*/
extern void frame_draw(const WFrame *frame, bool complete);
extern void frame_draw_bar(const WFrame *frame, bool complete);
-extern void frame_recalc_bar(WFrame *frame);
+extern void frame_recalc_bar(WFrame *frame, bool complete);
extern void frame_bar_geom(const WFrame *frame, WRectangle *geom);
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);
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 */
WHook *frame_managed_changed_hook=NULL;
-#define IS_FLOATING_MODE(FRAME) \
- ((FRAME)->mode==FRAME_MODE_FLOATING || (FRAME)->mode==FRAME_MODE_TRANSIENT)
-#define FORWARD_CWIN_RQGEOM(FRAME) IS_FLOATING_MODE(FRAME)
-#define USE_MINMAX(FRAME) IS_FLOATING_MODE(FRAME)
-#define DEST_EMPTY(FRAME) IS_FLOATING_MODE(FRAME)
+#define FORWARD_CWIN_RQGEOM(FRAME) framemode_is_floating(frame_mode(FRAME))
+#define USE_MINMAX(FRAME) framemode_is_floating(frame_mode(FRAME))
+#define DEST_EMPTY(FRAME) framemode_is_floating(frame_mode(FRAME))
+
+
+WFrameMode framemode_unalt(WFrameMode mode)
+{
+ if(mode==FRAME_MODE_UNKNOWN_ALT)
+ return FRAME_MODE_UNKNOWN;
+ else if(mode==FRAME_MODE_TILED_ALT)
+ return FRAME_MODE_TILED;
+ else if(mode==FRAME_MODE_FLOATING_ALT)
+ return FRAME_MODE_FLOATING;
+ else if(mode==FRAME_MODE_TRANSIENT_ALT)
+ return FRAME_MODE_TRANSIENT;
+ else
+ return mode;
+}
+
+
+static WFrameMode framemode_is_floating(WFrameMode mode)
+{
+ WFrameMode modea=framemode_unalt(mode);
+
+ return (modea==FRAME_MODE_FLOATING || modea==FRAME_MODE_TRANSIENT);
+}
/*{{{ Destroy/create frame */
frame->mode=mode;
frame->tab_min_w=0;
frame->bar_max_width_q=1.0;
- frame->quasiact_source=NULL;
gr_stylespec_init(&frame->baseattr);
static void frame_add_mode_bindmaps(WFrame *frame)
{
- WFrameMode mode=frame->mode;
+ WFrameMode modea=framemode_unalt(frame->mode);
- if(mode==FRAME_MODE_FLOATING){
+ if(modea==FRAME_MODE_FLOATING){
region_add_bindmap((WRegion*)frame, ioncore_mplex_toplevel_bindmap);
region_add_bindmap((WRegion*)frame, ioncore_frame_toplevel_bindmap);
region_add_bindmap((WRegion*)frame, ioncore_frame_floating_bindmap);
- }else if(mode==FRAME_MODE_TRANSIENT){
+ }else if(modea==FRAME_MODE_TRANSIENT){
region_add_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap);
region_add_bindmap((WRegion*)frame, ioncore_frame_floating_bindmap);
}else{
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);
- frame_set_background(frame, TRUE);
+ frame_updategr(frame);
}
}
-StringIntMap frame_modes[]={
+static StringIntMap frame_modes[]={
{"unknown", FRAME_MODE_UNKNOWN},
+ {"unknown-alt", FRAME_MODE_UNKNOWN_ALT},
{"tiled", FRAME_MODE_TILED},
{"tiled-alt", FRAME_MODE_TILED_ALT},
{"floating", FRAME_MODE_FLOATING},
+ {"floating-alt", FRAME_MODE_FLOATING_ALT},
{"transient", FRAME_MODE_TRANSIENT},
+ {"transient-alt", FRAME_MODE_TRANSIENT_ALT},
END_STRINGINTMAP
};
/*EXTL_DOC
- * Set frame mode.
+ * Set frame mode (one of
+ * \codestr{unknown}, \codestr{tiled}, \codestr{floating}, \codestr{transient},
+ * or any of these suffixed with \codestr{-alt}).
*/
EXTL_EXPORT_AS(WFrame, set_mode)
bool frame_set_mode_extl(WFrame *frame, const char *modestr)
}
}
- frame_recalc_bar(frame);
+ frame_recalc_bar(frame, FALSE);
return TRUE;
}
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);
woff=maxof(REGION_GEOM(frame).w-subgeom.w, 0);
hoff=maxof(REGION_GEOM(frame).h-subgeom.h, 0);
- if(FRAME_CURRENT(frame)!=NULL){
+ if(FRAME_CURRENT(frame)!=NULL)
region_size_hints(FRAME_CURRENT(frame), hints_ret);
- if(!USE_MINMAX(frame)){
- hints_ret->max_set=0;
- hints_ret->min_set=0;
- /*hints_ret->base_set=0;*/
- hints_ret->aspect_set=0;
- hints_ret->no_constrain=FALSE;
- /*hints_ret->no_constrain=TRUE;*/
- }
- }else{
+ else
sizehints_clear(hints_ret);
- }
FRAME_MX_FOR_ALL(sub, frame, tmp){
sizehints_adjust_for(hints_ret, sub);
}
- if(!hints_ret->base_set){
- hints_ret->base_width=0;
- hints_ret->base_height=0;
- hints_ret->base_set=TRUE;
+ if(!USE_MINMAX(frame)){
+ hints_ret->max_set=0;
+ hints_ret->min_set=0;
+ /*hints_ret->base_set=0;*/
+ hints_ret->aspect_set=0;
+ hints_ret->no_constrain=FALSE;
+ /*hints_ret->no_constrain=TRUE;*/
}
-
+
if(!hints_ret->min_set){
hints_ret->min_width=0;
hints_ret->min_height=0;
hints_ret->min_set=TRUE;
}
+ if(!hints_ret->base_set){
+ hints_ret->base_width=0;
+ hints_ret->base_height=0;
+ hints_ret->base_set=TRUE;
+ }
+
hints_ret->base_width+=woff;
hints_ret->base_height+=hoff;
hints_ret->max_width+=woff;
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;
/*}}}*/
-/*{{{ 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 */
/*{{{ 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;
}
-
+
/*}}}*/
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;
how==ioncore_g.notifies.tag){
frame_update_attrs(frame);
- frame_recalc_bar(frame);
+ frame_recalc_bar(frame, FALSE);
frame_draw_bar(frame, FALSE);
}
}
int bar_w=frame->bar_w;
if(wchg)
- frame_recalc_bar(frame);
+ frame_recalc_bar(frame, TRUE);
if(frame->barmode==FRAME_BAR_SHAPED &&
((!wchg && hchg) || (wchg && bar_w==frame->bar_w))){
{
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
/* Transient manager searches should not cross tiled frames
* unless explicitly floated.
*/
- if(IS_FLOATING_MODE(frame) ||
+ if(framemode_is_floating(frame_mode(frame)) ||
extl_table_is_bool_set(transient->proptab, "float")){
return region_prepare_manage_transient_default((WRegion*)frame,
transient,
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;
}
FRAME_MODE_TILED,
FRAME_MODE_TILED_ALT,
FRAME_MODE_FLOATING,
- FRAME_MODE_TRANSIENT
+ FRAME_MODE_TRANSIENT,
+ FRAME_MODE_UNKNOWN_ALT,
+ FRAME_MODE_FLOATING_ALT,
+ FRAME_MODE_TRANSIENT_ALT
} WFrameMode;
typedef enum{
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);
extern WHook *frame_managed_changed_hook;
+extern WFrameMode framemode_unalt(WFrameMode mode);
+
#endif /* ION_IONCORE_FRAME_H */
ph->cont=cont;
ph->param=*param;
+ watch_init(&ph->frame_watch);
+
return TRUE;
}
}
pholder_deinit(&(ph->ph));
+ watch_reset(&ph->frame_watch);
}
typedef struct{
WRegionAttachData *data;
WFramedParam *param;
+ WRegion *reg_ret;
} AP;
reg=mplex_do_attach(&frame->mplex, &mp, ap->data);
+ ap->reg_ret=reg;
+
if(reg==NULL){
destroy_obj((Obj*)frame);
return NULL;
ap.data=data;
ap.param=param;
+ ap.reg_ret=NULL;
return fn(reg, fn_param, &data2);
}
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;
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;
}
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)));
}
{(DynFun*)pholder_do_target,
(DynFun*)framedpholder_do_target},
- {(DynFun*)pholder_do_root,
- (DynFun*)framedpholder_do_root},
+ {(DynFun*)pholder_stale,
+ (DynFun*)framedpholder_stale},
END_DYNFUNTAB
};
WPHolder ph;
WPHolder *cont;
WFramedParam param;
+ Watch frame_watch;
};
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);
#include "names.h"
#include "framedpholder.h"
#include "grouppholder.h"
+#include "return.h"
+#include "saveload.h"
#define DFLT_SZPLCY SIZEPOLICY_FREE_GLUE__SOUTH
if(st->reg!=NULL){
WFitParams fp;
-
+
+ fp.mode=0;
fp.g=REGION_GEOM(cwg);
sizepolicy(&st->szplcy, st->reg, NULL,
/*}}}*/
+/*{{{ 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 */
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;
}
{group_bottom_set,
groupcw_bottom_set},
+
+ {(DynFun*)region_rescue_clientwins,
+ (DynFun*)groupcw_rescue_clientwins},
END_DYNFUNTAB
};
#include "group-ws.h"
#include "group-cw.h"
#include "grouppholder.h"
-#include "groupedpholder.h"
#include "framedpholder.h"
#include "float-placement.h"
#include "resize.h"
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;
}
}
-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;
{(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},
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,
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;
}
+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);
+}
+
+
+
/*}}}*/
frame=OBJ_CAST(reg, WFrame);
if(frame!=NULL){
- WFrameMode m=frame_mode(frame);
- if(m==FRAME_MODE_TILED || m==FRAME_MODE_TILED_ALT)
+ if(framemode_unalt(frame_mode(frame))==FRAME_MODE_TILED)
frame_set_mode(frame, FRAME_MODE_FLOATING);
}
region_set_focus(st->reg);
else
ws->current_managed=st;
+ }else if(region_is_fully_mapped(reg)){
+ region_pointer_focus_hack(reg);
}
-
+
return TRUE;
}
+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){
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. */
stdisp->flags|=REGION_SKIP_FOCUS;
fp.g=REGION_GEOM(ws);
+ fp.mode=0;
+
sizepolicy(&ws->managed_stdisp->szplcy, stdisp, NULL, 0, &fp);
region_fitrep(stdisp, NULL, &fp);
fp.mode=REGION_FIT_EXACT;
}else{
fp.g=REGION_GEOM(ws);
+ fp.mode=0;
sizepolicy(&st->szplcy, reg, &rq->geom, rq->flags, &fp);
}
/*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
return tab;
}
-
+
void group_do_load(WGroup *ws, ExtlTab tab)
{
ExtlTab substab, subtab;
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);
}
}
{(DynFun*)region_managed_rqorder,
(DynFun*)group_managed_rqorder},
+
+ {(DynFun*)region_get_rescue_pholder_for,
+ (DynFun*)group_get_rescue_pholder_for},
END_DYNFUNTAB
};
#include <ioncore/rectangle.h>
#include <ioncore/pholder.h>
#include <ioncore/stacking.h>
-#include <ioncore/framedpholder.h>
INTRSTRUCT(WGroupAttachParams);
WStacking *current_managed;
WStacking *bottom;
Window dummywin;
+ WGroupPHolder *phs;
};
+++ /dev/null
-/*
- * ion/ioncore/groupedpholder.c
- *
- * Copyright (c) Tuomo Valkonen 2005-2007.
- *
- * See the included file LICENSE for details.
- */
-
-#include <libtu/objp.h>
-#include <libtu/obj.h>
-
-#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);
-
-
-/*}}}*/
-
+++ /dev/null
-/*
- * 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 */
#include <libtu/objp.h>
#include <libtu/obj.h>
#include <libtu/pointer.h>
+#include <libmainloop/defer.h>
#include <ioncore/common.h>
#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;
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?
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,
void grouppholder_deinit(WGroupPHolder *ph)
{
- watch_reset(&(ph->group_watch));
- watch_reset(&(ph->stack_above_watch));
+ grouppholder_do_unlink(ph);
+
pholder_deinit(&(ph->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);
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);
WRegion *grouppholder_do_target(WGroupPHolder *ph)
{
- return (WRegion*)ph->group_watch.obj;
+ return (WRegion*)ph->group;
}
#include <ioncore/pholder.h>
#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,
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 */
"Ion " ION_VERSION ", copyright (c) Tuomo Valkonen 1999-2007.";
static const char ioncore_license[]=DUMMY_TR(
- "This software is essentially licensed under the GNU Lesser General\n"
- "Public License (LGPL), version 2.1, unless otherwise indicated in\n"
- "components taken from elsewhere. Additional terms apply to the use\n"
- "of the name of the project, Ion(tm). For details, see the file\n"
- "LICENSE that you should have received with this software.\n"
+ "This software is licensed under the GNU Lesser General Public License\n"
+ "(LGPL), version 2.1, extended with terms applying to the use of the name\n"
+ "of the project, Ion(tm), unless otherwise indicated in components taken\n"
+ "from elsewhere. For details, see the file LICENSE that you should have\n"
+ "received with this software.\n"
"\n"
"This program is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
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);
dopath('ioncore_wd')
dopath('ioncore_menudb')
dopath('ioncore_tabnum')
+dopath('ioncore_quasiact')
-- Modifier setup compatibility kludge
local oldindex
--- /dev/null
+--
+-- 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)
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
- print('follow')
- return checkdir(d2)
- end
elseif t=="directory" then
return true
else
- return TR("Not a directory.")
+ return nil, TR("Not a directory.")
end
end
end
--DOC
-- Change default working directory for new programs started in \var{reg}.
function ioncore.chdir_for(reg, dir)
- assert(type(dir)=="string")
+ assert(dir==nil or type(dir)=="string")
if dir=="" or dir==nil then
dirs[reg]=nil
return true
local function lookup_runinxterm_warn(prog, title, wait)
local rx=lookup_script_warn("ion-runinxterm")
if rx then
+ rx="exec "..rx
if wait then
rx=rx.." -w"
end
local function save_config()
local t={}
for r, d in pairs(dirs) do
- t[r:name()]=d
+ local nm=obj_exists(r) and r:name()
+ if nm then
+ t[nm]=d
+ end
end
ioncore.write_savefile(savefile, t)
end
if p==nil then
return true
else
- return (p==(i and true))
- -- hack for nil
+ return (p==(i and true or false))
+ -- hack for nil i
end
end
static double accel=1, accelinc=30, accelmax=100*100;
static long actmax=200, uptmin=50;
static int resize_delay=CF_RESIZE_DELAY;
+/* Here to not have to write other set callback for resize code... */
+int ioncore_edge_resistance=CF_EDGE_RESISTANCE;
static void accel_reset()
void ioncore_set_moveres_accel(ExtlTab tab)
{
- int t_max, t_min, rd;
+ int t_max, t_min, rd, er;
double step, maxacc;
if(extl_table_gets_i(tab, "kbresize_t_max", &t_max))
accelmax=(maxacc>0 ? maxacc*maxacc : 1);
if(extl_table_gets_i(tab, "kbresize_delay", &rd))
resize_delay=maxof(0, rd);
+ if(extl_table_gets_i(tab, "edge_resistance", &er))
+ ioncore_edge_resistance=maxof(0, er);
}
extl_table_sets_d(tab, "kbresize_step", accelinc);
extl_table_sets_d(tab, "kbresize_maxacc", accelmax);
extl_table_sets_d(tab, "kbresize_delay", resize_delay);
+ extl_table_sets_i(tab, "edge_resistance", ioncore_edge_resistance);
}
}
+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)
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));
}
}
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);
#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) \
mplex->mx_list=NULL;
mplex->mx_current=NULL;
- mplex->mx_phs=NULL;
+ mplex->misc_phs=NULL;
mplex->mx_count=0;
mplex->mgd=NULL;
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);
/*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
/*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
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);
node=mplex_find_stacking(mplex, sub);
assert(node!=NULL);
-
+
+ fp.mode=0;
mplex_managed_geom(mplex, &fp.g);
-
+
sizepolicy(&node->szplcy, sub, &rq->geom, rq->flags, &fp);
if(geomret!=NULL)
if(!(param->flags&MPLEX_ATTACH_WHATEVER)){
WFitParams fp;
+ fp.mode=0;
mplex_managed_geom(mplex, &(fp.g));
sizepolicy(&node->szplcy, reg,
* client windows still..)
*/
mplex_refocus(mplex, NULL, FALSE);
+ }else if(!hidden){
+ region_pointer_focus_hack(reg);
}
+ }else if(!hidden){
+ region_pointer_focus_hack(reg);
}
if(lnode!=NULL)
}
+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,
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;
}
+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.
}
-
-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)
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);
}
data.type=REGION_ATTACH_LOAD;
data.u.tab=t;
-
+
stdisp=region_attach_helper((WRegion*)mplex,
(WWindow*)mplex, &fp,
do_attach_stdisp, NULL,
}
-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;
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);
}
int mx_count;
WLListNode *mx_current;
WLListNode *mx_list;
- WMPlexPHolder *mx_phs;
+ WMPlexPHolder *misc_phs;
Watch stdispwatch;
WMPlexSTDispInfo stdispinfo;
#include <libtu/objp.h>
#include <libtu/obj.h>
#include <libtu/pointer.h>
+#include <libmainloop/defer.h>
#include "common.h"
#include "mplex.h"
#include "basicpholder.h"
-static void mplex_watch_handler(Watch *watch, Obj *mplex);
-
-
/*{{{ Primitives */
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);
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;
/*{{{ 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)
{
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};
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;
}
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));
}
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);
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;
WRegionAttachData data2;
WFramedPHolder *fph;
WPHolder *root;
- WRegion *reg;
+ WRegion *frame;
RP rp;
rp.ph_head=get_head(ph);
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);
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;
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);
WRegion *mplexpholder_do_target(WMPlexPHolder *ph)
{
- WRegion *reg=(WRegion*)ph->mplex_watch.obj;
+ WRegion *reg=(WRegion*)ph->mplex;
if(reg!=NULL){
return reg;
}
-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));
}
}
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);
}
}
+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;
+ }
+}
+
+
/*}}}*/
{(DynFun*)pholder_do_target,
(DynFun*)mplexpholder_do_target},
- {(DynFun*)pholder_do_root,
- (DynFun*)mplexpholder_do_root},
+ {(DynFun*)pholder_stale,
+ (DynFun*)mplexpholder_stale},
END_DYNFUNTAB
};
DECLCLASS(WMPlexPHolder){
WPHolder ph;
- Watch mplex_watch;
+ WMPlex *mplex;
WFramedPHolder *recreate_pholder; /* only on first of list */
WLListNode *after;
WMPlexPHolder *next, *prev;
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);
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);
/*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
/*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
bool pholder_init(WPHolder *ph)
{
- ph->redirect=NULL;
return TRUE;
}
void pholder_deinit(WPHolder *ph)
{
- if(ph->redirect!=NULL)
- destroy_obj((Obj*)ph->redirect);
}
}
-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;
data.type=REGION_ATTACH_REPARENT;
data.u.reg=reg;
- return (pholder_attach_(ph, flags, &data)!=NULL);
+ return (pholder_do_attach(ph, flags, &data)!=NULL);
}
WRegion *pholder_target(WPHolder *ph)
{
- return (ph->redirect!=NULL
- ? pholder_target(ph->redirect)
- : pholder_do_target(ph));
+ return pholder_do_target(ph);
}
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);
}
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;
}
{(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
};
DECLCLASS(WPHolder){
Obj obj;
- WPHolder *redirect;
};
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);
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);
}
-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; i<n_acts; i++){
+ if(region_lookup_binding(reg, acts[i], state, button, area))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static bool ioncore_dodo_handle_buttonpress(XButtonEvent *ev, bool sub)
{
WBinding *pressbind=NULL;
WRegion *reg=NULL;
WRegion *subreg=NULL;
uint button, state;
bool dblclick;
+ int area;
state=ev->state;
button=ev->button;
if(reg==NULL)
return FALSE;
-
- if(ev->subwindow!=None){
- XButtonEvent ev2=*ev;
- ev2.window=ev->subwindow;
- if(XTranslateCoordinates(ioncore_g.dpy, ev->window, ev2.window,
- ev->x, ev->y, &(ev2.x), &(ev2.y),
- &(ev2.subwindow))){
- if(ioncore_do_handle_buttonpress(&ev2))
- return TRUE;
- }
- }
-
+
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;
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;
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);
}
#define XOR_RESIZE (!ioncore_g.opaque_resize)
+extern int ioncore_edge_resistance;
+
+
/*{{{ Size/position display and rubberband */
w=mode->geom.w;
h=mode->geom.h;
- if((mode->hints.inc_set) &&
- (mode->hints.width_inc>1 || mode->hints.height_inc>1)){
- if(mode->hints.base_set){
- w-=mode->hints.base_width;
- h-=mode->hints.base_height;
- }
- w/=mode->hints.width_inc;
- h/=mode->hints.height_inc;
+ if(mode->hints.base_set){
+ w=maxof(0, w-mode->hints.base_width);
+ h=maxof(0, h-mode->hints.base_height);
+ }
+
+ if(mode->hints.inc_set){
+ w/=maxof(1, mode->hints.width_inc);
+ h/=maxof(1, mode->hints.height_inc);
}
snprintf(buf, INFOWIN_BUFFER_LEN, "%dx%d", w, h);
if(mgr==(WRegion*)parent){
mode->snapgeom.x=0;
mode->snapgeom.y=0;
- mode->snap_enabled=FALSE;
- }else if(REGION_PARENT(mgr)==parent){
- mode->snap_enabled=TRUE;
+ /*mode->snap_enabled=FALSE;*/
}
+ mode->snap_enabled=TRUE;
}
if(!mode->hints.min_set || mode->hints.min_width<1)
}
+static int clamp_up(int t, int low, int high)
+{
+ return (t < high && t > low ? high : t);
+}
+
+
static void moveresmode_delta(WMoveresMode *mode,
int dx1, int dx2, int dy1, int dy2,
WRectangle *rret)
{
int realdx1, realdx2, realdy1, realdy2;
WRQGeomParams rq=RQGEOMPARAMS_INIT;
+ int er=ioncore_edge_resistance;
int w=0, h=0;
realdx1=(mode->dx1+=dx1);
/* snap */
if(mode->snap_enabled){
WRectangle *sg=&mode->snapgeom;
- int er=CF_EDGE_RESISTANCE;
if(mode->dx1!=0 && rq.geom.x+mode->dx1<sg->x && rq.geom.x+mode->dx1>sg->x-er)
realdx1=sg->x-rq.geom.x;
realdy2=sg->y+sg->h-rq.geom.y-rq.geom.h;
}
- w=mode->origgeom.w-realdx1+realdx2;
- h=mode->origgeom.h-realdy1+realdy2;
-
- if(w<=0)
- w=mode->hints.min_width;
- if(h<=0)
- h=mode->hints.min_height;
+ w=maxof(1, mode->origgeom.w-realdx1+realdx2);
+ h=maxof(1, mode->origgeom.h-realdy1+realdy2);
+
+ if(mode->snap_enabled && mode->hints.base_set){
+ w=clamp_up(w, mode->hints.base_width-er, mode->hints.base_width);
+ h=clamp_up(h, mode->hints.base_height-er, mode->hints.base_height);
+ }
+ /* Correct size */
sizehints_correct(&mode->hints, &w, &h, TRUE, TRUE);
/* Do not modify coordinates and sizes that were not requested to be
/*}}}*/
+
+/*{{{ 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);
+}
+
+
+/*}}}*/
+
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)
}
-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;
WRegion *reg=NULL;
bool grouped=FALSE;
char *grouped_name=NULL;
+ WPHolder **old_ph_p;
if(!extl_table_gets_s(tab, "type", &objclass))
return NULL;
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);
}
}
- ph_cb=NULL;
-
return reg;
}
#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);
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 */
/*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
Context:
+[Do not remove proxy from cache in object destroy watch handler.
+Tuomo Valkonen <tuomov@iki.fi>**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 <tuomov@iki.fi>**20070506140705]
#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) \
extern void extl_uncache(Obj *obj);
+/*
static void obj_dest_handler(Watch *watch, Obj *obj)
{
extl_uncache(obj);
obj->flags&=~OBJ_EXTL_CACHED;
}
-
+*/
/*
* Miscellaneous.
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
Context:
+[Added prefix stuff
+Tuomo Valkonen <tuomov@iki.fi>**20071220180414]
+
[CF_NO_GETTEXT
Tuomo Valkonen <tuomov@iki.fi>**20070620202409]
--- /dev/null
+/*
+ * 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 <string.h>
+#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;
+}
--- /dev/null
+/*
+ * 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 */
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", "")))'
######################################
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; \
}
-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;
}
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);
ModQueryConfig mod_query_config={
250,
TRUE,
- FALSE
+ FALSE,
+ TRUE
};
* 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
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)){
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;
}
int autoshowcompl_delay;
bool autoshowcompl;
bool caseicompl;
+ bool substrcompl;
};
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
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)
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
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)
-- See the included file LICENSE for details.
--
+local function simplify_path(path)
+ local npath=string.gsub(path, "([^/]+)/+%.%./+", "")
+ if npath~=path then
+ return simplify_path(npath)
+ else
+ return string.gsub(string.gsub(path, "([^/]+)/+%.%.$", ""), "/+", "/")
+ end
+end
+
+local function relative_path(path)
+ return not string.find(path, "^/")
+end
+
+local function empty_path(path)
+ return (not path or path=="")
+end
+
local function ws_chdir(mplex, params)
+ local nwd=params[1]
+
ws=assert(ioncore.find_manager(mplex, "WGroupWS"))
- local ok, err=ioncore.chdir_for(ws, params[1] or "")
+
+ if not empty_path(nwd) and relative_path(nwd) then
+ local owd=ioncore.get_dir_for(ws)
+ if empty_path(owd) then
+ owd=os.getenv("PWD")
+ end
+ if owd then
+ nwd=owd.."/"..nwd
+ end
+ end
+ local ok, err=ioncore.chdir_for(ws, nwd and simplify_path(nwd))
if not ok then
mod_query.warn(mplex, err)
end
end
local function ws_showdir(mplex, params)
- local dir=assert(ioncore.get_dir_for(mplex) or os.getenv("PWD"))
- mod_query.message(mplex, dir)
+ local dir=ioncore.get_dir_for(mplex)
+ if empty_path(dir) then
+ dir=os.getenv("PWD")
+ end
+ mod_query.message(mplex, dir or "(?)")
end
mod_query.defcmd("cd", ws_chdir)
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);
frame=OBJ_CAST(reg, WFrame);
if(frame!=NULL){
- WFrameMode mode=frame_mode(frame);
- if(mode!=FRAME_MODE_TILED && mode!=FRAME_MODE_TILED_ALT)
+ if(framemode_unalt(frame_mode(frame))!=FRAME_MODE_TILED)
frame_set_mode(frame, FRAME_MODE_TILED);
}
/*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
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)
#include <libtu/util.h>
#include <libtu/optparser.h>
#include <libtu/errorlog.h>
+#include <libtu/prefix.h>
#include <libextl/readconfig.h>
#include <libmainloop/exec.h>
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);
## 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:
usercache="$HOME/.ion3/mancache"
fi
-syscache="@VARDIR@/mancache"
+vardir=${ION_VAR_PATH-@VARDIR@}
+syscache="$vardir/mancache"
+
case "$action" in
complete)
if test "x$usercache" != x -a -f "$usercache"; then
cachefile="$usercache"
- fi
-
- if test -f "$syscache"; then
+ elif test -f "$syscache"; then
cachefile="$syscache"
fi
fi
;;
mksyscache)
- mkdir -p "@VARDIR@"
+ mkdir -p "$vardir"
scan > "$syscache"
;;
esac
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
#include <libtu/errorlog.h>
#include <libtu/locale.h>
#include <libtu/misc.h>
+#include <libtu/prefix.h>
#include <libextl/readconfig.h>
#include <libmainloop/select.h>
#include <libmainloop/signal.h>
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);
-#define ION_VERSION "3rc-20071109"
+#define ION_VERSION "3rc-20071220"
#define ION_API_VERSION "3"