Hi,
I'd like to suggest that two changes be made in the Ion port.
- Don't load the status bar by default.
- Add and load the workspace nesting code by default. Permits you to do
this: http://ambientworks.net/~pedro/floating-over-tiled.png
Both modifications are based on the particular use I make of this window
manager, so I'd like to know if other people would be okay with them.
Please reply to me privately.
-p.
Index: Makefile
===================================================================
RCS file: /cvs/ports/x11/ion/Makefile,v
retrieving revision 1.24
diff -u -r1.24 Makefile
--- Makefile 7 Sep 2005 19:53:41 -0000 1.24
+++ Makefile 29 Sep 2005 04:05:15 -0000
@@ -3,6 +3,7 @@
COMMENT= "light, keyboard friendly window manager"
DISTNAME= ion-3ds-20050820
+PKGNAME= ${DISTNAME}p0
CATEGORIES= x11
HOMEPAGE= http://modeemi.cs.tut.fi/~tuomov/ion/
@@ -22,6 +23,9 @@
NO_REGRESS= Yes
LIB_DEPENDS= lua.5,lualib.5::lang/lua
+
+post-install:
+ $(INSTALL_DATA) ${FILESDIR}/*.lua ${PREFIX}/share/examples/ion3
.include <bsd.port.mk>
Index: files/detach.lua
===================================================================
RCS file: files/detach.lua
diff -N files/detach.lua
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ files/detach.lua 29 Sep 2005 04:05:15 -0000
@@ -0,0 +1,407 @@
+-- $OpenBSD$
+-- Fancy management of transcient windows in ion. Mix WIonWS and
+-- WFloatWS on the same "workspace".
+
+-- Written by Matthieu Moy <[EMAIL PROTECTED]> on February 17th 2005.
+-- Public domain.
+
+if not detach then
+ detach = {
+ -- default "passiveness" for the layer 2 floating workspace.
+ passive = true,
+ -- Whether transcient windows should automatically be made floating
+ manage_transcient_with_float = true,
+ }
+end
+
+-- Introduction:
+
+-- This extension exploits some of ion3's new features: It is now
+-- possible to attach objects on a second layer on the screen, which
+-- allows you to have, for example, floating objects on top of a
+-- traditional WIonWS workspace. See
+-- http://www-verimag.imag.fr/~moy/ion/ion3/float-split.png if you
+-- prefer images to explanations :-)
+
+-- A simple setup is to put the following in your cfg_user.lua:
+-- dopath("detach.lua")
+-- detach.setup_hooks()
+
+-- The layer 2 objects can be either passive or non passive. A passive
+-- object will only take the focus when the mouse is over it, while a
+-- non passive object will allways have the focus when shown. (The
+-- scratchpad is an example of non passive object).
+
+-- Layer 2 objects can be hidden. This way, a non passive object can
+-- let the focus to the layer 1.
+
+-- This script attaches two WFloatWS on the layer 2. One is passive,
+-- the other not. The function detach.topmost_transient_to_float sends
+-- a window (or the topmost transcient if the window has transcient)
+-- to one of them (depending on the value of the 3rd parameter).
+
+-- The function detach.toggle_floatws shows or hide the current layer
+-- 2 floating workspace. This is very usefull to get rid of the non
+-- passive WFloatWS, when it is active and you want to give the focus
+-- to a layer 1 object.
+
+
+--------------------
+-- User functions --
+--------------------
+
+
+-- Call this function once and all transcient windows will be managed
+-- as floating frame in layer 2. Additionally, you may define the
+-- "float" winprop for other non transcient windows to manage as
+-- floating frames like this
+--
+-- defwinprop {
+-- class = "Xawtv",
+-- float = true,
+-- }
+--
+-- the winprop "float_passive", if specified, overrides the
+-- detach.passive setting. For example,
+--
+-- defwinprop {
+-- class = "Gkrellm",
+-- float = true,
+-- float_passive = true
+-- }
+--
+-- will make gkrellm start in a passive floating window. (this means
+-- the window will not accept focus)
+--
+-- Note: Adding all the functions to hooks here may conflict with
+-- other functions you could have added to the same hook somewhere
+-- else. If you want to add your personal functions to
+-- clientwin_do_manage_alt, I suggest not adding detach.manager, but
+-- doing something like
+--
+-- if detach.manager(cwin, table) then
+-- return true
+-- end
+--
+-- at the beginning of function you'll use in clientwin_do_manage_alt.
+function detach.setup_hooks ()
+ ioncore.get_hook("clientwin_do_manage_alt"):add(detach.manager)
+
ioncore.get_hook("frame_managed_changed_hook"):add(detach.maybe_leave_layer2)
+ ioncore.get_hook("region_do_warp_alt"):add(detach.skip_l2_warp)
+end
+
+
+-- Submenu to add to the WFrame menu:
+-- Add the line
+-- submenu("Attach", "menudetach"),
+-- to the definition defctxmenu("WFrame", { ... })
+defmenu("menudetach", {
+ menuentry("Topmost transient",
+ "detach.topmost_transient_to_reg(_sub)"),
+ menuentry("To scratchpad",
+ "detach.topmost_transient_to_sp(_sub)"),
+ menuentry("To passive float",
+ "detach.topmost_transient_to_float(_sub, nil, true)"),
+ menuentry("To non passive float",
+ "detach.topmost_transient_to_float(_sub, nil, false)"),
+ })
+
+
+-- Can be called on any object defining screen_of(). shows or hide the
+-- floating workspace on layer 2 of this screen. This applies to the
+-- passive WFloatWS if the second argument is true, and to the non
+-- passive one if it is false. (detach.passive is used if the argument
+-- is nil)
+function detach.toggle_floatws(obj, passive)
+ local screen = obj:screen_of()
+ local sp = detach.find_ws(screen, passive)
+ if sp then
+ screen:l2_set_hidden(sp, 'toggle')
+ end
+end
+
+-- close (and relocate managed of) all layer2 WFloatWS on all screens.
+-- You can call this function from you cfg_user.lua or equivalent to
+-- avoid having layer 2 workspaces at startup.
+function detach.close_all_floatws()
+ local screen = ioncore.find_screen_id(0)
+ local cur = screen
+ repeat
+ detach.close_floatws(cur)
+ cur = ioncore.goto_next_screen()
+ until (cur == screen or cur == nil)
+end
+
+---------------------------------------------------------
+-- Normally, simple users shouldn't need to go further --
+---------------------------------------------------------
+
+
+-- Put the function "detach.topmost_transient(_sub)" in e.g.
+-- defctxmenu("WFrame" {}) or ionframe_bindings to use this.
+function detach.topmost_transient_to_reg(cwin)
+ local l=cwin:managed_list()
+ local trs=l[table.getn(l)]
+ if trs then
+ cwin:manager():attach(trs)
+ end
+end
+
+
+-- send either the topmost transcient or the window itself if it has
+-- no transcient to the scratchpad
+function detach.topmost_transient_to_sp(cwin)
+ local to_detach = cwin
+ local l=cwin:managed_list()
+ local trs=l[table.getn(l)]
+ if trs then
+ to_detach = trs
+ end
+ -- search for the scratchpad
+ local sp = nil
+ for _,r in cwin:screen_of():llist(2) do
+ if (r:name() == "WScratchpad") then
+ sp = r
+ end
+ end
+ sp:attach(to_detach)
+ if not sp:is_active() then
+ mod_sp.toggle_on(cwin:screen_of())
+ end
+end
+
+function detach.ws_name(passive)
+ local passive_loc = detach.passive
+ if passive ~= nil then
+ passive_loc = passive
+ end
+ if passive_loc then
+ return "layer 2 float - passive"
+ else
+ return "layer 2 float - active"
+ end
+end
+
+function detach.find_ws(screen, passive)
+ local name = detach.ws_name(passive)
+ local ws
+ for _,r in screen:llist(2) do
+ if r:name() == name then
+ ws = r
+ end
+ end
+ return ws
+end
+
+function startswith(s, target)
+ return string.sub(s, 0, string.len(target)) == target
+end
+
+function is_l2floatws(ws)
+ return startswith(ws:name(), "layer 2 float - ")
+end
+
+-- send either the topmost transcient or the window itself if it has
+-- no transcient to a floating workspace, on the second layer of the
+-- screen.
+-- the parameter "passive" overrides detach.passive if specified.
+
+-- If "restricted" is true, then, the function will use
+-- ioncore.defer(), and can be called in restricted mode. Otherwise,
+-- the action is immediate.
+function detach.topmost_transient_to_float(cwin, screen, passive, geom,
restricted)
+ local to_detach = cwin
+ local l=cwin:managed_list()
+ local trs=l[table.getn(l)]
+ if trs then
+ to_detach = trs
+ end
+ local scr = screen
+ if scr == nil then
+ scr = cwin:screen_of()
+ end
+ -- use a passive WFloatWS ?
+ local passive_loc = detach.passive
+ if passive ~= nil then
+ passive_loc = passive
+ end
+ -- Find it if it already exists ...
+ local name = detach.ws_name(passive_loc)
+ local fws = detach.find_ws(scr, passive_loc)
+ local geom_loc
+ local oldgeom = to_detach:geom()
+ if geom == nil then
+ -- debug.echo("geom==nil")
+ geom_loc = {x=20, y=20, h=oldgeom.h, w=oldgeom.w}
+ else
+ -- debug.echo("geom=={x="..geom.x..",y="..geom.y.."}")
+ geom_loc = {x=geom.x, y=geom.y,
+ h=oldgeom.h, w=oldgeom.w}
+ end
+ if not restricted then
+ -- ... if not, create it
+ if fws == nil then
+ fws = scr:attach_new{
+ type = "WFloatWS",
+ name = name,
+ layer = 2,
+ passive = passive_loc,
+ switchto = false,
+ }
+ end
+ fws:attach(to_detach)
+ fws:screen_of():l2_set_hidden(fws, 'false')
+ to_detach:rqgeom(geom_loc)
+ ioncore.defer(function()
+ to_detach:goto()
+ end)
+ else
+ ioncore.defer(function()
+ -- ... if not, create it
+ if fws == nil then
+ fws = scr:attach_new{
+ type = "WFloatWS",
+ name = name,
+ layer = 2,
+ passive = passive_loc,
+ switchto = false,
+ }
+ end
+ ioncore.defer(function()
+ fws:screen_of():l2_set_hidden(fws, 'false')
+ fws:attach(to_detach)
+ -- fws:goto()
+ to_detach:manager():goto()
+ to_detach:goto()
+
+ to_detach:manager():rqgeom(geom_loc)
+ ioncore.defer(function ()
+
to_detach:rqgeom({h=geom_loc.h})
+ end)
+ end)
+ end)
+ end
+end
+
+-- close the floating workspaces on layer 2 and relocate the floating
+-- windows in the layer 1 workspace.
+-- Usefull to change the settings of the workspace (passive or
+-- not, ...)
+function detach.close_floatws(region)
+ local screen
+ if region then
+ screen = region:screen_of()
+ end
+ if (screen == nil) then
+ screen = ioncore.find_screen_id(0)
+ end
+ for _,r in screen:llist(2) do
+ if obj_is(r, "WFloatWS") then
+ local fws = r
+ -- relocate windows to layer 1
+ local dest = screen:lcurrent(1):current()
+ for _,fframe in r:managed_list() do
+ for _,cwin in fframe:llist(1) do
+ dest:attach(cwin)
+ cwin:goto()
+ end
+ end
+ -- and close this workspace
+ ioncore.defer(function () fws:rqclose() end)
+ end
+ end
+end
+
+-- Brings a Frame back to the layer 1
+function detach.float_to_layer1 (cwin)
+ local screen = cwin:screen_of()
+ if screen == nil then
+ screen = ioncore.find_screen_id(0)
+ end
+ screen:lcurrent(1):current():attach(cwin)
+ ioncore.defer(function () cwin:goto() end)
+end
+
+-- detach.toggle_float (_sub) to call on a WFrame
+-- Takes a frame from a WIonWS to a WFloatWS in the second layer.
+function detach.toggle_float (cwin)
+ if obj_is(cwin:manager(), "WFloatFrame") then
+ detach.float_to_layer1(cwin)
+ else
+ detach.topmost_transient_to_float(cwin)
+ end
+end
+
+-- candidate for clientwin_do_manage_alt to manage transient. See
+-- documentation for detach.manage_transcient_with_float for details.
+function detach.manager(cwin, table)
+ local wp=ioncore.getwinprop(cwin)
+ if detach.manage_transcient_with_float
+ and table.tfor
+ and not obj_is(table.tfor:manager(), "WFloatWS") then
+
+ local manager = table.tfor:manager()
+ detach.topmost_transient_to_float(cwin,
+ manager:screen_of(),
+ (wp and wp.float_passive),
+ table.geom)
+ table.tfor:goto()
+ return true
+ end
+ if (wp and wp.float) then
+ local screen = cwin:screen_of()
+ if screen == nil then
+ screen = ioncore.find_screen_id(0)
+ end
+ detach.topmost_transient_to_float(cwin,
+ screen,
+ (wp and wp.float_passive),
+ table.geom)
+ return true
+ end
+ return false
+end
+
+-- DEPRECATED. detach.manager() does all this now.
+-- candidate for ionws_placement_alt to manage windows with the
+-- "float" winprop.
+function detach.ionws_manager(cwin, ws, table)
+ local wp=ioncore.getwinprop(cwin)
+ if wp.float then
+ detach.topmost_transient_to_float(cwin,
+ ws:screen_of(),
+ (wp and wp.float_passive),
+ table.geom,
+ true)
+ return true
+ end
+ return false
+end
+
+-- candidate for frame_managed_changed_hook.
+--
+-- If the action is a "remove", and the layer 2 workspace is empty, hide it.
+-- This prevents an empty (and thus invisible) layer 2 floating workspace from
+-- having the focus after its last managed frame is closed, so that focus
+-- returns to layer 1.
+function detach.maybe_leave_layer2(tbl)
+ if tbl.mode == "remove" then
+ local mgr = tbl.reg:manager()
+ if is_l2floatws(mgr) then
+ local l = mgr:managed_list()
+ -- The region will be empty if the only managed region is the one
+ -- currently being removed.
+ if table.getn(l) == 1 and l[1] == tbl.reg then
+ ioncore.defer(function () mgr:screen_of():l2_set_hidden(mgr,
'true') end)
+ end
+ end
+ end
+end
+
+function detach.skip_l2_warp(reg)
+ n = reg:manager():manager():name()
+ if is_l2floatws(reg:manager():manager()) then
+ return true
+ end
+ return false
+end
Index: files/nest-ws.lua
===================================================================
RCS file: files/nest-ws.lua
diff -N files/nest-ws.lua
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ files/nest-ws.lua 29 Sep 2005 04:05:15 -0000
@@ -0,0 +1,15 @@
+-- $OpenBSD$
+-- Nest workspaces inside Frames.
+-- Matthieu Moy <[EMAIL PROTECTED]>, February 15th 2005.
+-- Public domain.
+
+-- This defines a menu to be used as a submenu for WFrames.
+-- Add the line
+-- submenu("Attach", "menuattach"),
+-- to the definition defctxmenu("WFrame", { ... })
+
+defmenu("menuattach", {
+ menuentry("WIonWS", "_:attach_new({type=\"WIonWS\" }):goto()"),
+ menuentry("WFloatWS", "_:attach_new({type=\"WFloatWS\"}):goto()"),
+ menuentry("WPaneWS", "_:attach_new({type=\"WPaneWS\" }):goto()"),
+ })
Index: patches/patch-etc_cfg_ion_lua
===================================================================
RCS file: patches/patch-etc_cfg_ion_lua
diff -N patches/patch-etc_cfg_ion_lua
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-etc_cfg_ion_lua 29 Sep 2005 04:05:15 -0000
@@ -0,0 +1,24 @@
+$OpenBSD$
+--- etc/cfg_ion.lua.orig Sat Aug 20 08:33:49 2005
++++ etc/cfg_ion.lua Wed Sep 28 23:41:29 2005
+@@ -44,7 +44,7 @@ dopath("mod_menu")
+ dopath("mod_ionws")
+ dopath("mod_floatws")
+ dopath("mod_panews")
+-dopath("mod_statusbar")
++--dopath("mod_statusbar")
+ --dopath("mod_dock")
+ dopath("mod_sp")
+
+@@ -56,6 +56,11 @@ dopath("cfg_bindings")
+
+ -- Define some menus (mod_menu required)
+ dopath("cfg_menus")
++
++-- Load workspace nesting stuff.
++dopath("detach")
++dopath("nest-ws")
++detach.setup_hooks()
+
+ -- Load additional user configuration. 'true' as second parameter asks
+ -- Ion not to complain if the file is not found.
Index: patches/patch-etc_cfg_menus_lua
===================================================================
RCS file: patches/patch-etc_cfg_menus_lua
diff -N patches/patch-etc_cfg_menus_lua
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-etc_cfg_menus_lua 29 Sep 2005 04:05:15 -0000
@@ -0,0 +1,10 @@
+$OpenBSD$
+--- etc/cfg_menus.lua.orig Sat Aug 20 08:33:49 2005
++++ etc/cfg_menus.lua Wed Sep 28 23:46:29 2005
+@@ -43,4 +43,6 @@ defctxmenu("WFrame", {
+ menuentry("Clear tags", "ioncore.clear_tags()"),
+ menuentry("Window info", "mod_query.show_clientwin(_, _sub)",
+ "_sub:WClientWin"),
++ submenu("Attach", "menuattach"),
++ submenu("Detach", "menudetach"),
+ })
Index: patches/patch-mod_statusbar_ion-statusd_statusd_mail_lua
===================================================================
RCS file: patches/patch-mod_statusbar_ion-statusd_statusd_mail_lua
diff -N patches/patch-mod_statusbar_ion-statusd_statusd_mail_lua
--- patches/patch-mod_statusbar_ion-statusd_statusd_mail_lua 8 Jun 2005
12:45:55 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,12 +0,0 @@
-$OpenBSD: patch-mod_statusbar_ion-statusd_statusd_mail_lua,v 1.2 2005/06/08
12:45:55 pedro Exp $
---- mod_statusbar/ion-statusd/statusd_mail.lua.orig Tue Jun 7 10:06:02 2005
-+++ mod_statusbar/ion-statusd/statusd_mail.lua Wed Jun 8 09:11:13 2005
-@@ -15,7 +15,7 @@ local mon = "mail"
- local defaults={
- update_interval=10*1000,
- retry_interval=60*10*1000,
-- mbox = os.getenv("MAIL"),
-+ mbox = os.getenv("MAIL") or "/var/mail/" .. os.getenv("USER"),
- files = {}
- }
-
Index: pkg/PLIST
===================================================================
RCS file: /cvs/ports/x11/ion/pkg/PLIST,v
retrieving revision 1.11
diff -u -r1.11 PLIST
--- pkg/PLIST 7 Sep 2005 19:53:41 -0000 1.11
+++ pkg/PLIST 29 Sep 2005 04:05:15 -0000
@@ -67,6 +67,7 @@
share/examples/ion3/cfg_query.lua
share/examples/ion3/cfg_sp.lua
share/examples/ion3/cfg_statusbar.lua
+share/examples/ion3/detach.lua
share/examples/ion3/dock-draw.lua
share/examples/ion3/look.lua
share/examples/ion3/look_brownsteel.lua
@@ -80,6 +81,7 @@
share/examples/ion3/look_wheat2.lua
share/examples/ion3/lookcommon_clean.lua
share/examples/ion3/lookcommon_emboss.lua
+share/examples/ion3/nest-ws.lua
share/ion3/
share/ion3/ion-completeman
share/ion3/ion-runinxterm