]> git.decadent.org.uk Git - ion3.git/commitdiff
Merge commit '20071220' into HEAD
authorBen Hutchings <ben@decadent.org.uk>
Sun, 2 Nov 2008 12:43:57 +0000 (12:43 +0000)
committerBen Hutchings <ben@decadent.org.uk>
Sun, 2 Nov 2008 12:43:57 +0000 (12:43 +0000)
84 files changed:
ChangeLog
LICENSE
Makefile
README
RELNOTES
build/rules.mk
de/fontset.c
etc/cfg_ioncore.lua
etc/cfg_query.lua
etc/lookcommon_clean.lua
etc/lookcommon_emboss.lua
exact-version
ion/Makefile
ion/ion.c
ioncore/Makefile
ioncore/activity.c
ioncore/attach.c
ioncore/attach.h
ioncore/basicpholder.c
ioncore/binding.c
ioncore/classes.h
ioncore/clientwin.c
ioncore/conf-bindings.c
ioncore/conf.c
ioncore/detach.c
ioncore/focus.c
ioncore/focus.h
ioncore/frame-draw.c
ioncore/frame-draw.h
ioncore/frame.c
ioncore/frame.h
ioncore/framedpholder.c
ioncore/framedpholder.h
ioncore/group-cw.c
ioncore/group-ws.c
ioncore/group.c
ioncore/group.h
ioncore/groupedpholder.c [deleted file]
ioncore/groupedpholder.h [deleted file]
ioncore/grouppholder.c
ioncore/grouppholder.h
ioncore/ioncore.c
ioncore/ioncore_ext.lua
ioncore/ioncore_quasiact.lua [new file with mode: 0644]
ioncore/ioncore_wd.lua
ioncore/ioncore_winprops.lua
ioncore/kbresize.c
ioncore/manage.c
ioncore/manage.h
ioncore/mplex.c
ioncore/mplex.h
ioncore/mplexpholder.c
ioncore/mplexpholder.h
ioncore/names.c
ioncore/pholder.c
ioncore/pholder.h
ioncore/pointer.c
ioncore/resize.c
ioncore/return.c
ioncore/saveload.c
ioncore/saveload.h
ioncore/tags.c
libextl/exact-version
libextl/private.h
libtu/Makefile
libtu/exact-version
libtu/prefix.c [new file with mode: 0644]
libtu/prefix.h [new file with mode: 0644]
man/Makefile
mod_query/input.c
mod_query/input.h
mod_query/main.c
mod_query/main.h
mod_query/mod_query.lua
mod_query/mod_query_chdir.lua
mod_statusbar/statusbar.c
mod_tiling/tiling.c
pwm/Makefile
pwm/pwm.c
system.mk
utils/ion-completeman.in
utils/ion-statusd/Makefile
utils/ion-statusd/ion-statusd.c
version.h

index e73da79d78fd78a618ce600d34607e80e956b6b5..dee0e0b52b70f15e9c7f58b186cc022f57a20933 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,193 @@
+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
 
diff --git a/LICENSE b/LICENSE
index 576a773f17f3f5a3a1a01da0e2818e3e84ae82d3..21d506e8b4f24658988ea04b8b4813e03dbf8f59 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,75 +1,75 @@
 
 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
index 6f7c06a6342d74011ea84279a203dc85c42b6cdf..89562f8657dc9f77af1d3e491eb7b10fd9d1cbc3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -34,3 +34,6 @@ _install:
        for i in $(DOCS); do \
                $(INSTALL) -m $(DATA_MODE) $$i $(DOCDIR); \
        done
+
+relocatable_build:
+       $(MAKE) RELOCATABLE=1 PREFIX=
diff --git a/README b/README
index 226bbe43ef8ffa83c1d0a6142fafd2ec78d296ad..c588b958398ad47dfc567dc66c419eac6a3c4f0f 100644 (file)
--- a/README
+++ b/README
@@ -12,10 +12,12 @@ tuomov at iki.fi
 Building and installing
 -----------------------
 
-1. Make sure you have the following tools and libraries installed:
+1. Make sure you have the following tools and libraries installed (along
+   with, of course, standard X11 and libc stuff).
 
-    * GNU make
-    * Lua 5.1 (see <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.
@@ -114,9 +116,8 @@ The dock module was written by Tom Payne and Per Olofsson.
 `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 
index 0d09d47ff6b74a9b2b64d54097e13ea73cb38b5b..97c57e6da9f2ffc5c313fd40b77b150d6bdddc1d 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,4 +1,19 @@
 
+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
 ----------------
 
index b61e2f61b397d48a9daa870d145e29eaa13f85af..f4f18d1f261e0b88175759a482da7c796d477bad 100644 (file)
@@ -2,6 +2,10 @@
 ## Some make rules
 ##
 
+ifdef RELOCATABLE
+DEFINES += -DCF_RELOCATABLE
+endif
+
 ifdef MODULE
 ifeq ($(PRELOAD_MODULES),1)
 MODULE_TARGETS := $(MODULE).a $(MODULE).lc
index af164bef52f7860c66a0fb60ea00a342228437ff..37946e0cc04343d430ab7dafb91d74f6ddca6a54 100644 (file)
@@ -3,10 +3,34 @@
  * 
  * 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>
index a643e4416a4fc5cc5f116a0e4e03a182b8415f77..406cc1aae8def2730b518db83be6ee24bf9b22a1 100644 (file)
@@ -129,19 +129,9 @@ defbindings("WGroupCW", {
 defbindings("WMPlex", {
     bdoc("Close current object."),
     kpress_wait(META.."C", "WRegion.rqclose_propagate(_, _sub)"),
-    
-    submap(META.."K", {
-        bdoc("Detach (float) or reattach an object to its previous location."),
-        -- By using _chld instead of _sub, we can detach/reattach queries
-        -- attached to a group. The detach code checks if the parameter 
-        -- (_chld) is a group 'bottom' and detaches the whole group in that
-        -- case.
-        kpress("D", "ioncore.detach(_chld, 'toggle')", "_chld:non-nil"),
-    }),
 })
 
 -- Frames for transient windows ignore this bindmap
-
 defbindings("WMPlex.toplevel", {
     bdoc("Toggle tag of current object."),
     kpress(META.."T", "WRegion.set_tagged(_sub, 'toggle')", "_sub:non-nil"),
@@ -181,6 +171,15 @@ defbindings("WMPlex.toplevel", {
     bdoc("Display context menu."),
     --kpress(META.."M", "mod_menu.menu(_, _sub, 'ctxmenu')"),
     kpress(META.."M", "mod_query.query_menu(_, _sub, 'ctxmenu', 'Context menu:')"),
+    
+    submap(META.."K", {
+        bdoc("Detach (float) or reattach an object to its previous location."),
+        -- By using _chld instead of _sub, we can detach/reattach queries
+        -- attached to a group. The detach code checks if the parameter 
+        -- (_chld) is a group 'bottom' and detaches the whole group in that
+        -- case.
+        kpress("D", "ioncore.detach(_chld, 'toggle')", "_chld:non-nil"),
+    }),
 })
 
 
index 6abc8a52328c5fa355de8ba496a82f925867568b..0b1d75a3bbc41f121aaa55a12e7488bbeaff5700 100644 (file)
@@ -117,5 +117,8 @@ mod_query.set{
      
      -- Case-insensitive completion? (Some queries only.)
      caseicompl=true,
+     
+     -- Sub-string completion? (Some queries only.)
+     caseicompl=true,
 }
 --]]
index 6ffb7b45e0618ea8c1b14bd33eb96d8e4ba5f483..c2a8420abeb70f19271925c121bf57e8de0cc6bf 100644 (file)
@@ -19,17 +19,17 @@ de.defstyle("frame-tiled", {
     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,
 })
 
index b15de6a0dc423fcd169681de556cedde1d28cc85..f50935a12b61bc3f6dfaeb33b00eab4da68242ee 100644 (file)
@@ -25,17 +25,17 @@ de.defstyle("frame-tiled", {
     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,
 })
 
index 7d9d05643182f3ee93b6fc9952d7fda96d80a447..61cbfd3939a1837750d515b4a2b70f1602b3d551 100644 (file)
@@ -1,5 +1,5 @@
 
 Context:
 
-[TAG ion-3rc-20071109
-Tuomo Valkonen <tuomov@iki.fi>**20071109144719] 
+[TAG ion-3rc-20071220
+Tuomo Valkonen <tuomov@iki.fi>**20071220184549] 
index 823ab7ffc99a4175ef3f179205fb192e8bfef64d..1f1037ec07d5f49ccc1b6da0964eb22b8cc9c8f2 100644 (file)
@@ -40,7 +40,8 @@ EXT_OBJS += ../ioncore/ioncore.a
 
 DEFINES += -DETCDIR=\"$(ETCDIR)\" -DSHAREDIR=\"$(SHAREDIR)\" \
            -DEXTRABINDIR=\"$(EXTRABINDIR)\" -DMODULEDIR=\"$(MODULEDIR)\" \
-          -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\"
+          -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" \
+          -DION3_LOCATION=\"$(BINDIR)/ion3\"
 
 CFLAGS += $(XOPEN_SOURCE) $(C99_SOURCE)
 
index 9dc0c936f040e52af2442d34db21c3816291ab0f..23dce0cdc641541f686cb7ae7c332f821bf1086d 100644 (file)
--- a/ion/ion.c
+++ b/ion/ion.c
@@ -19,6 +19,7 @@
 #include <libtu/util.h>
 #include <libtu/optparser.h>
 #include <libtu/errorlog.h>
+#include <libtu/prefix.h>
 #include <libextl/readconfig.h>
 #include <libmainloop/exec.h>
 
@@ -146,17 +147,27 @@ int main(int argc, char*argv[])
     char *efnam=NULL;
     bool may_continue=FALSE;
     bool noerrorlog=FALSE;
+    char *localedir;
 
     libtu_init(argv[0]);
-
-    if(!ioncore_init("ion3", argc, argv, LOCALEDIR))
+    
+#ifdef CF_RELOCATABLE
+    prefix_set(argv[0], ION3_LOCATION);
+#endif
+    
+    localedir=prefix_add(LOCALEDIR);
+    
+    if(!ioncore_init("ion3", argc, argv, localedir))
         return EXIT_FAILURE;
+    
+    if(localedir!=NULL)
+        free(localedir);
 
-    extl_add_searchdir(EXTRABINDIR); /* ion-completefile */
-    extl_add_searchdir(MODULEDIR);
-    extl_add_searchdir(ETCDIR);
-    extl_add_searchdir(SHAREDIR);
-    extl_add_searchdir(LCDIR);
+    prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR); /* ion-completefile */
+    prefix_wrap_simple(extl_add_searchdir, MODULEDIR);
+    prefix_wrap_simple(extl_add_searchdir, ETCDIR);
+    prefix_wrap_simple(extl_add_searchdir, SHAREDIR);
+    prefix_wrap_simple(extl_add_searchdir, LCDIR);
     extl_set_userdirs("ion3");
 
     optparser_init(argc, argv, OPTP_MIDLONG, ion_opts);
index ccf7c36808439d17a0707f33bc4f5a3f83ad8ee9..de7529d459a659b6541df6740b0f400ff950806a 100644 (file)
@@ -23,13 +23,14 @@ SOURCES=binding.c conf-bindings.c cursor.c event.c exec.c focus.c         \
        kbresize.c rectangle.c xwindow.c presize.c extlrx.c               \
         pholder.c mplexpholder.c llist.c basicpholder.c sizepolicy.c      \
         stacking.c group.c grouppholder.c group-cw.c navi.c              \
-        group-ws.c float-placement.c groupedpholder.c framedpholder.c    \
+        group-ws.c float-placement.c framedpholder.c                      \
         return.c detach.c screen-notify.c
 
 LUA_SOURCES=\
        ioncore_ext.lua ioncore_luaext.lua ioncore_bindings.lua \
        ioncore_winprops.lua ioncore_misc.lua ioncore_efbb.lua \
-       ioncore_wd.lua ioncore_menudb.lua ioncore_tabnum.lua
+       ioncore_wd.lua ioncore_menudb.lua ioncore_tabnum.lua \
+       ioncore_quasiact.lua
 
 ifeq ($(PRELOAD_MODULES),1)
 CFLAGS += -DCF_PRELOAD_MODULES
index 25e2a5aba4587f4c91b9ac1e095d325bafbe9ee2..3eba697aee3eb67666d785f79b08da696c8cc640 100644 (file)
@@ -122,7 +122,8 @@ bool region_is_activity_r(WRegion *reg)
 
 /*EXTL_DOC
  * Iterate over activity list until \var{iterfn} returns \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
index 5d81222a97663e6a1e05eba06b183cb0b818c02b..52d09986b1fb71c2e481d552f859c4731f01e732 100644 (file)
@@ -116,10 +116,14 @@ static WRegion *doit_reparent(WRegion *mgr,
 }
 
 
-static WRegion *wrap_load(WWindow *par, const WFitParams *fp, 
-                          ExtlTab *tab)
+typedef struct{
+    ExtlTab tab;
+    WPHolder **sm_ph_p;
+} WLP;
+
+static WRegion *wrap_load(WWindow *par, const WFitParams *fp, WLP *p)
 {
-    return create_region_load(par, fp, *tab);
+    return create_region_load(par, fp, p->tab, p->sm_ph_p);
 }
 
 
@@ -129,11 +133,11 @@ WRegion *ioncore_newly_created=NULL;
 static WRegion *doit_load(WRegion *mgr,
                           WWindow *par, const WFitParams *fp,
                           WRegionDoAttachFn *cont, void *cont_param,
-                          ExtlTab tab)
+                          const WRegionAttachData *data)
 {
     WRegion *reg=NULL;
     
-    if(extl_table_gets_o(tab, "reg", (Obj**)&reg)){
+    if(extl_table_gets_o(data->u.tab, "reg", (Obj**)&reg)){
         if(!OBJ_IS(reg, WRegion))
             return FALSE;
     }/*else if(extl_table_is_bool_set(tab, "reg_use_new")){
@@ -145,11 +149,30 @@ static WRegion *doit_load(WRegion *mgr,
     if(reg!=NULL){
         return doit_reparent(mgr, par, fp, cont, cont_param, reg);
     }else{
+        WLP p;
+        p.tab=data->u.tab;
+        p.sm_ph_p=NULL;
+        
         return doit_new(mgr, par, fp, cont, cont_param,
-                        (WRegionCreateFn*)wrap_load, &tab);
+                        (WRegionCreateFn*)wrap_load, &p);
     }
 }
 
+
+WRegion *region_attach_load_helper(WRegion *mgr,
+                                   WWindow *par, const WFitParams *fp,
+                                   WRegionDoAttachFn *fn, void *fn_param,
+                                   ExtlTab tab, WPHolder **sm_ph)
+{
+    WLP p;
+    p.tab=tab;
+    p.sm_ph_p=sm_ph;
+    
+    return doit_new(mgr, par, fp, fn, fn_param,
+                    (WRegionCreateFn*)wrap_load, &p);
+}                                   
+
+
 WRegion *region_attach_helper(WRegion *mgr,
                               WWindow *par, const WFitParams *fp,
                               WRegionDoAttachFn *fn, void *fn_param,
@@ -159,7 +182,7 @@ WRegion *region_attach_helper(WRegion *mgr,
         return doit_new(mgr, par, fp, fn, fn_param, 
                         data->u.n.fn, data->u.n.param);
     }else if(data->type==REGION_ATTACH_LOAD){
-        return doit_load(mgr, par, fp, fn, fn_param, data->u.tab);
+        return doit_load(mgr, par, fp, fn, fn_param, data);
     }else if(data->type==REGION_ATTACH_REPARENT){
         return doit_reparent(mgr, par, fp, fn, fn_param, data->u.reg);
     }else{
index ec518ae397a724a621225f7871588c28dcd06f3a..ca144febeb678092ceb7cb6d7578496c301966e7 100644 (file)
@@ -51,6 +51,11 @@ extern WRegion *region_attach_helper(WRegion *mgr,
                                      WRegionDoAttachFn *fn, void *fn_param,
                                      const WRegionAttachData *data);
 
+extern WRegion *region_attach_load_helper(WRegion *mgr,
+                                          WWindow *par, const WFitParams *fp,
+                                          WRegionDoAttachFn *fn, void *fn_param,
+                                          ExtlTab tab, WPHolder **sm_ph);
+
 extern bool region_ancestor_check(WRegion *dst, WRegion *reg);
 
 extern void region_postdetach_dispose(WRegion *reg, WRegion *disposeroot);
index 77e863dd877199ebd7a030fc3bafac67defd802a..f4527814d6a4f08c82ea26022cd7f17914538398 100644 (file)
 /*{{{ Init/deinit */
 
 
-static void basicpholder_watch_handler(Watch *watch, Obj *reg)
-{
-    WBasicPHolder *ph=FIELD_TO_STRUCT(WBasicPHolder, reg_watch, watch);
-    pholder_redirect(&(ph->ph), (WRegion*)reg);
-}
-
-
 bool basicpholder_init(WBasicPHolder *ph, WRegion *reg, 
                        WBasicPHolderHandler *hnd)
 {
@@ -32,7 +25,7 @@ bool basicpholder_init(WBasicPHolder *ph, WRegion *reg,
 
     watch_init(&(ph->reg_watch));
     
-    if(!watch_setup(&(ph->reg_watch), (Obj*)reg, basicpholder_watch_handler)){
+    if(!watch_setup(&(ph->reg_watch), (Obj*)reg, NULL)){
         pholder_deinit(&(ph->ph));
         return FALSE;
     }
index 740e67baa6cf09dc862e0cebf60ef3a67449c478..cad47d334350c3761e1f6fb59acb943e2d29f76e 100644 (file)
@@ -381,7 +381,7 @@ void binding_grab_on(const WBinding *binding, Window win)
        binding->act!=BINDING_BUTTONMOTION)
         return;
     
-    if(binding->state==0)
+    if(binding->state==0 || binding->area!=0)
         return;
     
 #ifndef CF_HACK_IGNORE_EVIL_LOCKS
@@ -412,7 +412,7 @@ void binding_ungrab_on(const WBinding *binding, Window win)
        binding->act!=BINDING_BUTTONMOTION)
         return;
     
-    if(binding->state==0)
+    if(binding->state==0 || binding->area!=0)
         return;
 
 #ifndef CF_HACK_IGNORE_EVIL_LOCKS
index b1bce1b7a6d6b152f067439f3a40d7c59707a51f..58698a71614f1bded10b2252d8f46deb29f5bbfc 100644 (file)
@@ -31,6 +31,8 @@ INTRCLASS(WGroupWS);
 INTRCLASS(WPHolder);
 INTRCLASS(WMPlexPHolder);
 INTRCLASS(WFramedPHolder);
+INTRCLASS(WGroupPHolder);
+INTRCLASS(WGroupedPHolder);
 
 INTRSTRUCT(WStacking);
 INTRSTRUCT(WLListNode);
index 01a15d34b4018e0444498fa7780a2f2529562afc..1b85dfcf994c8e95ee0522452139869fa204d990 100644 (file)
@@ -448,7 +448,6 @@ WClientWin* ioncore_manage_clientwin(Window win, bool maprq)
 
     param.dockapp=FALSE;
     
-again:
     /* Is the window already being managed? */
     cwin=XWINDOW_REGION_OF_T(win, WClientWin);
     if(cwin!=NULL)
@@ -459,70 +458,88 @@ again:
      */
     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)
@@ -1302,6 +1319,25 @@ static ExtlTab clientwin_get_configuration(WClientWin *cwin)
 }
 
 
+static void do_sm(ExtlTab tab)
+{
+    SMAddCallback *add_cb;
+    SMCfgCallback *cfg_cb;
+    WPHolder *ph;
+    
+    ioncore_get_sm_callbacks(&add_cb, &cfg_cb);
+    
+    if(add_cb!=NULL){
+        ph=ioncore_get_load_pholder();
+    
+        if(ph!=NULL){
+            if(!add_cb(ph, tab))
+                destroy_obj((Obj*)ph);
+        }
+    }
+}
+
+    
 WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
 {
     double wind=0;
@@ -1328,7 +1364,7 @@ WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
                                           &real_chkc);
     
     if(!got_chkc || real_chkc!=chkc){
-        ioncore_clientwin_load_missing();
+        do_sm(tab);
         return NULL;
     }
 
@@ -1339,6 +1375,9 @@ WRegion *clientwin_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
         return NULL;
     }
     
+    if(attr.root!=region_root_of((WRegion*)par))
+        return NULL;
+        
     if(attr.override_redirect || 
        (ioncore_g.opmode==IONCORE_OPMODE_INIT && attr.map_state!=IsViewable)){
         warn(TR("Saved client window does not want to be managed."));
index c449a87cdbf740f3e4a69e1b80cca6dd9810d8ab..d745a0996806c96525c7e8b8c8b4cd6e778f494b 100644 (file)
@@ -185,7 +185,7 @@ static bool do_action(WBindmap *bindmap, const char *str,
         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;
index eb464cb83a55080e1a0746f3c90650252e2b4268..1656fc0224f523d00b2014e9e37936826009c9b6 100644 (file)
@@ -70,6 +70,7 @@ static ExtlFn get_layout_fn;
  *  \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), 
index 2d24fee42c70d7fc31db0200e30a6e01c5cbb717..8a866401f6d9009dd5f07d13265478ccc060c337 100644 (file)
@@ -6,6 +6,8 @@
  * See the included file LICENSE for details.
  */
 
+#include <string.h>
+
 #include <libtu/objp.h>
 #include <libtu/setparam.h>
 #include <libtu/minmax.h>
@@ -85,10 +87,13 @@ static bool ioncore_do_detach(WRegion *reg, WGroup *grp, WFrameMode framemode,
             ap.szplcy=st->szplcy;
             ap.szplcy_set=TRUE;
             
-            ap.level_set=TRUE;
-            ap.level=maxof(st->level, STACKING_LEVEL_NORMAL);
+            /*ap.level_set=TRUE;
+            ap.level=maxof(st->level, STACKING_LEVEL_NORMAL);*/
         }
         
+        ap.level_set=TRUE;
+        ap.level=framelevel+1;
+        
         ap.geom_set=TRUE;
         get_relative_geom(&ap.geom, reg, (WRegion*)grp);
         
@@ -115,9 +120,10 @@ static WRegion *check_mplex(WRegion *reg, WFrameMode *mode)
         
     *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;
index 573dcebb0203d334cc2a2dcdf455d44c36e8da5f..baada3eaca81915f12c512efa570f79749e92200 100644 (file)
@@ -101,7 +101,8 @@ WRegion *ioncore_goto_previous()
 
 /*EXTL_DOC
  * Iterate over focus history until \var{iterfn} returns \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_EXPORT
@@ -300,9 +301,10 @@ void region_lost_focus(WRegion *reg)
  */
 EXTL_SAFE
 EXTL_EXPORT_MEMBER
-bool region_is_active(WRegion *reg)
+bool region_is_active(WRegion *reg, bool pseudoact_ok)
 {
-    return REGION_IS_ACTIVE(reg);
+    return (REGION_IS_ACTIVE(reg) || 
+            (pseudoact_ok && REGION_IS_PSEUDOACTIVE(reg)));
 }
 
 
index 9f16415fcbd8cbd9ccbb448469c680b95ea8ed3e..fe0b12039ce820d809624a82cf77abb620b209c7 100644 (file)
@@ -41,7 +41,7 @@ extern void region_lost_focus(WRegion *reg);
 extern bool region_may_control_focus(WRegion *reg);
 
 /* Does reg have focus? */
-extern bool region_is_active(WRegion *reg);
+extern bool region_is_active(WRegion *reg, bool pseudoact_ok);
 
 /* Focus history */
 extern void region_focuslist_remove_with_mgrs(WRegion *reg);
index 0b3411a85b1e4e44407f89efe0a74faf909e667b..8591f2a254b3f84ca03fe99d4d5b6d76c51ad5a7 100644 (file)
@@ -42,8 +42,6 @@ GR_DEFATTR(dragged);
 GR_DEFATTR(not_dragged);
 GR_DEFATTR(activity);
 GR_DEFATTR(no_activity);
-GR_DEFATTR(quasiactive);
-GR_DEFATTR(not_quasiactive);
 
 
 static void ensure_create_attrs()
@@ -59,8 +57,6 @@ static void ensure_create_attrs()
     GR_ALLOCATTR(not_dragged);
     GR_ALLOCATTR(no_activity);
     GR_ALLOCATTR(activity);
-    GR_ALLOCATTR(quasiactive);
-    GR_ALLOCATTR(not_quasiactive);
     GR_ALLOCATTR_END;
 }
     
@@ -187,6 +183,22 @@ void frame_managed_geom(const WFrame *frame, WRectangle *geom)
 }
 
 
+int frame_shaded_height(const WFrame *frame)
+{
+    if(frame->barmode==FRAME_BAR_NONE){
+        return 0;
+    }else if(!BAR_INSIDE_BORDER(frame)){
+        return frame->bar_h;
+    }else {
+        GrBorderWidths bdw;
+        
+        grbrush_get_border_widths(frame->brush, &bdw);
+        
+        return frame->bar_h+bdw.top+bdw.bottom;
+    }
+}
+
+
 void frame_set_shape(WFrame *frame)
 {
     WRectangle gs[2];
@@ -214,7 +226,7 @@ void frame_clear_shape(WFrame *frame)
 #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;
@@ -268,7 +280,7 @@ static void frame_shaped_recalc_bar_size(WFrame *frame)
             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);
     }
@@ -290,7 +302,7 @@ static int init_title(WFrame *frame, int i)
 }
 
 
-void frame_recalc_bar(WFrame *frame)
+void frame_recalc_bar(WFrame *frame, bool complete)
 {
     int textw, i;
     WLListIterTmp tmp;
@@ -301,7 +313,9 @@ void frame_recalc_bar(WFrame *frame)
         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;
     
@@ -371,19 +385,21 @@ void frame_draw(const WFrame *frame, bool complete)
 
 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)
@@ -445,16 +461,20 @@ void frame_updategr(WFrame *frame)
     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
 };
 
@@ -570,21 +590,5 @@ void frame_activated(WFrame *frame)
 }
 
 
-void frame_quasiactivity_change(WFrame *frame)
-{
-    bool is=(frame->quasiact_source!=NULL);
-    
-    ensure_create_attrs();
-    
-    if(is){
-        gr_stylespec_set(&frame->baseattr, GR_ATTR(quasiactive));
-        gr_stylespec_unset(&frame->baseattr, GR_ATTR(not_quasiactive));
-    }else{
-        gr_stylespec_set(&frame->baseattr, GR_ATTR(not_quasiactive));
-        gr_stylespec_unset(&frame->baseattr, GR_ATTR(quasiactive));
-    }
-}
-
-
 /*}}}*/
 
index e286bc3fdb078c7fad2f78b942eb19bdacce8e4f..0acc21d4c64679ac0068b8786fa449325fd74346 100644 (file)
 
 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);
@@ -38,6 +39,5 @@ extern void frame_setup_dragwin_style(WFrame *frame, GrStyleSpec *spec, int tab)
 
 extern void frame_inactivated(WFrame *frame);
 extern void frame_activated(WFrame *frame);
-extern void frame_quasiactivity_change(WFrame *frame);
 
 #endif /* ION_IONCORE_FRAME_DRAW_H */
index 6937b3d21b27b20d70c234b21c20de07f9527d30..ee666bc2068500801d782ce7b46c5a92bb73ed87 100644 (file)
@@ -50,11 +50,32 @@ static void frame_add_mode_bindmaps(WFrame *frame);
 
 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 */
@@ -81,7 +102,6 @@ bool frame_init(WFrame *frame, WWindow *parent, const WFitParams *fp,
     frame->mode=mode;
     frame->tab_min_w=0;
     frame->bar_max_width_q=1.0;
-    frame->quasiact_source=NULL;
     
     gr_stylespec_init(&frame->baseattr);
     
@@ -130,13 +150,13 @@ void frame_deinit(WFrame *frame)
 
 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{
@@ -164,14 +184,10 @@ void frame_set_mode(WFrame *frame, WFrameMode mode)
     region_remove_bindmap((WRegion*)frame, ioncore_frame_transient_bindmap);
     
     frame->mode=mode;
-
-    frame_add_mode_bindmaps(frame);
     
-    frame_initialise_gr(frame);
+    frame_add_mode_bindmaps(frame);
     
-    mplex_fit_managed(&frame->mplex);
-    frame_recalc_bar(frame);
-    frame_set_background(frame, TRUE);
+    frame_updategr(frame);
 }
 
 
@@ -181,12 +197,15 @@ WFrameMode frame_mode(WFrame *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
 };
 
@@ -203,7 +222,9 @@ const char *frame_mode_extl(WFrame *frame)
 
 
 /*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)
@@ -386,7 +407,7 @@ static bool frame_initialise_titles(WFrame *frame)
         }
     }
     
-    frame_recalc_bar(frame);
+    frame_recalc_bar(frame, FALSE);
 
     return TRUE;
 }
@@ -406,7 +427,8 @@ bool frame_fitrep(WFrame *frame, WWindow *par, const WFitParams *fp)
     
     old_geom=REGION_GEOM(frame);
     
-    window_do_fitrep(&(frame->mplex.win), par, &(fp->g));
+    if(!window_fitrep(&(frame->mplex.win), par, fp))
+        return FALSE;
 
     mplex_managed_geom((WMPlex*)frame, &mg);
     
@@ -453,36 +475,36 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret)
     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;
@@ -490,13 +512,14 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret)
     hints_ret->min_width+=woff;
     hints_ret->min_height+=hoff;
     
-    if(frame->barmode==FRAME_BAR_SHAPED){
+    /* shaded */ {
         int f=frame->flags&(FRAME_SHADED|FRAME_SHADED_TOGGLE);
         
         if(f==FRAME_SHADED || f==FRAME_SHADED_TOGGLE){
-            hints_ret->min_height=frame->bar_h;
-            hints_ret->max_height=frame->bar_h;
-            hints_ret->base_height=frame->bar_h;
+            int h=frame_shaded_height(frame);
+            hints_ret->min_height=h;
+            hints_ret->max_height=h;
+            hints_ret->base_height=h;
             if(!hints_ret->max_set){
                 hints_ret->max_width=INT_MAX;
                 hints_ret->max_set=TRUE;
@@ -509,97 +532,6 @@ void frame_size_hints(WFrame *frame, WSizeHints *hints_ret)
 /*}}}*/
 
 
-/*{{{ Focus  */
-
-
-static void frame_quasiactivation(WFrame *frame, Obj *src, bool act)
-{
-    if(frame->quasiact_source==src || act){
-        bool was, is;
-        
-        was=(frame->quasiact_source!=NULL);
-    
-        frame->quasiact_source=(act ? src : NULL);
-    
-        is=(frame->quasiact_source!=NULL);
-        
-        if(was!=is){
-            frame_quasiactivity_change(frame);
-            if(!REGION_IS_ACTIVE(frame))
-                window_draw((WWindow*)frame, FALSE);
-        }
-    }
-}
-
-
-static bool actinact(WRegion *reg, bool act)
-{
-    WPHolder *returnph=region_get_return(reg);
-    WFrame *frame=NULL;
-    Obj *src=NULL;
-    WRegion *tgt;
-    
-    if(returnph==NULL || pholder_stale(returnph))
-        return FALSE;
-    
-    tgt=pholder_target(returnph);
-
-    frame=OBJ_CAST(tgt, WFrame);
-    
-    if(frame!=NULL){
-        src=(Obj*)returnph;
-    }else{
-        /* Show quasiactivation for stuff detached from
-         * groups contained in the frame as well.
-         */
-        WGroup *grp=OBJ_CAST(tgt, WGroup);
-        if(grp!=NULL){
-            frame=REGION_MANAGER_CHK(grp, WFrame);
-            src=(Obj*)grp;
-        }
-    }
-    
-    if(frame!=NULL)
-        frame_quasiactivation(frame, src, act);
-    
-    return TRUE;
-}
-
-
-static bool activated(WRegion *reg)
-{
-    return actinact(reg, TRUE);
-}
-
-
-static bool inactivated(WRegion *reg)
-{
-    return actinact(reg, FALSE);
-}
-
-
-void ioncore_frame_quasiactivation_notify(WRegion *reg, 
-                                          WRegionNotify how)
-{
-    if(how==ioncore_g.notifies.activated || 
-       how==ioncore_g.notifies.pseudoactivated){
-        activated(reg);
-    }else if(how==ioncore_g.notifies.inactivated ||
-             how==ioncore_g.notifies.pseudoinactivated){
-        inactivated(reg);
-    }else if(how==ioncore_g.notifies.set_return){
-        if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg))
-            activated(reg);
-    }else if(how==ioncore_g.notifies.unset_return){
-        if(REGION_IS_ACTIVE(reg) || REGION_IS_PSEUDOACTIVE(reg))
-            inactivated(reg);
-    }
-}
-
-
-/*}}}*/
-
-
 /*{{{ Client window rqgeom */
 
 
@@ -669,75 +601,78 @@ static void frame_managed_rqgeom_absolute(WFrame *frame, WRegion *sub,
 /*{{{ Frame recreate pholder stuff */
 
 
-static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame)
+static WFramedPHolder *frame_make_recreate_pholder(WFrame *frame, WPHolder *rph)
 {
-    WPHolder *ph;
-    WFramedPHolder *fph;
     WFramedParam fparam=FRAMEDPARAM_INIT;
+    WFramedPHolder *fph=NULL;
     
-    ph=region_make_return_pholder((WRegion*)frame);
-    
-    if(ph==NULL){
-        return NULL;
-    }
-    
-    fparam.mode=frame->mode;
+    if(rph!=NULL){
+        fparam.mode=frame->mode;
     
-    fph=create_framedpholder(ph, &fparam);
+        fph=create_framedpholder(rph, &fparam);
     
-    if(fph==NULL){
-        destroy_obj((Obj*)ph);
-        return NULL;
+        if(fph==NULL)
+            destroy_obj((Obj*)rph);
     }
     
     return fph;
 }
 
 
-static void mplex_flatten_phs(WMPlex *mplex)
+static void mplex_migrate_phs_to_fph(WMPlex *mplex, WFramedPHolder *fph)
 {
-    WLListNode *node;
-    WLListIterTmp tmp;
-
-    FOR_ALL_NODES_ON_LLIST(node, mplex->mx_list, tmp){
-        WMPlexPHolder *last=(mplex->mx_phs==NULL ? NULL : mplex->mx_phs->prev);
-        mplex_move_phs(mplex, node, last, NULL);
-    }
-}
-
-
-static void frame_modify_pholders(WFrame *frame)
-{
-    WFramedPHolder *fph;
     WMPlexPHolder *phs, *ph;
     
-    mplex_flatten_phs(&frame->mplex);
-    
-    if(frame->mplex.mx_phs==NULL)
-        return;
-    
-    fph=frame_make_recreate_pholder(frame);
-    
-    if(fph==NULL)
-        return;
-    
-    phs=frame->mplex.mx_phs;
-    frame->mplex.mx_phs=NULL;
+    phs=mplex->misc_phs;
+    mplex->misc_phs=NULL;
     
     phs->recreate_pholder=fph;
     
     for(ph=phs; ph!=NULL; ph=ph->next)
-        watch_reset(&ph->mplex_watch);
+        ph->mplex=NULL;
 }
 
 
+
 bool frame_rescue_clientwins(WFrame *frame, WRescueInfo *info)
 {
-    frame_modify_pholders(frame);
-    return mplex_rescue_clientwins(&frame->mplex, info);
+    bool ret;
+    
+    ret=mplex_rescue_clientwins(&frame->mplex, info);
+    
+    /* Now, do placeholders. 
+     * We can't currently be arsed to keep them ordered with regions...
+     * First we check if we can simply recreate this frame, which takes
+     * care of e.g. floating frames being destroyed when entering full
+     * screen mode. If not, we check if the target would be a WMPlex, and
+     * migrate there. This takes care of frames destroyed in tilings.
+     */
+    mplex_flatten_phs(&frame->mplex);
+    
+    if(frame->mplex.misc_phs!=NULL){
+        WPHolder *ret_ph=region_make_return_pholder((WRegion*)frame);
+        WFramedPHolder *fph=frame_make_recreate_pholder(frame, ret_ph);
+        
+        if(fph!=NULL){
+            mplex_migrate_phs_to_fph(&frame->mplex, fph);
+        }else{
+            WPHolder *rescueph=rescueinfo_pholder(info);
+            if(rescueph!=NULL){
+                WRegion *target=pholder_target(rescueph);
+                WMPlex *other_mplex=OBJ_CAST(target, WMPlex);
+                    
+                if(other_mplex!=NULL){
+                    assert(other_mplex!=&frame->mplex);
+                    mplex_migrate_phs(&frame->mplex, other_mplex);
+                }
+            }
+        }
+    }
+    
+    return ret;
 }
 
-    
+
 /*}}}*/
 
 
@@ -763,17 +698,9 @@ bool frame_set_shaded(WFrame *frame, int sp)
             return FALSE;
         rq.geom.h=frame->saved_h;
     }else{
-        if(frame->barmode==FRAME_BAR_NONE){
+        if(frame->barmode==FRAME_BAR_NONE)
             return FALSE;
-        }else if(frame->barmode==FRAME_BAR_SHAPED){
-            rq.geom.h=frame->bar_h;
-        }else{
-            WRectangle tmp;
-            
-            frame_border_inner_geom(frame, &tmp);
-            
-            rq.geom.h=rq.geom.h-tmp.h;
-        }
+        rq.geom.h=frame_shaded_height(frame);
     }
     
     frame->flags|=FRAME_SHADED_TOGGLE;
@@ -868,7 +795,7 @@ void frame_managed_notify(WFrame *frame, WRegion *sub, WRegionNotify how)
        how==ioncore_g.notifies.tag){
        
         frame_update_attrs(frame);
-        frame_recalc_bar(frame);
+        frame_recalc_bar(frame, FALSE);
         frame_draw_bar(frame, FALSE);
     }
 }
@@ -880,7 +807,7 @@ static void frame_size_changed_default(WFrame *frame,
     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))){
@@ -894,14 +821,6 @@ static void frame_managed_changed(WFrame *frame, int mode, bool sw,
 {
     bool need_draw=TRUE;
     
-    if(mode==MPLEX_CHANGE_REMOVE && (Obj*)reg==frame->quasiact_source){
-        /* Reset indirect quasiactivation through group that
-         * is being removed.
-         */
-        frame->quasiact_source=NULL;
-        frame_quasiactivity_change(frame);
-    }
-    
     if(mode!=MPLEX_CHANGE_SWITCHONLY)
         frame_initialise_titles(frame);
     else
@@ -953,7 +872,7 @@ WPHolder *frame_prepare_manage_transient(WFrame *frame,
     /* 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,
@@ -1028,6 +947,14 @@ WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
         frame_do_load(frame, tab);
     
     if(DEST_EMPTY(frame) && frame->mplex.mgd==NULL){
+        if(frame->mplex.misc_phs!=NULL){
+            /* Session management hack */
+            WFramedPHolder *fph;
+            fph=frame_make_recreate_pholder(frame, ioncore_get_load_pholder());
+            if(fph!=NULL)
+                mplex_migrate_phs_to_fph(&frame->mplex, fph);
+        }
+        
         destroy_obj((Obj*)frame);
         return NULL;
     }
index c8827a53791dcdc90679e91928156d77488af634..7d5da746a5bba82732c349031adaef9c38682b2d 100644 (file)
@@ -39,7 +39,10 @@ typedef enum{
     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{
@@ -116,15 +119,11 @@ extern int frame_default_index(WFrame *frame);
 extern void frame_managed_notify(WFrame *frame, WRegion *sub, WRegionNotify how);
 extern bool frame_managed_rqdispose(WFrame *frame, WRegion *reg);
 
-extern void ioncore_frame_quasiactivation_notify(WRegion *reg, WRegionNotify how);
-
 extern WPHolder *frame_prepare_manage_transient(WFrame *frame,
                                                 const WClientWin *transient,
                                                 const WManageParams *param,
                                                 int unused);
 
-extern bool frame_rescue_clientwins(WFrame *frame, WRescueInfo *info);
-
 /* Save/load */
 extern ExtlTab frame_get_configuration(WFrame *frame);
 extern WRegion *frame_load(WWindow *par, const WFitParams *fp, ExtlTab tab);
@@ -132,4 +131,6 @@ extern void frame_do_load(WFrame *frame, ExtlTab tab);
 
 extern WHook *frame_managed_changed_hook;
 
+extern WFrameMode framemode_unalt(WFrameMode mode);
+
 #endif /* ION_IONCORE_FRAME_H */
index de437a23c6921ae10cbd132f93697f7f0691ffc4..a2cd2c55fba55dfcaed7c090ff942c6f6b9343e9 100644 (file)
@@ -28,6 +28,8 @@ bool framedpholder_init(WFramedPHolder *ph, WPHolder *cont,
     ph->cont=cont;
     ph->param=*param;
     
+    watch_init(&ph->frame_watch);
+    
     return TRUE;
 }
  
@@ -47,6 +49,7 @@ void framedpholder_deinit(WFramedPHolder *ph)
     }
     
     pholder_deinit(&(ph->ph));
+    watch_reset(&ph->frame_watch);
 }
 
 
@@ -59,6 +62,7 @@ void framedpholder_deinit(WFramedPHolder *ph)
 typedef struct{
     WRegionAttachData *data;
     WFramedParam *param;
+    WRegion *reg_ret;
 } AP;
 
 
@@ -119,6 +123,8 @@ WRegion *framed_handler(WWindow *par,
 
     reg=mplex_do_attach(&frame->mplex, &mp, ap->data);
     
+    ap->reg_ret=reg;
+    
     if(reg==NULL){
         destroy_obj((Obj*)frame);
         return NULL;
@@ -143,6 +149,7 @@ WRegion *region_attach_framed(WRegion *reg, WFramedParam *param,
     
     ap.data=data;
     ap.param=param;
+    ap.reg_ret=NULL;
     
     return fn(reg, fn_param, &data2);
 }
@@ -152,8 +159,16 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags,
                                  WRegionAttachData *data)
 {
     WRegionAttachData data2;
+    WFrame *frame;
     AP ap;
     
+    frame=(WFrame*)ph->frame_watch.obj;
+    
+    if(frame!=NULL){
+        WMPlexAttachParams mp=MPLEXATTACHPARAMS_INIT;
+        return mplex_do_attach(&frame->mplex, &mp, data);
+    }
+    
     if(ph->cont==NULL)
         return FALSE;
 
@@ -163,8 +178,16 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags,
     
     ap.data=data;
     ap.param=&ph->param;
+    ap.reg_ret=NULL;
         
-    return pholder_do_attach(ph->cont, flags, &data2);
+    frame=(WFrame*)pholder_do_attach(ph->cont, flags, &data2);
+    
+    if(frame!=NULL){
+        assert(OBJ_IS(frame, WFrame));
+        watch_setup(&ph->frame_watch, (Obj*)frame, NULL);
+    }
+    
+    return ap.reg_ret;
 }
 
 
@@ -176,32 +199,34 @@ WRegion *framedpholder_do_attach(WFramedPHolder *ph, int flags,
 
 bool framedpholder_do_goto(WFramedPHolder *ph)
 {
-    return (ph->cont!=NULL
-            ? pholder_goto(ph->cont)
-            : FALSE);
+    WRegion *frame=(WRegion*)ph->frame_watch.obj;
+    
+    if(frame!=NULL)
+        return region_goto((WRegion*)frame);
+    else if(ph->cont!=NULL)
+        return pholder_goto(ph->cont);
+    else
+        return FALSE;
 }
 
 
 WRegion *framedpholder_do_target(WFramedPHolder *ph)
 {
-    return (ph->cont!=NULL
-            ? pholder_target(ph->cont)
-            : NULL);
+    WRegion *frame=(WRegion*)ph->frame_watch.obj;
+    
+    return (frame!=NULL
+            ? frame
+            : (ph->cont!=NULL
+               ? pholder_target(ph->cont)
+               : NULL));
 }
 
 
-WPHolder *framedpholder_do_root(WFramedPHolder *ph)
+bool framedpholder_stale(WFramedPHolder *ph)
 {
-    WPHolder *root;
-    
-    if(ph->cont==NULL)
-        return NULL;
-    
-    root=pholder_root(ph->cont);
+    WRegion *frame=(WRegion*)ph->frame_watch.obj;
     
-    return (root!=ph->cont 
-            ? root
-            : &ph->ph);
+    return (frame==NULL && (ph->cont==NULL || pholder_stale(ph->cont)));
 }
 
 
@@ -221,8 +246,8 @@ static DynFunTab framedpholder_dynfuntab[]={
     {(DynFun*)pholder_do_target, 
      (DynFun*)framedpholder_do_target},
      
-    {(DynFun*)pholder_do_root
-     (DynFun*)framedpholder_do_root},
+    {(DynFun*)pholder_stale
+     (DynFun*)framedpholder_stale},
     
     END_DYNFUNTAB
 };
index 49becc2389cc9ed567940cf634f394107eddb12f..43032b7289afa426ce06d25abc23308b9f63ec55 100644 (file)
@@ -32,6 +32,7 @@ DECLCLASS(WFramedPHolder){
     WPHolder ph;
     WPHolder *cont;
     WFramedParam param;
+    Watch frame_watch;
 };
 
 
@@ -45,7 +46,7 @@ extern void framedpholder_deinit(WFramedPHolder *ph);
 
 extern bool framedpholder_do_goto(WFramedPHolder *ph);
 
-extern WPHolder *framedpholder_do_root(WFramedPHolder *ph);
+extern bool framedpholder_stale(WFramedPHolder *ph);
 
 extern WRegion *framedpholder_do_target(WFramedPHolder *ph);
 
index 5a2a32d3ceda3377fe3a19f95a057363f612335a..d5b7396efbe476d2dc1c2f2f95f677a0e766598d 100644 (file)
@@ -22,6 +22,8 @@
 #include "names.h"
 #include "framedpholder.h"
 #include "grouppholder.h"
+#include "return.h"
+#include "saveload.h"
 
 
 #define DFLT_SZPLCY SIZEPOLICY_FREE_GLUE__SOUTH
@@ -163,7 +165,8 @@ void groupcw_toggle_transients_pos(WGroupCW *cwg)
         
         if(st->reg!=NULL){
             WFitParams fp;
-
+            
+            fp.mode=0;
             fp.g=REGION_GEOM(cwg);
             
             sizepolicy(&st->szplcy, st->reg, NULL, 
@@ -208,6 +211,46 @@ void groupcw_bottom_set(WGroupCW *cwg)
 /*}}}*/
 
 
+/*{{{ Rescue */
+
+
+static void group_migrate_phs_to_ph(WGroup *group, WPHolder *rph)
+{
+    WGroupPHolder *phs, *ph;
+    
+    phs=group->phs;
+    group->phs=NULL;
+    
+    phs->recreate_pholder=rph;
+    
+    for(ph=phs; ph!=NULL; ph=ph->next)
+        ph->group=NULL;
+}
+
+
+bool groupcw_rescue_clientwins(WGroupCW *cwg, WRescueInfo *info)
+{
+    bool ret=group_rescue_clientwins(&cwg->grp, info);
+    
+    /* If this group can be recreated, arrange remaining placeholders
+     * to do so. This takes care of e.g. recreating client window groups
+     * when recreating layout delayedly under a session manager.
+     */
+    if(cwg->grp.phs!=NULL){
+        WPHolder *rph=region_make_return_pholder((WRegion*)cwg);
+        
+        if(rph!=NULL)
+            group_migrate_phs_to_ph(&cwg->grp, rph);
+    }
+    
+    return ret;
+}
+
+
+/*}}}*/
+
+
+
 /*{{{ WGroupCW class */
 
 
@@ -238,34 +281,29 @@ void groupcw_deinit(WGroupCW *cwg)
 
 WRegion *groupcw_load(WWindow *par, const WFitParams *fp, ExtlTab tab)
 {
-    WGroupCW *ws;
+    WGroupCW *cwg;
     ExtlTab substab, subtab;
     int i, n;
     
-    ws=create_groupcw(par, fp);
+    cwg=create_groupcw(par, fp);
     
-    if(ws==NULL)
+    if(cwg==NULL)
         return NULL;
-        
-    if(!extl_table_gets_t(tab, "managed", &substab))
-        return (WRegion*)ws;
-
-    n=extl_table_get_n(substab);
-    for(i=1; i<=n; i++){
-        if(extl_table_geti_t(substab, i, &subtab)){
-            group_attach_new(&ws->grp, subtab);
-            extl_unref_table(subtab);
-        }
-    }
-    
-    extl_unref_table(substab);
+
+    group_do_load(&cwg->grp, tab);
     
-    if(ws->grp.managed_list==NULL){
-        destroy_obj((Obj*)ws);
+    if(cwg->grp.managed_list==NULL){
+        if(cwg->grp.phs!=NULL){
+            /* Session management hack */
+            WPHolder *ph=ioncore_get_load_pholder();
+            if(ph!=NULL)
+                group_migrate_phs_to_ph(&cwg->grp, ph);
+        }
+        destroy_obj((Obj*)cwg);
         return NULL;
     }
 
-    return (WRegion*)ws;
+    return (WRegion*)cwg;
 }
 
 
@@ -306,6 +344,9 @@ static DynFunTab groupcw_dynfuntab[]={
      
     {group_bottom_set,
      groupcw_bottom_set},
+     
+    {(DynFun*)region_rescue_clientwins,
+     (DynFun*)groupcw_rescue_clientwins},
     
     END_DYNFUNTAB
 };
index 3fd8cb765bd30577781dc8d57a736cf204a663a1..c12d8ec905242c2f2af097fe0b25c71d5c1de801 100644 (file)
@@ -22,7 +22,6 @@
 #include "group-ws.h"
 #include "group-cw.h"
 #include "grouppholder.h"
-#include "groupedpholder.h"
 #include "framedpholder.h"
 #include "float-placement.h"
 #include "resize.h"
@@ -171,8 +170,21 @@ static WPHolder *groupws_do_prepare_manage(WGroupWS *ws,
     if(ph!=NULL)
         ph=pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
     
-    if(ph!=NULL)
-        ph=pholder_either((WPHolder*)create_groupedpholder((WPHolder*)ph), ph);
+    if(ph!=NULL){
+        WGroupPHolder *gph;
+        WGroupAttachParams gp=GROUPATTACHPARAMS_INIT;
+        
+        gp.switchto_set=1;
+        gp.switchto=1;
+        gp.bottom=1;
+        
+        gph=create_grouppholder(NULL, NULL, &gp);
+        
+        if(gph!=NULL){
+            gph->recreate_pholder=ph;
+            return (WPHolder*)gph;
+        }
+    }
     
     return ph;
 }
@@ -256,27 +268,6 @@ WPHolder *groupws_prepare_manage_transient(WGroupWS *ws, const WClientWin *cwin,
 }
 
 
-WPHolder *groupws_get_rescue_pholder_for(WGroupWS *ws, 
-                                         WRegion *forwhat)
-{
-    WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
-    WFramedParam fp=FRAMEDPARAM_INIT;
-    WPHolder *ph;
-    
-    ap.geom_set=TRUE;
-    ap.geom=REGION_GEOM(forwhat);
-
-    ap.geom_weak_set=1;
-    ap.geom_weak=(REGION_PARENT(forwhat)!=REGION_PARENT(ws)
-                  ? REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y
-                  : 0);
-
-    ph=(WPHolder*)create_grouppholder(&ws->grp, NULL, &ap);
-    
-    return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
-}
-
-
 static bool group_empty_for_bottom_stdisp(WGroup *ws)
 {
     WGroupIterTmp tmp;
@@ -364,9 +355,6 @@ static DynFunTab groupws_dynfuntab[]={
     {(DynFun*)region_handle_drop,
      (DynFun*)groupws_handle_drop},
     
-    {(DynFun*)region_get_rescue_pholder_for,
-     (DynFun*)groupws_get_rescue_pholder_for},
-    
     {region_manage_stdisp,
      group_manage_stdisp},
     
index e39b20241f3e3b45a4e643a92fcd8c2297944b6c..886913f5a58f154808880c93252a67f6fe80b528 100644 (file)
@@ -356,6 +356,7 @@ bool group_init(WGroup *ws, WWindow *par, const WFitParams *fp)
     ws->managed_stdisp=NULL;
     ws->bottom=NULL;
     ws->managed_list=NULL;
+    ws->phs=NULL;
     
     ws->dummywin=XCreateWindow(ioncore_g.dpy, par->win,
                                 fp->g.x, fp->g.y, 1, 1, 0,
@@ -406,12 +407,14 @@ void group_deinit(WGroup *ws)
     XDeleteContext(ioncore_g.dpy, ws->dummywin, ioncore_g.win_context);
     XDestroyWindow(ioncore_g.dpy, ws->dummywin);
     ws->dummywin=None;
-
+    
+    while(ws->phs!=NULL)
+        grouppholder_do_unlink(ws->phs);
+    
     region_deinit(&ws->reg);
 }
 
 
-    
 bool group_rescue_clientwins(WGroup *ws, WRescueInfo *info)
 {
     WGroupIterTmp tmp;
@@ -424,6 +427,39 @@ bool group_rescue_clientwins(WGroup *ws, WRescueInfo *info)
 }
 
 
+WPHolder *group_get_rescue_pholder_for(WGroup *ws, 
+                                       WRegion *forwhat)
+{
+    WGroupAttachParams ap=GROUPATTACHPARAMS_INIT;
+    WFramedParam fp=FRAMEDPARAM_INIT;
+    WPHolder *ph;
+    
+    ap.geom_set=TRUE;
+    ap.geom=REGION_GEOM(forwhat);
+
+    ap.geom_weak_set=1;
+    
+    if(REGION_PARENT(forwhat)==REGION_PARENT(ws)){
+        ap.geom.x-=REGION_GEOM(ws).x;
+        ap.geom.y-=REGION_GEOM(ws).y;
+    }else{
+        ap.geom_weak=REGION_RQGEOM_WEAK_X|REGION_RQGEOM_WEAK_Y;
+    }
+    
+    /* frame mode */
+    /*{
+        WFrame *frame=OBJ_CAST(forwhat, WFrame);
+        if(frame!=NULL)
+            fp.mode=frame->mode;
+    }*/
+    
+    ph=(WPHolder*)create_grouppholder(ws, NULL, &ap);
+    
+    return pholder_either((WPHolder*)create_framedpholder(ph, &fp), ph);
+}
+
+
+
 /*}}}*/
 
 
@@ -531,8 +567,7 @@ WStacking *group_do_add_managed_default(WGroup *ws, WRegion *reg, int level,
     
     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);
     }
 
@@ -662,18 +697,32 @@ bool group_do_attach_final(WGroup *ws,
             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, &param->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){
@@ -681,18 +730,9 @@ WRegion *group_do_attach(WGroup *ws,
         return NULL;
     }
     
-    par=REGION_PARENT(ws);
-    assert(par!=NULL);
-
-    if(param->geom_set){
-        geom_group_to_parent(ws, &param->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. */
@@ -897,6 +937,8 @@ void group_manage_stdisp(WGroup *ws, WRegion *stdisp,
     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);
@@ -935,6 +977,7 @@ void group_managed_rqgeom(WGroup *ws, WRegion *reg,
         fp.mode=REGION_FIT_EXACT;
     }else{
         fp.g=REGION_GEOM(ws);
+        fp.mode=0;
         sizepolicy(&st->szplcy, reg, &rq->geom, rq->flags, &fp);
     }
     
@@ -1171,7 +1214,8 @@ bool group_managed_rqorder(WGroup *grp, WRegion *reg, WRegionOrder order)
 /*EXTL_DOC
  * Iterate over managed regions of \var{ws} until \var{iterfn} returns
  * \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
@@ -1291,7 +1335,7 @@ static ExtlTab group_get_configuration(WGroup *ws)
     return tab;
 }
 
-
+    
 void group_do_load(WGroup *ws, ExtlTab tab)
 {
     ExtlTab substab, subtab;
@@ -1301,7 +1345,23 @@ void group_do_load(WGroup *ws, ExtlTab tab)
         n=extl_table_get_n(substab);
         for(i=1; i<=n; i++){
             if(extl_table_geti_t(substab, i, &subtab)){
-                group_attach_new(ws, subtab);
+                WGroupAttachParams par=GROUPATTACHPARAMS_INIT;
+                WRegionAttachData data;
+                WFitParams fp;
+                WPHolder *ph;
+                
+                group_get_attach_params(ws, subtab, &par);
+                group_attach_fp(ws, &par, &fp);
+                
+                ph=(WPHolder*)create_grouppholder(ws, NULL, &par);
+                
+                region_attach_load_helper((WRegion*)ws, REGION_PARENT(ws), &fp,
+                                          (WRegionDoAttachFn*)group_do_attach_final,
+                                          (void*)&par, subtab, &ph);
+                                              
+                if(ph!=NULL)
+                    destroy_obj((Obj*)ph);
+                
                 extl_unref_table(subtab);
             }
         }
@@ -1395,6 +1455,9 @@ static DynFunTab group_dynfuntab[]={
     
     {(DynFun*)region_managed_rqorder,
      (DynFun*)group_managed_rqorder},
+     
+    {(DynFun*)region_get_rescue_pholder_for,
+     (DynFun*)group_get_rescue_pholder_for},
     
     END_DYNFUNTAB
 };
index 1966ba2ec9cb912a40b74f24d06e6fb9c7310518..d09ba9f862e1a3b0991ea69983366524cf2e088c 100644 (file)
@@ -17,7 +17,6 @@
 #include <ioncore/rectangle.h>
 #include <ioncore/pholder.h>
 #include <ioncore/stacking.h>
-#include <ioncore/framedpholder.h>
 
 
 INTRSTRUCT(WGroupAttachParams);
@@ -54,6 +53,7 @@ DECLCLASS(WGroup){
     WStacking *current_managed;
     WStacking *bottom;
     Window dummywin;
+    WGroupPHolder *phs;
 };
 
 
diff --git a/ioncore/groupedpholder.c b/ioncore/groupedpholder.c
deleted file mode 100644 (file)
index cce1a16..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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&REGION_FIT_WHATEVER)){
-        /* Comm. hack */
-        param.geom_set=TRUE;
-    }
-    
-    reg=region_attach_helper((WRegion*)cwg, par, fp, 
-                             (WRegionDoAttachFn*)grouped_do_attach_final,
-                             &param, data);
-    
-    if(reg==NULL){
-        destroy_obj((Obj*)cwg);
-        return NULL;
-    }
-
-    return (WRegion*)cwg;
-}
-
-
-WRegion *groupedpholder_do_attach(WGroupedPHolder *ph, int flags,
-                                  WRegionAttachData *data)
-{
-    WRegionAttachData data2;
-    
-    if(ph->cont==NULL)
-        return FALSE;
-
-    data2.type=REGION_ATTACH_NEW;
-    data2.u.n.fn=grouped_handler;
-    data2.u.n.param=data;
-        
-    return pholder_do_attach(ph->cont, flags, &data2);
-}
-
-
-/*}}}*/
-
-
-/*{{{ Other dynfuns */
-
-
-bool groupedpholder_do_goto(WGroupedPHolder *ph)
-{
-    return (ph->cont!=NULL
-            ? pholder_goto(ph->cont)
-            : FALSE);
-}
-
-
-WRegion *groupedpholder_do_target(WGroupedPHolder *ph)
-{
-    return (ph->cont!=NULL
-            ? pholder_target(ph->cont)
-            : NULL);
-}
-
-
-WPHolder *groupedpholder_do_root(WGroupedPHolder *ph)
-{
-    WPHolder *root;
-    
-    if(ph->cont==NULL)
-        return NULL;
-    
-    root=pholder_root(ph->cont);
-    
-    return (root!=ph->cont 
-            ? root
-            : &ph->ph);
-}
-
-
-/*}}}*/
-
-
-/*{{{ Class information */
-
-
-static DynFunTab groupedpholder_dynfuntab[]={
-    {(DynFun*)pholder_do_attach, 
-     (DynFun*)groupedpholder_do_attach},
-
-    {(DynFun*)pholder_do_goto, 
-     (DynFun*)groupedpholder_do_goto},
-
-    {(DynFun*)pholder_do_target, 
-     (DynFun*)groupedpholder_do_target},
-     
-    {(DynFun*)pholder_do_root, 
-     (DynFun*)groupedpholder_do_root},
-    
-    END_DYNFUNTAB
-};
-
-IMPLCLASS(WGroupedPHolder, WPHolder, groupedpholder_deinit, 
-          groupedpholder_dynfuntab);
-
-
-/*}}}*/
-
diff --git a/ioncore/groupedpholder.h b/ioncore/groupedpholder.h
deleted file mode 100644 (file)
index d0edf68..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ion/ioncore/groupedpholder.h
- *
- * Copyright (c) Tuomo Valkonen 2005-2007. 
- *
- * See the included file LICENSE for details.
- */
-
-#ifndef ION_IONCORE_GROUPEDPHOLDER_H
-#define ION_IONCORE_GROUPEDPHOLDER_H
-
-#include "common.h"
-#include "pholder.h"
-#include "attach.h"
-
-INTRCLASS(WGroupedPHolder);
-
-DECLCLASS(WGroupedPHolder){
-    WPHolder ph;
-    WPHolder *cont;
-};
-
-extern WGroupedPHolder *create_groupedpholder(WPHolder *cont);
-
-extern bool groupedpholder_init(WGroupedPHolder *ph, WPHolder *cont);
-
-extern void groupedpholder_deinit(WGroupedPHolder *ph);
-
-extern bool groupedpholder_do_goto(WGroupedPHolder *ph);
-
-extern WRegion *groupedpholder_do_target(WGroupedPHolder *ph);
-
-extern WPHolder *groupedpholder_do_root(WGroupedPHolder *ph);
-
-extern WRegion *groupedpholder_do_attach(WGroupedPHolder *ph, int flags,
-                                         WRegionAttachData *data);
-
-#endif /* ION_IONCORE_GROUPEDPHOLDER_H */
index 3c2ed30d244334d13a44a2e0a6f227ced3225e5e..afd8ac675f54808d674b3b2f59bf9de22bca7c51 100644 (file)
@@ -9,26 +9,93 @@
 #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;
 
 
@@ -36,22 +103,17 @@ bool grouppholder_init(WGroupPHolder *ph, WGroup *ws,
                        const WStacking *st,
                        const WGroupAttachParams *param)
 {
+    WRegion *stack_above=NULL;
+    
     pholder_init(&(ph->ph));
 
-    watch_init(&(ph->group_watch));
     watch_init(&(ph->stack_above_watch));
-    
-    if(ws!=NULL){
-        if(!watch_setup(&(ph->group_watch), (Obj*)ws, 
-                        group_watch_handler)){
-            pholder_deinit(&(ph->ph));
-            return FALSE;
-        }
-    }
-    
-    if(param==NULL)
-        param=&dummy_param;
-    
+    ph->next=NULL;
+    ph->prev=NULL;
+    ph->group=NULL;
+    ph->recreate_pholder=NULL;
+    ph->param=(param==NULL ? dummy_param : *param);
+
     if(st!=NULL){
         /* TODO? Just link to the stacking structure to remember 
          * stacking order? 
@@ -71,22 +133,18 @@ bool grouppholder_init(WGroupPHolder *ph, WGroup *ws,
             ph->param.stack_above=st->above->reg;
         
         ph->param.bottom=(st==ws->bottom);
-    }else{
-        ph->param=*param;
     }
-
+    
     ph->param.switchto_set=FALSE;
-
-    if(ph->param.stack_above!=NULL){
-        /* We must move stack_above pointer into a Watch. */
-        watch_setup(&(ph->stack_above_watch), 
-                    (Obj*)ph->param.stack_above, NULL);
-        ph->param.stack_above=NULL;
-    }
+    
+    stack_above=ph->param.stack_above;
+    ph->param.stack_above=NULL;
+    
+    grouppholder_do_link(ph, ws, stack_above);
     
     return TRUE;
 }
+
 
 WGroupPHolder *create_grouppholder(WGroup *ws,
                                    const WStacking *st,
@@ -98,8 +156,8 @@ WGroupPHolder *create_grouppholder(WGroup *ws,
 
 void grouppholder_deinit(WGroupPHolder *ph)
 {
-    watch_reset(&(ph->group_watch));
-    watch_reset(&(ph->stack_above_watch));
+    grouppholder_do_unlink(ph);
+    
     pholder_deinit(&(ph->ph));
 }
 
@@ -110,15 +168,96 @@ void grouppholder_deinit(WGroupPHolder *ph)
 /*{{{ Dynfuns */
 
 
+static WPHolder *get_recreate_ph(WGroupPHolder *ph)
+{
+    return get_head(ph)->recreate_pholder;
+}
+
+
+typedef struct{
+    WGroupPHolder *ph, *ph_head;
+    WRegionAttachData *data;
+    WRegion *reg_ret;
+} RP;
+
+
+static WRegion *recreate_handler(WWindow *par, 
+                                 const WFitParams *fp, 
+                                 void *rp_)
+{
+    WGroupPHolder *phtmp;
+    RP *rp=(RP*)rp_;
+    WGroup *grp;
+    
+    grp=(WGroup*)create_groupcw(par, fp);
+    
+    if(grp==NULL)
+        return NULL;
+    
+    rp->reg_ret=group_do_attach(grp, &rp->ph->param, rp->data);
+    
+    if(rp->reg_ret==NULL){
+        destroy_obj((Obj*)grp);
+        return NULL;
+    }else{
+        grp->phs=rp->ph_head;
+        
+        for(phtmp=grp->phs; phtmp!=NULL; phtmp=phtmp->next)
+            phtmp->group=grp;
+    }
+    
+    return (WRegion*)grp;
+}
+
+
+
+static WRegion *grouppholder_attach_recreate(WGroupPHolder *ph, int flags,
+                                             WRegionAttachData *data)
+{
+    WRegionAttachData data2;
+    WPHolder *root, *rph;
+    WGroup *grp;
+    RP rp;
+    
+    rp.ph_head=get_head(ph);
+    
+    assert(rp.ph_head!=NULL);
+    
+    rph=rp.ph_head->recreate_pholder;
+    
+    if(rph==NULL)
+        return NULL;
+    
+    rp.ph=ph;
+    rp.data=data;
+    rp.reg_ret=NULL;
+    
+    data2.type=REGION_ATTACH_NEW;
+    data2.u.n.fn=recreate_handler;
+    data2.u.n.param=&rp;
+    
+    grp=(WGroup*)pholder_do_attach(rph, flags, &data2);
+    
+    if(grp!=NULL){
+        assert(OBJ_IS(grp, WGroup));
+        rp.ph_head->recreate_pholder=NULL;
+        /* It might be in use in attach chain! So defer. */
+        mainloop_defer_destroy((Obj*)rph);
+    }
+
+    return rp.reg_ret;
+}
+
+
 WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags,
                                 WRegionAttachData *data)
 {
-    WGroup *ws=(WGroup*)ph->group_watch.obj;
+    WGroup *ws=ph->group;
     WRegion *reg;
 
     if(ws==NULL)
-        return FALSE;
-
+        return grouppholder_attach_recreate(ph, flags, data);
+    
     ph->param.switchto_set=1;
     ph->param.switchto=(flags&PHOLDER_ATTACH_SWITCHTO ? 1 : 0);
     
@@ -135,7 +274,7 @@ WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags,
 
 bool grouppholder_do_goto(WGroupPHolder *ph)
 {
-    WGroup *ws=(WGroup*)ph->group_watch.obj;
+    WGroup *ws=ph->group;
     
     if(ws!=NULL)
         return region_goto((WRegion*)ws);
@@ -146,7 +285,7 @@ bool grouppholder_do_goto(WGroupPHolder *ph)
 
 WRegion *grouppholder_do_target(WGroupPHolder *ph)
 {
-    return (WRegion*)ph->group_watch.obj;
+    return (WRegion*)ph->group;
 }
 
 
index 86974ad3b39a4b4c32e600dfeb3d51e71ffa3c76..c8295370b9b2f718a4f6027e29d1963cacc3d4e6 100644 (file)
 #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, 
@@ -43,4 +44,8 @@ extern WRegion *grouppholder_do_attach(WGroupPHolder *ph, int flags,
 extern WGroupPHolder *group_managed_get_pholder(WGroup *group, 
                                                 WRegion *mgd);
 
+extern void grouppholder_do_unlink(WGroupPHolder *ph);
+extern void grouppholder_do_link(WGroupPHolder *ph, WGroup *group, 
+                                 WRegion *stack_above);
+
 #endif /* ION_IONCORE_GROUPPHOLDER_H */
index 9f9bcfce0603281725c5fdde65b0ac6af649932a..8974780e2aad00454bc530f12e54ac66edc0f820 100644 (file)
@@ -76,11 +76,11 @@ static const char ioncore_copy[]=
     "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"
@@ -281,7 +281,6 @@ static bool init_hooks()
     INIT_HOOK_(ioncore_submap_ungrab_hook);
     
     INIT_HOOK_(region_notify_hook);
-    ADD_HOOK_(region_notify_hook, ioncore_frame_quasiactivation_notify);
     ADD_HOOK_(region_notify_hook, ioncore_screen_activity_notify);
     
     INIT_HOOK(clientwin_do_manage_alt, clientwin_do_manage_default);
index dde9195d991e2c63ef7d3cd399729387b950244e..8f1bfab34b956d71bc764a3b6ba27c44dbd5d168 100644 (file)
@@ -26,6 +26,7 @@ dopath('ioncore_misc')
 dopath('ioncore_wd')
 dopath('ioncore_menudb')
 dopath('ioncore_tabnum')
+dopath('ioncore_quasiact')
 
 -- Modifier setup compatibility kludge
 local oldindex
diff --git a/ioncore/ioncore_quasiact.lua b/ioncore/ioncore_quasiact.lua
new file mode 100644 (file)
index 0000000..ce4116d
--- /dev/null
@@ -0,0 +1,74 @@
+--
+-- ion/share/ioncore_quasiact.lua -- Frame quasiactivation support
+-- 
+-- Copyright (c) Tuomo Valkonen 2007.
+--
+-- See the included file LICENSE for details.
+--
+
+local qa_source={}
+local qa_target={}
+
+local function quasi_activated(frame, src)
+    local old=qa_source[frame]
+    if old then
+        qa_target[old]=nil
+    end
+    qa_source[frame]=src
+    qa_target[src]=frame
+    ioncore.defer(function() frame:set_grattr("quasiactive", "set") end)
+end
+
+local function quasi_inactivated(frame, src)
+    qa_source[frame]=nil
+    qa_target[src]=nil
+    ioncore.defer(function() frame:set_grattr("quasiactive", "unset") end)
+end
+
+local function activated(src)
+    local tgt=src:__return_target()
+    if obj_is(tgt, "WFrame") then
+        quasi_activated(tgt, src)
+    elseif obj_is(tgt, "WGroup") then
+        local mgr=tgt:manager()
+        if obj_is(mgr, "WFrame") then
+            quasi_activated(mgr, src)
+        end
+    end
+end
+
+local function inactivated(src)
+    local tgt=qa_target[src]
+    if tgt then
+        quasi_inactivated(tgt, src)
+        return true
+    end
+end
+
+local function deinit(tgt)
+    local src=qa_source[tgt]
+    if src then
+        qa_target[src]=nil
+        qa_source[tgt]=nil
+    end
+end
+
+local function quasiact_notify(reg, how)
+    if how=="activated" or how=="pseudoactivated" then
+        activated(reg)
+    elseif how=="inactivated" or how=="pseudoinactivated" then
+        inactivated(reg)
+    elseif how=="set_return" then
+        if reg:is_active(true--[[pseudoact--]]) then
+            activated(reg)
+        end
+    elseif how=="unset_return" then
+        inactivated(reg)
+    elseif how=="deinit" then
+        inactivated(reg)
+        deinit(reg)
+    end
+end
+
+
+ioncore.get_hook("region_notify_hook"):add(quasiact_notify)
index cdb7a36ed815d316df295080ed52629b1377c24d..c0b42e5b5043e260f6bec5567755869aea7a0bc0 100644 (file)
@@ -8,31 +8,23 @@
 
 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
@@ -51,7 +43,7 @@ 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
@@ -87,6 +79,7 @@ end
 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
@@ -147,7 +140,10 @@ 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
index 6a6ca51eb6b1478d93c07c78889f1de6308be905..cae9c633a7dcca10a9734e1a8cd006b68babaff1 100644 (file)
@@ -92,8 +92,8 @@ function ioncore.match_winprop_dflt(prop, cwin, id)
         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
     
index f91821ca5864eaebffd9c46004bd6f60cc2291f1..636ac1dabd6514bcfa1844de0459a3b474d6add4 100644 (file)
@@ -33,6 +33,8 @@ static int last_accel_mode=0;
 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()
@@ -46,7 +48,7 @@ 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))
@@ -59,6 +61,8 @@ void ioncore_set_moveres_accel(ExtlTab tab)
        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);
 }
 
 
@@ -69,6 +73,7 @@ void ioncore_get_moveres_accel(ExtlTab tab)
     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);
 }
 
 
index 69b7711f9f7311e060d0a8c4cd53ece76af9193a..f1b04c60f5e82f29db0378738388eb337b6dd1c4 100644 (file)
@@ -339,6 +339,23 @@ bool region_rescue_child_clientwins(WRegion *reg, WRescueInfo *info)
 }
 
 
+WPHolder *rescueinfo_pholder(WRescueInfo *info)
+{
+    if(info->test)
+        return NULL;
+        
+    if(info->ph==NULL){
+        info->ph=region_get_rescue_pholder(info->get_rescue);
+        if(info->ph==NULL){
+            info->failed_get=TRUE;
+            return NULL;
+        }
+    }
+    
+    return info->ph;
+}
+
+
 /* Bah, unsplitissä oikestaan pitäisi tehä non-deep rescue */
 
 bool region_do_rescue_this(WRegion *tosave_, WRescueInfo *info, int ph_flags)
@@ -359,19 +376,13 @@ bool region_do_rescue_this(WRegion *tosave_, WRescueInfo *info, int ph_flags)
     
     if(tosave==NULL){
         return region_rescue_clientwins(tosave_, info);
-    }else if(info->test){
-        return FALSE;
     }else{
         int phf=(info->flags&REGION_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));
     }
 }
 
index dbe09ac5c38cb46dc97bea5630ebd7f203e22699..f745d66a8dd94ab25cb1785a21bccfa8aee06a7e 100644 (file)
@@ -103,6 +103,8 @@ extern WPHolder *region_prepare_manage_transient_default(WRegion *reg,
 
 INTRSTRUCT(WRescueInfo);
 
+extern WPHolder *rescueinfo_pholder(WRescueInfo *info);
+
 /* if ph is given, it is used, otherwise one is looked for when needed */
 extern bool region_rescue(WRegion *reg, WPHolder *ph, int flags);
 extern bool region_rescue_needed(WRegion *reg);
index da1bd49b48218c0bd4cfd631cd097ed2fbf56646..8af9148afc1084d3c287de7daea9b76bd9bac9ec 100644 (file)
 #include "saveload.h"
 #include "xwindow.h"
 #include "mplexpholder.h"
+#include "grouppholder.h"
 #include "llist.h"
 #include "names.h"
 #include "sizepolicy.h"
 #include "stacking.h"
 #include "group.h"
 #include "navi.h"
-#include "groupedpholder.h"
 
 
 #define SUBS_MAY_BE_MAPPED(MPLEX) \
@@ -98,7 +98,7 @@ bool mplex_do_init(WMPlex *mplex, WWindow *parent,
     
     mplex->mx_list=NULL;
     mplex->mx_current=NULL;
-    mplex->mx_phs=NULL;
+    mplex->misc_phs=NULL;
     mplex->mx_count=0;
     
     mplex->mgd=NULL;
@@ -147,8 +147,8 @@ void mplex_deinit(WMPlex *mplex)
     assert(mplex->mgd==NULL);
     assert(mplex->mx_list==NULL);
 
-    while(mplex->mx_phs!=NULL){
-        assert(mplexpholder_move(mplex->mx_phs, NULL, NULL, NULL));
+    while(mplex->misc_phs!=NULL){
+        assert(mplexpholder_move(mplex->misc_phs, NULL, NULL, NULL));
     }
     
     window_deinit((WWindow*)mplex);
@@ -246,7 +246,8 @@ WRegion *mplex_mx_nth(WMPlex *mplex, uint n)
 /*EXTL_DOC
  * Iterate over numbered/mutually exclusive region list of \var{mplex} 
  * until \var{iterfn} returns \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
@@ -263,7 +264,8 @@ bool mplex_mx_i(WMPlex *mplex, ExtlFn iterfn)
 /*EXTL_DOC
  * Iterate over managed regions of \var{mplex} until \var{iterfn} returns
  * \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
@@ -432,7 +434,8 @@ bool mplex_fitrep(WMPlex *mplex, WWindow *par, const WFitParams *fp)
     bool wchg=(REGION_GEOM(mplex).w!=fp->g.w);
     bool hchg=(REGION_GEOM(mplex).h!=fp->g.h);
     
-    window_do_fitrep(&(mplex->win), par, &(fp->g));
+    if(!window_fitrep(&(mplex->win), par, fp))
+        return FALSE;
     
     if(wchg || hchg){
         mplex_fit_managed(mplex);
@@ -492,9 +495,10 @@ static void mplex_managed_rqgeom(WMPlex *mplex, WRegion *sub,
     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)
@@ -1297,6 +1301,7 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph)
     if(!(param->flags&MPLEX_ATTACH_WHATEVER)){
         WFitParams fp;
         
+        fp.mode=0;
         mplex_managed_geom(mplex, &(fp.g));
         
         sizepolicy(&node->szplcy, reg, 
@@ -1323,7 +1328,11 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph)
              * 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)
@@ -1333,18 +1342,24 @@ bool mplex_do_attach_final(WMPlex *mplex, WRegion *reg, WMPlexPHolder *ph)
 }
 
 
+static void mplex_attach_fp(WMPlex *mplex, const WMPlexAttachParams *param,
+                            WFitParams *fp)
+{
+    if(param->flags&MPLEX_ATTACH_GEOM)
+        fp->g=param->geom;
+    else
+        mplex_managed_geom(mplex, &(fp->g));
+    
+    fp->mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS;
+}
+
+
 WRegion *mplex_do_attach_pholder(WMPlex *mplex, WMPlexPHolder *ph,
                                  WRegionAttachData *data)
 {
-    WMPlexAttachParams *param=&(ph->param);
     WFitParams fp;
     
-    if(param->flags&MPLEX_ATTACH_GEOM)
-        fp.g=param->geom;
-    else
-        mplex_managed_geom(mplex, &(fp.g));
-    
-    fp.mode=REGION_FIT_WHATEVER|REGION_FIT_BOUNDS;
+    mplex_attach_fp(mplex, &ph->param, &fp);
     
     return region_attach_helper((WRegion*)mplex, 
                                 (WWindow*)mplex, &fp,
@@ -1592,9 +1607,19 @@ WPHolder *mplex_prepare_manage(WMPlex *mplex, const WClientWin *cwin,
     mph=create_mplexpholder(mplex, NULL, &ap);
     
     if(mph!=NULL){
-        WGroupedPHolder *gph=create_groupedpholder((WPHolder*)mph);
-        if(gph!=NULL)
+        WGroupPHolder *gph;
+        WGroupAttachParams gp=GROUPATTACHPARAMS_INIT;
+        
+        gp.switchto_set=1;
+        gp.switchto=1;
+        gp.bottom=1;
+        
+        gph=create_grouppholder(NULL, NULL, &gp);
+        
+        if(gph!=NULL){
+            gph->recreate_pholder=(WPHolder*)mph;
             return (WPHolder*)gph;
+        }
     }
     
     return (WPHolder*)mph;
@@ -1677,13 +1702,29 @@ void mplex_managed_remove(WMPlex *mplex, WRegion *sub)
 }
 
 
+void mplex_child_removed(WMPlex *mplex, WRegion *sub)
+{
+    if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){
+        watch_reset(&(mplex->stdispwatch));
+        mplex_set_stdisp(mplex, NULL, NULL);
+    }
+}
+
+
+/*}}}*/
+
+
+/*{{{ Rescue */
+
+
 bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info)
 {
     bool ret1, ret2;
     WMPlexIterTmp tmp;
     WLListIterTmp ltmp;
     WLListNode *lnode, *was_current=mplex->mx_current;
-    
+
+     
     /* First all mx stuff to move them nicely to another mplex (when that 
      * is the case), switching to the current region in the target if 
      * allowed by ph_flags_mask region_rescue.
@@ -1706,40 +1747,11 @@ bool mplex_rescue_clientwins(WMPlex *mplex, WRescueInfo *info)
 }
 
 
-
-void mplex_child_removed(WMPlex *mplex, WRegion *sub)
-{
-    if(sub!=NULL && sub==(WRegion*)(mplex->stdispwatch.obj)){
-        watch_reset(&(mplex->stdispwatch));
-        mplex_set_stdisp(mplex, NULL, NULL);
-    }
-}
-
-
 /*}}}*/
 
 
 /*{{{ Status display support */
 
-#ifndef offsetof
-# define offsetof(T,F) ((size_t)((char*)&((T*)0L)->F-(char*)0L))
-#endif
-
-#define STRUCTOF(T, F, FADDR) \
-        ((T*)((char*)(FADDR)-offsetof(T, F)))
-
-
-static void stdisp_watch_handler(Watch *watch, Obj *obj)
-{
-    /*WMPlex *mplex=STRUCTOF(WMPlex, stdispinfo, 
-     STRUCTOF(WMPlexSTDispInfo, regwatch, watch));
-     WMPlexSTDispInfo *di=&(mplex->stdispinfo);
-     WGenWS *ws=OBJ_CAST(REGION_MANAGER(obj), WGenWS);
-     * 
-     if(ioncore_g.opmode!=IONCORE_OPMODE_DEINIT && ws!=NULL)
-     genws_unmanage_stdisp(ws, TRUE, FALSE);*/
-}
-
 
 bool mplex_set_stdisp(WMPlex *mplex, WRegion *reg, 
                       const WMPlexSTDispInfo *din)
@@ -1770,7 +1782,7 @@ bool mplex_set_stdisp(WMPlex *mplex, WRegion *reg,
                 region_detach_manager(oldstdisp);
         }
     }else{
-        watch_setup(&(mplex->stdispwatch), (Obj*)reg, stdisp_watch_handler);
+        watch_setup(&(mplex->stdispwatch), (Obj*)reg, NULL);
         
         mplex_remanage_stdisp(mplex);
     }
@@ -1864,7 +1876,7 @@ WRegion *mplex_set_stdisp_extl(WMPlex *mplex, ExtlTab t)
         
         data.type=REGION_ATTACH_LOAD;
         data.u.tab=t;
-            
+        
         stdisp=region_attach_helper((WRegion*)mplex, 
                                     (WWindow*)mplex, &fp,
                                     do_attach_stdisp, NULL,
@@ -2107,16 +2119,6 @@ ExtlTab mplex_get_configuration(WMPlex *mplex)
 }
 
 
-static WMPlex *tmp_mplex=NULL;
-static WMPlexAttachParams *tmp_par=NULL;
-
-static WPHolder *pholder_callback()
-{
-    assert(tmp_mplex!=NULL);
-    return (WPHolder*)create_mplexpholder(tmp_mplex, NULL, tmp_par);
-}
-
-
 void mplex_load_contents(WMPlex *mplex, ExtlTab tab)
 {
     ExtlTab substab, subtab;
@@ -2132,27 +2134,26 @@ void mplex_load_contents(WMPlex *mplex, ExtlTab tab)
         n=extl_table_get_n(substab);
         for(i=1; i<=n; i++){
             if(extl_table_geti_t(substab, i, &subtab)){
-                /*mplex_attach_new(mplex, subtab);*/
                 WMPlexAttachParams par=MPLEXATTACHPARAMS_INIT;
-                WRegionAttachData data;
-                char *tmp=NULL;
+                WFitParams fp;
+                WPHolder *ph;
                 
                 get_params(mplex, subtab, 0, &par);
+                mplex_attach_fp(mplex, &par, &fp);
                 
                 par.flags|=MPLEX_ATTACH_INDEX;
                 par.index=LLIST_INDEX_LAST;
                 
-                tmp_par=&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);
             }
index 7bc833f8e7f899e60bd07cefab59b8aa771d251d..aced27fe8df3f81659ff1b8cbffd772dc053f0da 100644 (file)
@@ -94,7 +94,7 @@ DECLCLASS(WMPlex){
     int mx_count;
     WLListNode *mx_current;
     WLListNode *mx_list;
-    WMPlexPHolder *mx_phs;
+    WMPlexPHolder *misc_phs;
     
     Watch stdispwatch;
     WMPlexSTDispInfo stdispinfo;
index 8bb7ddb1e89ee279d3f99ec0229b68dd3e956d63..3cbf5fdc2fa46a87471482c2d71502780fcae14a 100644 (file)
@@ -9,6 +9,7 @@
 #include <libtu/objp.h>
 #include <libtu/obj.h>
 #include <libtu/pointer.h>
+#include <libmainloop/defer.h>
 
 #include "common.h"
 #include "mplex.h"
@@ -18,9 +19,6 @@
 #include "basicpholder.h"
 
 
-static void mplex_watch_handler(Watch *watch, Obj *mplex);
-
-
 /*{{{ Primitives */
 
 
@@ -35,7 +33,7 @@ static void mplexpholder_do_link(WMPlexPHolder *ph,
                                  WMPlexPHolder *after,
                                  WLListNode *or_after)
 {
-    assert(mplex==(WMPlex*)ph->mplex_watch.obj && mplex!=NULL);
+    assert(mplex==(WMPlex*)ph->mplex && mplex!=NULL);
     
     if(after!=NULL){
         assert(after->after==or_after);
@@ -43,44 +41,60 @@ static void mplexpholder_do_link(WMPlexPHolder *ph,
         if(after->after!=NULL){
             LINK_ITEM_AFTER(after->after->phs, after, ph, next, prev);
         }else{
-            assert(on_ph_list(mplex->mx_phs, after));
-            LINK_ITEM_AFTER(mplex->mx_phs, after, ph, next, prev);
+            assert(on_ph_list(mplex->misc_phs, after));
+            LINK_ITEM_AFTER(mplex->misc_phs, after, ph, next, prev);
         }
         ph->after=after->after;
     }else if(or_after!=NULL){
         LINK_ITEM_FIRST(or_after->phs, ph, next, prev);
         ph->after=or_after;
     }else{
-        LINK_ITEM_FIRST(mplex->mx_phs, ph, next, prev);
+        LINK_ITEM_FIRST(mplex->misc_phs, ph, next, prev);
         ph->after=NULL;
     }
 }
 
 
+static WMPlexPHolder *get_head(WMPlexPHolder *ph)
+{
+    while(1){
+        /* ph->prev==NULL should not happen.. */
+        if(ph->prev==NULL || ph->prev->next==NULL)
+            break;
+        ph=ph->prev;
+    }
+    
+    return ph;
+}
+
+
 void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex)
 {
     if(ph->recreate_pholder!=NULL){
-        if(ph->prev!=NULL)
-            ph->prev->recreate_pholder=ph->recreate_pholder;
-        else
-            destroy_obj((Obj*)ph->recreate_pholder);
+        if(ph->next!=NULL){
+            ph->next->recreate_pholder=ph->recreate_pholder;
+        }else{
+            /* It might be in use in attach chain! So defer. */
+            mainloop_defer_destroy((Obj*)ph->recreate_pholder);
+        }
         ph->recreate_pholder=NULL;
     }
     
     if(ph->after!=NULL){
         UNLINK_ITEM(ph->after->phs, ph, next, prev);
-    }else if(mplex!=NULL && on_ph_list(mplex->mx_phs, ph)){
-        UNLINK_ITEM(mplex->mx_phs, ph, next, prev);
+    }else if(mplex!=NULL && on_ph_list(mplex->misc_phs, ph)){
+        UNLINK_ITEM(mplex->misc_phs, ph, next, prev);
     }else{
         WMPlexPHolder *next=ph->next;
-    
-        assert((ph->next==NULL && ph->prev==NULL)
-               || ph->mplex_watch.obj==NULL);
         
-        if(ph->next!=NULL)
-            ph->next->prev=ph->prev;
         if(ph->prev!=NULL)
             ph->prev->next=next;
+
+        if(next==NULL){
+            next=get_head(ph);
+            assert(next->prev==ph);
+        }
+        next->prev=ph->prev;
     }
     
     ph->after=NULL;
@@ -95,14 +109,6 @@ void mplexpholder_do_unlink(WMPlexPHolder *ph, WMPlex *mplex)
 /*{{{ Init/deinit */
 
 
-static void mplex_watch_handler(Watch *watch, Obj *mplex)
-{
-    WMPlexPHolder *ph=FIELD_TO_STRUCT(WMPlexPHolder, mplex_watch, watch);
-    mplexpholder_do_unlink(ph, (WMPlex*)mplex);
-    pholder_redirect(&(ph->ph), (WRegion*)mplex);
-}
-
-
 static void mplex_get_attach_params(WMPlex *mplex, WStacking *st,
                                     WMPlexAttachParams *param)
 {
@@ -120,27 +126,24 @@ static void mplex_get_attach_params(WMPlex *mplex, WStacking *st,
 bool mplexpholder_init(WMPlexPHolder *ph, WMPlex *mplex, WStacking *st,
                        WMPlexAttachParams *param)
 {
+    WLListNode *or_after=NULL;
+    WMPlexPHolder *after=NULL;
+    
     pholder_init(&(ph->ph));
 
-    watch_init(&(ph->mplex_watch));
+    ph->mplex=mplex;
     ph->after=NULL;
     ph->next=NULL;
     ph->prev=NULL;
     ph->param.flags=0;
     ph->recreate_pholder=NULL;
-    
-    if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler)){
-        pholder_deinit(&(ph->ph));
-        return FALSE;
-    }
 
     if(st!=NULL){
         mplex_get_attach_params(mplex, st, &ph->param);
         
         if(st->lnode!=NULL){
-            mplexpholder_do_link(ph, mplex, 
-                                 LIST_LAST(st->lnode->phs, next, prev), 
-                                 st->lnode);
+            after=LIST_LAST(st->lnode->phs, next, prev);
+            or_after=st->lnode;
         }
     }else{
         static WMPlexAttachParams dummy_param={0, 0, {0, 0, 0, 0}, 0, 0};
@@ -154,18 +157,17 @@ bool mplexpholder_init(WMPlexPHolder *ph, WMPlex *mplex, WStacking *st,
             int index=(param->flags&MPLEX_ATTACH_INDEX
                        ? param->index
                        : mplex_default_index(mplex));
-            WLListNode *or_after=llist_index_to_after(mplex->mx_list, 
-                                                      mplex->mx_current, 
-                                                      index);
-            WMPlexPHolder *after=(index==LLIST_INDEX_LAST
-                                  ? (or_after!=NULL
-                                     ? LIST_LAST(or_after->phs, next, prev) 
-                                     : LIST_LAST(mplex->mx_phs, next, prev))
-                                  : NULL);
-
-            mplexpholder_do_link(ph, mplex, after, or_after);
+            or_after=llist_index_to_after(mplex->mx_list, 
+                                          mplex->mx_current, index);
+            after=(index==LLIST_INDEX_LAST
+                   ? (or_after!=NULL
+                      ? LIST_LAST(or_after->phs, next, prev) 
+                      : LIST_LAST(mplex->misc_phs, next, prev))
+                   : NULL);
         }
     }
+
+    mplexpholder_do_link(ph, mplex, after, or_after);
     
     return TRUE;
 }
@@ -181,8 +183,7 @@ WMPlexPHolder *create_mplexpholder(WMPlex *mplex,
 
 void mplexpholder_deinit(WMPlexPHolder *ph)
 {
-    mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj);
-    watch_reset(&(ph->mplex_watch));
+    mplexpholder_do_unlink(ph, ph->mplex);
     pholder_deinit(&(ph->ph));
 }
 
@@ -197,18 +198,18 @@ typedef struct{
     WMPlexPHolder *ph, *ph_head;
     WRegionAttachData *data;
     WFramedParam *param;
+    WRegion *reg_ret;
 } RP;
 
 
-WRegion *recreate_handler(WWindow *par, 
-                          const WFitParams *fp, 
-                          void *rp_)
+static WRegion *recreate_handler(WWindow *par, 
+                                 const WFitParams *fp, 
+                                 void *rp_)
 {
     RP *rp=(RP*)rp_;
     WMPlexPHolder *ph=rp->ph, *ph_head=rp->ph_head, *phtmp;
     WFramedParam *param=rp->param;
     WFrame *frame;
-    WRegion *reg;
     
     frame=create_frame(par, fp, param->mode);
     
@@ -216,49 +217,37 @@ WRegion *recreate_handler(WWindow *par,
         return NULL;
     
     /* Move pholders to frame */
-    frame->mplex.mx_phs=ph_head;
+    frame->mplex.misc_phs=ph_head;
     
-    for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next)
-        watch_setup(&(phtmp->mplex_watch), (Obj*)frame, mplex_watch_handler);
+    for(phtmp=frame->mplex.misc_phs; phtmp!=NULL; phtmp=phtmp->next)
+        phtmp->mplex=&frame->mplex;
         
     /* Attach */
     if(fp->mode&(REGION_FIT_BOUNDS|REGION_FIT_WHATEVER))
         ph->param.flags|=MPLEX_ATTACH_WHATEVER;
     
-    reg=mplex_do_attach_pholder(&frame->mplex, ph, rp->data);
+    rp->reg_ret=mplex_do_attach_pholder(&frame->mplex, ph, rp->data);
 
     ph->param.flags&=~MPLEX_ATTACH_WHATEVER;
 
-    if(reg==NULL){
+    if(rp->reg_ret==NULL){
         /* Try to recover */
-        for(phtmp=frame->mplex.mx_phs; phtmp!=NULL; phtmp=phtmp->next)
-            watch_reset(&(phtmp->mplex_watch));
-        frame->mplex.mx_phs=NULL;
+        for(phtmp=frame->mplex.misc_phs; phtmp!=NULL; phtmp=phtmp->next)
+            phtmp->mplex=NULL;
+        
+        frame->mplex.misc_phs=NULL;
     
         destroy_obj((Obj*)frame);
         
         return NULL;
     }else{
-        frame_adjust_to_initial(frame, fp, param, reg);
+        frame_adjust_to_initial(frame, fp, param, rp->reg_ret);
         
         return (WRegion*)frame;
     }
 }
 
 
-static WMPlexPHolder *get_head(WMPlexPHolder *ph)
-{
-    while(1){
-        /* ph->prev==NULL should not happen.. */
-        if(ph->prev==NULL || ph->prev->next==NULL)
-            break;
-        ph=ph->prev;
-    }
-    
-    return ph;
-}
-
-
 static WFramedPHolder *get_recreate_ph(WMPlexPHolder *ph)
 {
     return get_head(ph)->recreate_pholder;
@@ -271,7 +260,7 @@ static WRegion *mplexpholder_attach_recreate(WMPlexPHolder *ph, int flags,
     WRegionAttachData data2;
     WFramedPHolder *fph;
     WPHolder *root;
-    WRegion *reg;
+    WRegion *frame;
     RP rp;
     
     rp.ph_head=get_head(ph);
@@ -286,26 +275,28 @@ static WRegion *mplexpholder_attach_recreate(WMPlexPHolder *ph, int flags,
     rp.ph=ph;
     rp.data=data;
     rp.param=&fph->param;
+    rp.reg_ret=NULL;
     
     data2.type=REGION_ATTACH_NEW;
     data2.u.n.fn=recreate_handler;
     data2.u.n.param=&rp;
     
-    reg=pholder_do_attach(fph->cont, flags, &data2); /* == frame */
+    frame=pholder_do_attach(fph->cont, flags, &data2);
     
-    if(reg!=NULL){
-        destroy_obj((Obj*)fph);
+    if(frame!=NULL){
         rp.ph_head->recreate_pholder=NULL;
+        /* It might be in use in attach chain! So defer. */
+        mainloop_defer_destroy((Obj*)fph);
     }
-
-    return reg;
+    
+    return rp.reg_ret;
 }
 
 
 WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags,
                                 WRegionAttachData *data)
 {
-    WMPlex *mplex=(WMPlex*)ph->mplex_watch.obj;
+    WMPlex *mplex=ph->mplex;
     
     if(mplex==NULL)
         return mplexpholder_attach_recreate(ph, flags, data);
@@ -322,18 +313,14 @@ WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags,
 bool mplexpholder_move(WMPlexPHolder *ph, WMPlex *mplex, 
                        WMPlexPHolder *after,
                        WLListNode *or_after)
-
 {
-    mplexpholder_do_unlink(ph, (WMPlex*)ph->mplex_watch.obj);
+    mplexpholder_do_unlink(ph, ph->mplex);
 
-    watch_reset(&(ph->mplex_watch));
-    
+    ph->mplex=mplex;
+        
     if(mplex==NULL)
         return TRUE;
     
-    if(!watch_setup(&(ph->mplex_watch), (Obj*)mplex, mplex_watch_handler))
-        return FALSE;
-
     mplexpholder_do_link(ph, mplex, after, or_after);
     
     return TRUE;
@@ -342,7 +329,7 @@ bool mplexpholder_move(WMPlexPHolder *ph, WMPlex *mplex,
 
 bool mplexpholder_do_goto(WMPlexPHolder *ph)
 {
-    WRegion *reg=(WRegion*)ph->mplex_watch.obj;
+    WRegion *reg=(WRegion*)ph->mplex;
     
     if(reg!=NULL){
         return region_goto(reg);
@@ -358,7 +345,7 @@ bool mplexpholder_do_goto(WMPlexPHolder *ph)
 
 WRegion *mplexpholder_do_target(WMPlexPHolder *ph)
 {
-    WRegion *reg=(WRegion*)ph->mplex_watch.obj;
+    WRegion *reg=(WRegion*)ph->mplex;
     
     if(reg!=NULL){
         return reg;
@@ -372,24 +359,16 @@ WRegion *mplexpholder_do_target(WMPlexPHolder *ph)
 }
 
 
-WPHolder *mplexpholder_do_root(WMPlexPHolder *ph)
+bool mplexpholder_stale(WMPlexPHolder *ph)
 {
-    WRegion *reg=(WRegion*)ph->mplex_watch.obj;
+    WRegion *reg=(WRegion*)ph->mplex;
     
     if(reg!=NULL){
-        return &ph->ph;
+        return FALSE;
     }else{
         WFramedPHolder *fph=get_recreate_ph(ph);
-        WPHolder *root;
         
-        if(fph==NULL)
-            return NULL;
-    
-        root=pholder_root((WPHolder*)fph);
-    
-        return (root!=(WPHolder*)fph
-                ? root
-                : &ph->ph);
+        return (fph==NULL || pholder_stale((WPHolder*)fph));
     }
 }
 
@@ -427,7 +406,7 @@ void mplex_move_phs_before(WMPlex *mplex, WLListNode *node)
                          
     after=(or_after!=NULL
            ? LIST_LAST(or_after->phs, next, prev)
-           : LIST_LAST(mplex->mx_phs, next, prev));
+           : LIST_LAST(mplex->misc_phs, next, prev));
         
     mplex_move_phs(mplex, node, after, or_after);
 }
@@ -444,6 +423,33 @@ WMPlexPHolder *mplex_managed_get_pholder(WMPlex *mplex, WRegion *mgd)
 }
 
 
+void mplex_flatten_phs(WMPlex *mplex)
+{
+    WLListNode *node;
+    WLListIterTmp tmp;
+
+    FOR_ALL_NODES_ON_LLIST(node, mplex->mx_list, tmp){
+        WMPlexPHolder *last=(mplex->misc_phs==NULL ? NULL : mplex->misc_phs->prev);
+        mplex_move_phs(mplex, node, last, NULL);
+    }
+}
+
+
+void mplex_migrate_phs(WMPlex *src, WMPlex *dst)
+{
+    WLListNode *or_after=LIST_LAST(dst->mx_list, next, prev);
+    WMPlexPHolder *after=(or_after!=NULL
+                          ? LIST_LAST(or_after->phs, next, prev)
+                          : LIST_LAST(dst->misc_phs, next, prev));
+    
+    while(src->misc_phs!=NULL){
+        WMPlexPHolder *ph=src->misc_phs;
+        mplexpholder_move(ph, dst, after, or_after);
+        after=ph;
+    }
+}
+
+
 /*}}}*/
 
 
@@ -508,8 +514,8 @@ static DynFunTab mplexpholder_dynfuntab[]={
     {(DynFun*)pholder_do_target, 
      (DynFun*)mplexpholder_do_target},
      
-    {(DynFun*)pholder_do_root
-     (DynFun*)mplexpholder_do_root},
+    {(DynFun*)pholder_stale
+     (DynFun*)mplexpholder_stale},
 
     END_DYNFUNTAB
 };
index a017641c3df4c9badefa9fe2ba0488bdc3e23419..aee4678af57af122524eb1dcd2c496f4f6904315 100644 (file)
@@ -18,7 +18,7 @@
 
 DECLCLASS(WMPlexPHolder){
     WPHolder ph;
-    Watch mplex_watch;
+    WMPlex *mplex;
     WFramedPHolder *recreate_pholder; /* only on first of list */
     WLListNode *after;
     WMPlexPHolder *next, *prev;
@@ -43,7 +43,7 @@ extern WRegion *mplexpholder_do_attach(WMPlexPHolder *ph, int flags,
 
 extern bool mplexpholder_do_goto(WMPlexPHolder *ph);
 
-extern WPHolder *mplexpholder_do_root(WMPlexPHolder *ph);
+extern bool mplexpholder_stale(WMPlexPHolder *ph);
 
 extern WRegion *mplexpholder_do_target(WMPlexPHolder *ph);
 
@@ -57,6 +57,8 @@ extern void mplex_move_phs(WMPlex *mplex, WLListNode *node,
                            WMPlexPHolder *after,
                            WLListNode *or_after);
 extern void mplex_move_phs_before(WMPlex *mplex, WLListNode *node);
+extern void mplex_migrate_phs(WMPlex *src, WMPlex *dst);
+extern void mplex_flatten_phs(WMPlex *mplex);
 
 extern WMPlexPHolder *mplex_managed_get_pholder(WMPlex *mplex, 
                                                 WRegion *mgd);
index b7a8668a1f682199cecc6db0c80944aae8e21f0d..ce4d2aef9808c54db71b686507fa5bc6bd1b08d5 100644 (file)
@@ -562,7 +562,8 @@ static bool do_list(ExtlFn fn, WNamespace *ns, const char *typenam)
 /*EXTL_DOC
  * Iterate over all non-client window regions with (inherited) class
  * \var{typenam} until \var{iterfn} returns \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
@@ -575,7 +576,8 @@ bool ioncore_region_i(ExtlFn fn, const char *typenam)
 
 /*EXTL_DOC
  * Iterate over client windows until \var{iterfn} returns \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
index f5f9aae4e1da034ae0c7b9cff63d6265decb7f61..45c5d0ba6d183da90831a4bb0737d9831d3a816d 100644 (file)
 
 bool pholder_init(WPHolder *ph)
 {
-    ph->redirect=NULL;
     return TRUE;
 }
 
 
 void pholder_deinit(WPHolder *ph)
 {
-    if(ph->redirect!=NULL)
-        destroy_obj((Obj*)ph->redirect);
 }
 
 
@@ -37,20 +34,6 @@ WRegion *pholder_do_attach(WPHolder *ph, int flags,
 }
 
 
-WRegion *pholder_attach_(WPHolder *ph, int flags, WRegionAttachData *data)
-{
-    WPHolder *root=pholder_root(ph);
-    
-    /* Use the root, so that extra containers are not added from
-     * stale chains.
-     */
-    
-    return (root==NULL
-            ? NULL
-            : pholder_do_attach(root, flags, data));
-}
-
-
 bool pholder_attach(WPHolder *ph, int flags, WRegion *reg)
 {
     WRegionAttachData data;
@@ -58,7 +41,7 @@ bool pholder_attach(WPHolder *ph, int flags, WRegion *reg)
     data.type=REGION_ATTACH_REPARENT;
     data.u.reg=reg;
     
-    return (pholder_attach_(ph, flags, &data)!=NULL);
+    return (pholder_do_attach(ph, flags, &data)!=NULL);
 }
 
 
@@ -86,9 +69,7 @@ WRegion *pholder_do_target(WPHolder *ph)
 
 WRegion *pholder_target(WPHolder *ph)
 {
-    return (ph->redirect!=NULL
-            ? pholder_target(ph->redirect)
-            : pholder_do_target(ph));
+    return pholder_do_target(ph);
 }
 
 
@@ -112,10 +93,7 @@ DYNFUN bool pholder_do_check_reparent(WPHolder *ph, WRegion *reg)
 
 bool pholder_check_reparent(WPHolder *ph, WRegion *reg)
 {
-    if(ph->redirect!=NULL)
-        return pholder_check_reparent(ph->redirect, reg);
-    else
-        return pholder_do_check_reparent(ph, reg);
+    return pholder_do_check_reparent(ph, reg);
 }
     
 
@@ -129,53 +107,21 @@ bool pholder_do_goto(WPHolder *ph)
 
 bool pholder_goto(WPHolder *ph)
 {
-    return (ph->redirect!=NULL
-            ? pholder_goto(ph->redirect)
-            : pholder_do_goto(ph));
-}
-
-
-WPHolder *pholder_do_root_default(WPHolder *ph)
-{
-    return ph;
-}
-
-
-WPHolder *pholder_do_root(WPHolder *ph)
-{
-    WPHolder *ret=NULL;
-    CALL_DYN_RET(ret, WPHolder*, pholder_do_root, ph, (ph));
-    return ret;
+    return pholder_do_goto(ph);
 }
 
 
-WPHolder *pholder_root(WPHolder *ph)
+bool pholder_stale_default(WPHolder *ph)
 {
-    return (ph->redirect!=NULL
-            ? pholder_root(ph->redirect)
-            : pholder_do_root(ph));
+    return (pholder_target(ph)==NULL);
 }
 
 
 bool pholder_stale(WPHolder *ph)
 {
-    return (pholder_root(ph)!=ph);
-}
-
-
-bool pholder_redirect(WPHolder *ph, WRegion *old_target)
-{
-    WPHolder *ph2=region_get_rescue_pholder(old_target);
-    
-    if(ph2==NULL)
-        return FALSE;
-    
-    if(ph->redirect!=NULL)
-        destroy_obj((Obj*)ph->redirect);
-
-    ph->redirect=ph2;
-    
-    return TRUE;
+    bool ret=TRUE;
+    CALL_DYN_RET(ret, bool, pholder_stale, ph, (ph));
+    return ret;
 }
 
 
@@ -231,8 +177,8 @@ static DynFunTab pholder_dynfuntab[]={
     {(DynFun*)pholder_do_check_reparent, 
      (DynFun*)pholder_do_check_reparent_default},
      
-    {(DynFun*)pholder_do_root
-     (DynFun*)pholder_do_root_default},
+    {(DynFun*)pholder_stale
+     (DynFun*)pholder_stale_default},
 
     END_DYNFUNTAB
 };
index b2b4986a1e365d75dca1ff7642c3dec75f73a5bd..4d07f16be01b75fbf3aeb604048e1b8ffe4e2a8f 100644 (file)
@@ -21,7 +21,6 @@
 
 DECLCLASS(WPHolder){
     Obj obj;
-    WPHolder *redirect;
 };
 
 
@@ -42,11 +41,7 @@ DYNFUN WRegion *pholder_do_target(WPHolder *ph);
 
 extern WRegion *pholder_target(WPHolder *ph);
 
-extern WPHolder *pholder_do_root(WPHolder *ph);
-
-extern WPHolder *pholder_root(WPHolder *ph);
-
-extern bool pholder_stale(WPHolder *ph);
+DYNFUN bool pholder_stale(WPHolder *ph);
 
 DYNFUN bool pholder_do_check_reparent(WPHolder *ph, WRegion *reg);
 
@@ -56,8 +51,6 @@ DYNFUN bool pholder_do_goto(WPHolder *ph);
 
 extern bool pholder_goto(WPHolder *ph);
 
-extern bool pholder_redirect(WPHolder *ph, WRegion *old_target);
-
 extern WPHolder *pholder_either(WPHolder *a, WPHolder *b);
 
 DYNFUN WPHolder *region_managed_get_pholder(WRegion *reg, WRegion *mgd);
index 63a408e8b36c9c6c3f91af8528cfded674c2c365..f4fae714d724cf1afa70bea606cdc7b1be5df6f6 100644 (file)
@@ -217,13 +217,30 @@ static void pointer_grab_killed(WRegion *unused)
 }
 
 
-bool ioncore_do_handle_buttonpress(XButtonEvent *ev)
+static bool listens_to(WRegion *reg, uint state, uint button, int area)
+{
+    static const int acts[]={BINDING_BUTTONMOTION, BINDING_BUTTONCLICK, 
+                             BINDING_BUTTONDBLCLICK};
+    static const int n_acts=3;
+    int i;
+    
+    for(i=0; 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;
@@ -232,20 +249,37 @@ bool ioncore_do_handle_buttonpress(XButtonEvent *ev)
     
     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;
@@ -260,33 +294,44 @@ bool ioncore_do_handle_buttonpress(XButtonEvent *ev)
     p_orig_y=p_y=ev->y_root;
     p_time=ev->time;
     p_clickcnt=0;
-
-    watch_setup(&p_regwatch, (Obj*)reg, NULL);
+    p_area=area;
     
-    subreg=region_current(reg);
-    p_area=window_press((WWindow*)reg, ev, &subreg);
+    watch_setup(&p_regwatch, (Obj*)reg, NULL);
     if(subreg!=NULL)
         watch_setup(&p_subregwatch, (Obj*)subreg, NULL);
 
-    if(dblclick){
-        pressbind=region_lookup_binding(reg, BINDING_BUTTONDBLCLICK, state,
-                                             button, p_area);
-    }
-    
-    if(pressbind==NULL){
-        pressbind=region_lookup_binding(reg, BINDING_BUTTONPRESS, state,
-                                             button, p_area);
-    }
-    
     ioncore_grab_establish(reg, handle_key, pointer_grab_killed, 0);
     p_grabstate=ST_HELD;
     
-    call_button(pressbind, ev);
+    if(pressbind!=NULL)
+        call_button(pressbind, ev);
     
     return TRUE;
 }
 
 
+bool ioncore_do_handle_buttonpress(XButtonEvent *ev)
+{
+    /* Only one level of subwindows is supported... more would require
+     * searching through the trees thanks to grabbed events being reported
+     * relative to the outermost grabbing window.
+     */
+    if(ev->subwindow!=None && ev->state!=0){
+        XButtonEvent ev2=*ev;
+        ev2.window=ev->subwindow;
+        ev2.subwindow=None;
+        if(XTranslateCoordinates(ioncore_g.dpy, ev->window, ev2.window,
+                                 ev->x, ev->y, &(ev2.x), &(ev2.y),
+                                 &(ev2.subwindow))){
+            if(ioncore_dodo_handle_buttonpress(&ev2, TRUE))
+                return TRUE;
+        }
+    }
+    
+    return ioncore_dodo_handle_buttonpress(ev, FALSE);
+}
+
+
 bool ioncore_do_handle_buttonrelease(XButtonEvent *ev)
 {
     WBinding *binding=NULL;
@@ -299,7 +344,8 @@ bool ioncore_do_handle_buttonrelease(XButtonEvent *ev)
             p_clickcnt=1;
             binding=region_lookup_binding(p_reg, BINDING_BUTTONCLICK,
                                                p_state, p_button, p_area);
-            call_button(binding, ev);
+            if(binding!=NULL)
+                call_button(binding, ev);
         }else{
             call_motion_end(ev);
         }
index 22950ee9250beccba5c1f227fc69ff672bcab5f4..1592f000b7555fa53db3716f94e8c2e1f5fe38c9 100644 (file)
@@ -30,6 +30,9 @@
 #define XOR_RESIZE (!ioncore_g.opaque_resize)
 
 
+extern int ioncore_edge_resistance;
+
+
 /*{{{ Size/position display and rubberband */
 
 
@@ -139,14 +142,14 @@ static void moveres_draw_infowin(WMoveresMode *mode)
         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);
@@ -249,10 +252,9 @@ static bool moveresmode_init(WMoveresMode *mode, WRegion *reg,
         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)
@@ -341,12 +343,19 @@ static void moveresmode_do_newgeom(WMoveresMode *mode, WRQGeomParams *rq)
 }
 
 
+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);
@@ -358,7 +367,6 @@ static void moveresmode_delta(WMoveresMode *mode,
     /* 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;
@@ -370,14 +378,15 @@ static void moveresmode_delta(WMoveresMode *mode,
             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
index 092483c7fd999b556f494041dbf24397a682e4e2..9ebabc522d70c3638dd8d052373251ecc5d13c4f 100644 (file)
@@ -155,3 +155,18 @@ void region_unset_return(WRegion *reg)
 
 /*}}}*/
 
+
+/*{{{ Internal Lua exports */
+
+
+EXTL_SAFE
+EXTL_EXPORT_MEMBER
+WRegion *region___return_target(WRegion *reg)
+{
+    WPHolder *ph=region_get_return(reg);
+    return (ph!=NULL ? pholder_target(ph) : NULL);
+}
+
+
+/*}}}*/
+
index db8a12f47b55dcb9e9ee043690836ec042aaa750..c76c68e9aec642d959b425bddf07a31cb91494aa 100644 (file)
@@ -35,8 +35,6 @@ static bool layout_load_error=FALSE;
 
 static SMAddCallback *add_cb;
 static SMCfgCallback *cfg_cb;
-static SMPHolderCallback *ph_cb;
-static bool clientwin_was_missing=FALSE;
 
 
 void ioncore_set_sm_callbacks(SMAddCallback *add, SMCfgCallback *cfg)
@@ -53,26 +51,29 @@ void ioncore_get_sm_callbacks(SMAddCallback **add, SMCfgCallback **cfg)
 }
 
 
-void ioncore_set_sm_pholder_callback(SMPHolderCallback *phcb)
-{
-    ph_cb=phcb;
-}
+/*}}}*/
 
 
-void ioncore_clientwin_load_missing()
-{
-    clientwin_was_missing=TRUE;
-}
+/*{{{ Load support functions */
 
 
-/*}}}*/
+static WPHolder **current_ph_p=NULL;
 
 
-/*{{{ Load support functions */
+WPHolder *ioncore_get_load_pholder()
+{
+    if(current_ph_p==NULL){
+        return NULL;
+    }else{
+        WPHolder *ph=*current_ph_p;
+        *current_ph_p=NULL;
+        return ph;
+    }
+}
 
 
 WRegion *create_region_load(WWindow *par, const WFitParams *fp, 
-                            ExtlTab tab)
+                            ExtlTab tab, WPHolder **sm_ph_p)
 {
     char *objclass=NULL, *name=NULL;
     WRegionLoadCreateFn* fn=NULL;
@@ -80,6 +81,7 @@ WRegion *create_region_load(WWindow *par, const WFitParams *fp,
     WRegion *reg=NULL;
     bool grouped=FALSE;
     char *grouped_name=NULL;
+    WPHolder **old_ph_p;
     
     if(!extl_table_gets_s(tab, "type", &objclass))
         return NULL;
@@ -100,19 +102,14 @@ WRegion *create_region_load(WWindow *par, const WFitParams *fp,
 
     free(objclass);
     
-    clientwin_was_missing=FALSE;
+    old_ph_p=current_ph_p;
+    current_ph_p=sm_ph_p;
     
     reg=fn(par, fp, tab);
     
-    if(reg==NULL){
-        if(clientwin_was_missing && add_cb!=NULL && ph_cb!=NULL){
-            WPHolder *ph=ph_cb();
-            if(ph!=NULL){
-                if(!add_cb(ph, tab))
-                    destroy_obj((Obj*)ph);
-            }
-        }
-    }else{
+    current_ph_p=old_ph_p;
+    
+    if(reg!=NULL){
         if(!OBJ_IS(reg, WClientWin)){
             if(extl_table_gets_s(tab, "name", &name)){
                 region_set_name(reg, name);
@@ -121,8 +118,6 @@ WRegion *create_region_load(WWindow *par, const WFitParams *fp,
         }
     }
     
-    ph_cb=NULL;
-    
     return reg;
 }
 
index d15992e402ba8204e2bb78b6af37be3117ee2e67..587dfbfc8e2a5380d9079b36a2cd046067fe7339 100644 (file)
 #include "region.h"
 #include "screen.h"
 #include "pholder.h"
+#include "attach.h"
 
 extern WRegion *create_region_load(WWindow *par, const WFitParams *fp, 
-                                   ExtlTab tab);
+                                   ExtlTab tab, WPHolder **sm_ph_p);
 
 extern bool region_supports_save(WRegion *reg);
 DYNFUN ExtlTab region_get_configuration(WRegion *reg);
@@ -29,12 +30,11 @@ extern bool ioncore_save_layout();
 
 typedef bool SMAddCallback(WPHolder *ph, ExtlTab tab);
 typedef void SMCfgCallback(WClientWin *cwin, ExtlTab tab);
-typedef WPHolder *SMPHolderCallback();
     
 extern void ioncore_set_sm_callbacks(SMAddCallback *add, SMCfgCallback *cfg);
 extern void ioncore_get_sm_callbacks(SMAddCallback **add, SMCfgCallback **cfg);
-extern void ioncore_set_sm_pholder_callback(SMPHolderCallback *phcb);
-extern void ioncore_clientwin_load_missing();
+
+extern WPHolder *ioncore_get_load_pholder();
 
 #endif /* ION_IONCORE_SAVELOAD_H */
 
index 6f1e02980307b35bc1ca029b5b13205520c845d9..2343e9d11ebf5b0e6835289511fdba0abe7fc002 100644 (file)
@@ -107,7 +107,8 @@ WRegion *ioncore_tagged_first(bool untag)
 
 /*EXTL_DOC
  * Iterate over tagged regions until \var{iterfn} returns \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
index 24226a22e0948c3798c16e70327aeab95ab1ce3b..2ea85eb38e57e4cc43ffaa8dec79bef4e1faf7be 100644 (file)
@@ -1,6 +1,13 @@
 
 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] 
 
index b0f576b65993504625f631ebcbfe313c61ab7ce3..de9400e718992ed01bb6e26dd3ab6880c44f68e4 100644 (file)
@@ -82,7 +82,7 @@ typedef Watch ExtlProxy;
 
 #define EXTL_BEGIN_PROXY_OBJ(PROXY, OBJ)       \
     watch_init(PROXY);                         \
-    watch_setup(PROXY, OBJ, obj_dest_handler); \
+    watch_setup(PROXY, OBJ, NULL);             \
     (OBJ)->flags|=OBJ_EXTL_CACHED;
 
 #define EXTL_END_PROXY_OBJ(PROXY, OBJ) \
@@ -94,12 +94,13 @@ typedef Watch ExtlProxy;
 
 extern void extl_uncache(Obj *obj);
 
+/*
 static void obj_dest_handler(Watch *watch, Obj *obj)
 {
     extl_uncache(obj);
     obj->flags&=~OBJ_EXTL_CACHED;
 }
-
+*/
 
 /* 
  * Miscellaneous.
index 88b7a28cb5ecf612d3158b25bbae3d25533d5b4b..c614c60184af5b35d9d104bb2c23a015e5da098e 100644 (file)
@@ -12,7 +12,7 @@ CFLAGS += $(C89_SOURCE) $(POSIX_SOURCE)
 
 SOURCES=misc.c output.c util.c optparser.c parser.c tokenizer.c \
         map.c obj.c objlist.c errorlog.c ptrlist.c rb.c \
-        stringstore.c iterable.c setparam.c
+        stringstore.c iterable.c setparam.c prefix.c
 
 ifdef LIBTU_NO_ERRMSG
 DEFINES += -DLIBTU_NO_ERRMSG
index 5adae397b2e2ac8b29e2a45decdccd2e4408904b..825c172b70a81b7556510863e8ede9ca9264eb64 100644 (file)
@@ -1,6 +1,9 @@
 
 Context:
 
+[Added prefix stuff
+Tuomo Valkonen <tuomov@iki.fi>**20071220180414] 
+
 [CF_NO_GETTEXT
 Tuomo Valkonen <tuomov@iki.fi>**20070620202409] 
 
diff --git a/libtu/prefix.c b/libtu/prefix.c
new file mode 100644 (file)
index 0000000..676ae2e
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * libtu/prefix.c
+ *
+ * Copyright (c) Tuomo Valkonen 1999-2007.
+ *
+ * You may distribute and modify this library under the terms of either
+ * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
+ */
+
+#include <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;
+}
diff --git a/libtu/prefix.h b/libtu/prefix.h
new file mode 100644 (file)
index 0000000..d9d2f21
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * libtu/prefix.h
+ *
+ * Copyright (c) Tuomo Valkonen 1999-2007.
+ *
+ * You may distribute and modify this library under the terms of either
+ * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
+ */
+
+#ifndef _LIBTU_PREFIX_H
+#define _LIBTU_PREFIX_H
+
+extern void prefix_set(const char *binloc, const char *dflt);
+extern char *prefix_add(const char *s);
+extern bool prefix_wrap_simple(bool (*fn)(const char *s), const char *s);
+
+#endif /* _LIBTU_PREFIX_H */
index ed81982d2545595b1e7336f0ce01213c12466b6e..7dbcbab3ac0e31dc0a03ceb7a20b8b33cc72d1ed 100644 (file)
@@ -18,7 +18,13 @@ TARGETS=ion3.1 $(foreach tr, $(TRANSLATIONS), ion3.$(tr).1) \
        pwm3.1 $(foreach tr, $(TRANSLATIONS), pwm3.$(tr).1) \
        $(WELCOME_TARGETS)
 
-MKMAN=$(LUA) ../build/mkman.lua
+MKMAN=$(LUA) ../build/mkman.lua $(MKMAN_DEFS)
+MKMAN_DEFS=-D ETCDIR $(REL)$(ETCDIR) -D DOCDIR $(REL)$(DOCDIR)
+
+ifeq ($(RELOCATABLE),1)
+REL="/..."
+endif
+
 NROFF=nroff -man -Tlatin1
 #FILTERCRAP=perl -p -i -e 's/.\10//g'
 FILTERCRAP=$(LUA) -e 'io.write((string.gsub(io.read("*a"), ".\8", "")))'
@@ -41,16 +47,16 @@ include $(TOPDIR)/build/rules.mk
 ######################################
 
 ion3.1: ion3.in $(CONFIGS)
-       $(MKMAN) -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(CONFIGS)
+       $(MKMAN) -i $< -o $@ $(CONFIGS)
 
 pwm3.1: pwm3.in $(PWM_CONFIGS)
-       $(MKMAN) -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(PWM_CONFIGS)
+       $(MKMAN) -i $< -o $@ $(PWM_CONFIGS)
 
 ion3.%.1: ion3.%.in $(CONFIGS) ../po/%.po
-       $(MKMAN) -po ../po/$*.po -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(CONFIGS)
+       $(MKMAN) -po ../po/$*.po -i $< -o $@ $(CONFIGS)
 
 pwm3.%.1: pwm3.%.in $(PWM_CONFIGS) ../po/%.po
-       $(MKMAN) -po ../po/$*.po -i $< -o $@ -D ETCDIR $(ETCDIR) -D DOCDIR $(DOCDIR) $(PWM_CONFIGS)
+       $(MKMAN) -po ../po/$*.po -i $< -o $@ $(PWM_CONFIGS)
 
 welcome%txt: welcome%head ion3%1
        (cat welcome$*head; \
index 2cf1f25458597b089977c57f0baa922e276b00bd..53efd3c2fbcc8d7b6ef1631ea14a4c105c49323a 100644 (file)
@@ -76,10 +76,14 @@ void input_refit(WInput *input)
 }
 
 
-void input_fitrep(WInput *input, WWindow *par, const WFitParams *fp)
+bool input_fitrep(WInput *input, WWindow *par, const WFitParams *fp)
 {
+    if(par!=NULL && !region_same_rootwin((WRegion*)input, (WRegion*)par))
+        return FALSE;
     input->last_fp=*fp;
     input_do_refit(input, par);
+    
+    return TRUE;
 }
 
 
index 3a39b176311c46810deb4cbf34e8f2a617a18608..e3d06e5b6da3ccbffb7a0273cc617ae8a1be9e28 100644 (file)
@@ -25,7 +25,7 @@ DECLCLASS(WInput){
 extern bool input_init(WInput *input, WWindow *par, const WFitParams *fp);
 extern void input_deinit(WInput *input);
 
-extern void input_fitrep(WInput *input, WWindow *par, const WFitParams *fp);
+extern bool input_fitrep(WInput *input, WWindow *par, const WFitParams *fp);
 extern void input_refit(WInput *input);
 extern void input_cancel(WInput *input);
 extern bool input_rqclose(WInput *input);
index a360378f15a19ada01ff25bd461dc23706048d44..2d46cd5bb08adf6a068f526e127c04ce75574910 100644 (file)
@@ -53,7 +53,8 @@ WBindmap *mod_query_wedln_bindmap=NULL;
 ModQueryConfig mod_query_config={
     250,
     TRUE,
-    FALSE
+    FALSE,
+    TRUE
 };
 
 
@@ -68,6 +69,8 @@ ModQueryConfig mod_query_config={
  *      in milliseconds (default: 250). \\
  *  \var{caseicompl} & (boolean) Turn some completions case-insensitive
  *      (default: false). \\
+ *  \var{substrcompl} & (boolean) Complete on sub-strings in some cases
+ *      (default: ftrue). \\
  * \end{tabularx}
  */
 EXTL_EXPORT
@@ -77,6 +80,7 @@ void mod_query_set(ExtlTab tab)
 
     extl_table_gets_b(tab, "autoshowcompl", &c->autoshowcompl);
     extl_table_gets_b(tab, "caseicompl", &c->caseicompl);
+    extl_table_gets_b(tab, "substrcompl", &c->substrcompl);
     
     if(extl_table_gets_i(tab, "autoshowcompl_delay",
                          &c->autoshowcompl_delay)){
@@ -96,8 +100,9 @@ ExtlTab mod_query_get()
     ExtlTab tab=extl_create_table();
     
     extl_table_sets_b(tab, "autoshowcompl", c->autoshowcompl);
-    extl_table_sets_b(tab, "caseicompl", c->caseicompl);
     extl_table_sets_i(tab, "autoshowcompl_delay", c->autoshowcompl_delay);
+    extl_table_sets_b(tab, "caseicompl", c->caseicompl);
+    extl_table_sets_b(tab, "substrcompl", c->substrcompl);
     
     return tab;
 }
index 2fd127f983082693a2cb7540e2280c7eaa3f777a..f09b7655e352333a08936a6a0681ffdf3cfa16b2 100644 (file)
@@ -18,6 +18,7 @@ DECLSTRUCT(ModQueryConfig){
     int autoshowcompl_delay;
     bool autoshowcompl;
     bool caseicompl;
+    bool substrcompl;
 };
 
 
index 15b03c29428f55a49bbf987af25ed6a373c5c8ac..f4913f3fc272c6e7fd6e90209c21eb647745b53c 100644 (file)
@@ -324,6 +324,8 @@ end
 
 
 local function mk_completion_test(str, sub_ok, casei_ok)
+    local settings=mod_query.get()
+    
     if not str then
         return function(s) return true end
     end
@@ -337,9 +339,10 @@ local function mk_completion_test(str, sub_ok, casei_ok)
         end
     end
     
-    local casei=(casei_ok and mod_query.get().caseicompl)
+    casei_ok=(casei_ok and settings.caseicompl)
+    sub_ok=(sub_ok and settings.substrcompl)
     
-    if not casei then
+    if not casei_ok then
         return mk(str, sub_ok)
     else
         local fn=mk(string.lower(str), sub_ok)
@@ -931,7 +934,7 @@ function mod_query.complete_ssh(str)
     end
     
     local res = {}
-    local tst = mk_completion_test(host, true, false)
+    local tst = mk_completion_test(host, true, true)
     
     for _, v in ipairs(mod_query.ssh_completions) do
         if tst(v) then
@@ -1212,8 +1215,7 @@ function mod_query.query_menu(mplex, sub, themenu, prompt)
     local ntab=xform_menu({}, menu, "")
     
     local function complete(str)
-        -- casei_ok false, because everything is already in lower case
-        return mod_query.complete_keys(ntab, str, true, false)
+        return mod_query.complete_keys(ntab, str, true, true)
     end
     
     local function handle(mplex, str)
index dcf4d2a7e5120faaafbde08b3b83607e0752014c..083cf50f60af4515e10111872750cf99d3d9c416 100644 (file)
@@ -6,17 +6,49 @@
 -- 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)
index c43d2b0ef71594d6d5ccead046e28d88da9d6764..838fd98d354bd5f6f8e4993c3a8e9d9be284c11e 100644 (file)
@@ -635,7 +635,8 @@ bool statusbar_fitrep(WStatusBar *sb, WWindow *par, const WFitParams *fp)
     bool wchg=(REGION_GEOM(sb).w!=fp->g.w);
     bool hchg=(REGION_GEOM(sb).h!=fp->g.h);
     
-    window_do_fitrep(&(sb->wwin), par, &(fp->g));
+    if(!window_fitrep(&(sb->wwin), par, fp))
+        return FALSE;
     
     if(wchg || hchg){
         statusbar_calculate_xs(sb);
index e933dc70494e088c8ab99910e3dcb9d6e0790e17..8d9346a8ecd9a2ee0cb9116eb444e919f7f67556 100644 (file)
@@ -478,8 +478,7 @@ bool tiling_managed_add_default(WTiling *ws, WRegion *reg)
     
     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);
     }
     
@@ -1110,7 +1109,8 @@ WRegion *tiling_current(WTiling *ws)
 /*EXTL_DOC
  * Iterate over managed regions of \var{ws} until \var{iterfn} returns
  * \code{false}.
- * The function itself returns \code{true} if it reaches the end of list
+ * The function is called in protected mode.
+ * This routine returns \code{true} if it reaches the end of list
  * without this happening.
  */
 EXTL_SAFE
index 0bfbed5f1799b75f05e8f3b25a603e901f4c73df..83f310042c5c09aad04ea7686d29d96f7e36ec83 100644 (file)
@@ -42,7 +42,8 @@ EXT_OBJS += ../ioncore/ioncore.a
 
 DEFINES += -DETCDIR=\"$(ETCDIR)\" -DSHAREDIR=\"$(SHAREDIR)\" \
           -DEXTRABINDIR=\"$(EXTRABINDIR)\" -DMODULEDIR=\"$(MODULEDIR)\" \
-          -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\"
+          -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" \
+          -DPWM3_LOCATION=\"$(BINDIR)/pwm3\"
 
 ifndef PWM_ETCDIR
 PWM_ETCDIR = $(ETCDIR)
index a96e3067701a02e3755421596135b52ce861c6a6..178cf76c3ffbc340c5cfa1bc7af363682c4ef576 100644 (file)
--- a/pwm/pwm.c
+++ b/pwm/pwm.c
@@ -19,6 +19,7 @@
 #include <libtu/util.h>
 #include <libtu/optparser.h>
 #include <libtu/errorlog.h>
+#include <libtu/prefix.h>
 #include <libextl/readconfig.h>
 #include <libmainloop/exec.h>
 
@@ -93,20 +94,30 @@ int main(int argc, char*argv[])
     char *efnam=NULL;
     bool may_continue=FALSE;
     bool noerrorlog=FALSE;
-
+    char *localedir;
+    
     libtu_init(argv[0]);
 
-    if(!ioncore_init("pwm3", argc, argv, LOCALEDIR))
+#ifdef CF_RELOCATABLE    
+    prefix_set(argv[0], PWM3_LOCATION);
+#endif
+
+    localedir=prefix_add(LOCALEDIR);
+    
+    if(!ioncore_init("pwm3", argc, argv, localedir))
         return EXIT_FAILURE;
 
-    extl_add_searchdir(EXTRABINDIR); /* ion-completefile */
-    extl_add_searchdir(MODULEDIR);
-    extl_add_searchdir(ETCDIR);
+    if(localedir!=NULL)
+        free(localedir);
+    
+    prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR); /* ion-completefile */
+    prefix_wrap_simple(extl_add_searchdir, MODULEDIR);
+    prefix_wrap_simple(extl_add_searchdir, ETCDIR);
 #ifdef PWM_ETCDIR    
-    extl_add_searchdir(PWM_ETCDIR);
+    prefix_wrap_simple(extl_add_searchdir, PWM_ETCDIR);
 #endif
-    extl_add_searchdir(SHAREDIR);
-    extl_add_searchdir(LCDIR);
+    prefix_wrap_simple(extl_add_searchdir, SHAREDIR);
+    prefix_wrap_simple(extl_add_searchdir, LCDIR);
     extl_set_userdirs("pwm3");
 
     optparser_init(argc, argv, OPTP_MIDLONG, pwm_opts);
index 8a0d53c8f6835c2d8699975ba2b208f1c82fbf8e..26ea7f76c9378023c9b6a56b7def16521a66cbbd 100644 (file)
--- a/system.mk
+++ b/system.mk
@@ -2,13 +2,16 @@
 ## System settings
 ##
 
-
 ##
 ## Installation paths
 ##
 
 PREFIX=/usr/local
 
+# For relocatable build, use the following, and start with absolute path.
+# RELOCATABLE=1
+# PREFIX=
+
 # Unless you are creating a package conforming to some OS's standards, you
 # probably do not want to modify the following directories:
 
index 969839bbddb452c217e730561fadb34181442063..135efaf248dc5855e06103b22c66c3df98670c71 100644 (file)
@@ -107,15 +107,15 @@ if test "x$HOME" != x; then
     usercache="$HOME/.ion3/mancache"
 fi
 
-syscache="@VARDIR@/mancache"
+vardir=${ION_VAR_PATH-@VARDIR@}
+syscache="$vardir/mancache"
+
 
 case "$action" in
     complete)
         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
         
@@ -136,7 +136,7 @@ case "$action" in
         fi
         ;;
     mksyscache)
-        mkdir -p "@VARDIR@"
+        mkdir -p "$vardir"
         scan > "$syscache"
         ;;
 esac
index 1ed1ac9085307474dc7f651257f5bc093d185505..3df31f91f32ca0d67cc9a7fb1eeb03fff41de2d8 100644 (file)
@@ -14,8 +14,9 @@ CFLAGS += $(XOPEN_SOURCE) $(C99_SOURCE)
 
 DEFINES += -DETCDIR=\"$(ETCDIR)\" -DSHAREDIR=\"$(SHAREDIR)\" \
            -DEXTRABINDIR=\"$(EXTRABINDIR)\" -DMODULEDIR=\"$(MODULEDIR)\" \
-          -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\"
-
+          -DLCDIR=\"$(LCDIR)\" -DLOCALEDIR=\"$(LOCALEDIR)\" \
+           -DSTATUSD_LOCATION=\"$(EXTRABINDIR)/ion-statusd\"
+           
 SOURCES = ion-statusd.c exec.c extlrx.c
 
 TARGETS = ion-statusd
index da9e432cd2d9b2970f0f05c31c1d6a45557627c1..5822fe6f897ea850489a00e39613eb408db2d505 100644 (file)
@@ -19,6 +19,7 @@
 #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>
@@ -159,16 +160,21 @@ int main(int argc, char*argv[])
     configtab=extl_table_none();
     
     libtu_init(argv[0]);
-    extl_init();
 
+#ifdef CF_RELOCATABLE    
+    prefix_set(argv[0], STATUSD_LOCATION);
+#endif
+
+    extl_init();
+    
     if(!statusd_register_exports())
         return EXIT_FAILURE;
 
-    extl_add_searchdir(EXTRABINDIR);
-    extl_add_searchdir(MODULEDIR);
-    extl_add_searchdir(ETCDIR);
-    extl_add_searchdir(SHAREDIR);
-    extl_add_searchdir(LCDIR);
+    prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR);
+    prefix_wrap_simple(extl_add_searchdir, MODULEDIR);
+    prefix_wrap_simple(extl_add_searchdir, ETCDIR);
+    prefix_wrap_simple(extl_add_searchdir, SHAREDIR);
+    prefix_wrap_simple(extl_add_searchdir, LCDIR);
     extl_set_userdirs("ion3");
 
     optparser_init(argc, argv, OPTP_MIDLONG, ion_opts);
index 17f05f865f60ae196152c23f03810026c1a06f14..2317f10c70cd28cd0116f8ec617d6c77c669cd03 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
-#define ION_VERSION "3rc-20071109"
+#define ION_VERSION "3rc-20071220"
 #define ION_API_VERSION "3"