Sophie

Sophie

distrib > Mandriva > 2007.0 > i586 > media > contrib-release > by-pkgid > ccf32935cfa6c7c3f091a7b71bf477af > files > 107

ion3-20060524-3mdv2007.0.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">

<!--Converted with LaTeX2HTML 2002-2-1 (1.71)
original version by:  Nikos Drakos, CBLU, University of Leeds
* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<TITLE>3. Basic configuration</TITLE>
<META NAME="description" CONTENT="3. Basic configuration">
<META NAME="keywords" CONTENT="ionconf">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="LaTeX2HTML v2002-2-1">
<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css">

<LINK REL="STYLESHEET" HREF="ionconf.css">

<LINK REL="next" HREF="node5.html">
<LINK REL="previous" HREF="node3.html">
<LINK REL="up" HREF="ionconf.html">
<LINK REL="next" HREF="node5.html">
</HEAD>

<BODY >
<!--Navigation Panel-->
<A NAME="tex2html273"
  HREF="node5.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> 
<A NAME="tex2html267"
  HREF="ionconf.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> 
<A NAME="tex2html261"
  HREF="node3.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> 
<A NAME="tex2html269"
  HREF="node1.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> 
<A NAME="tex2html271"
  HREF="node11.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> 
<BR>
<B> Next:</B> <A NAME="tex2html274"
  HREF="node5.html">4. Graphical styles</A>
<B> Up:</B> <A NAME="tex2html268"
  HREF="ionconf.html">Configuring and extending Ion3</A>
<B> Previous:</B> <A NAME="tex2html262"
  HREF="node3.html">2. Preliminaries: Key concepts</A>
 &nbsp; <B>  <A NAME="tex2html270"
  HREF="node1.html">Contents</A></B> 
 &nbsp; <B>  <A NAME="tex2html272"
  HREF="node11.html">Index</A></B> 
<BR>
<BR>
<!--End of Navigation Panel-->
<!--Table of Child-Links-->
<A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></A>

<UL>
<LI><A NAME="tex2html275"
  HREF="node4.html#SECTION00410000000000000000">3.1 The configuration files</A>
<LI><A NAME="tex2html276"
  HREF="node4.html#SECTION00420000000000000000">3.2 A walk through <I>cfg_ion.lua</I></A>
<LI><A NAME="tex2html277"
  HREF="node4.html#SECTION00430000000000000000">3.3 Keys and rodents</A>
<UL>
<LI><A NAME="tex2html278"
  HREF="node4.html#SECTION00431000000000000000">3.3.1 Binding handlers and special variables</A>
<LI><A NAME="tex2html279"
  HREF="node4.html#SECTION00432000000000000000">3.3.2 Guards</A>
<LI><A NAME="tex2html280"
  HREF="node4.html#SECTION00433000000000000000">3.3.3 Defining the bindings</A>
<LI><A NAME="tex2html281"
  HREF="node4.html#SECTION00434000000000000000">3.3.4 Examples</A>
<LI><A NAME="tex2html282"
  HREF="node4.html#SECTION00435000000000000000">3.3.5 Key specifications</A>
<LI><A NAME="tex2html283"
  HREF="node4.html#SECTION00436000000000000000">3.3.6 Button specifications</A>
<LI><A NAME="tex2html284"
  HREF="node4.html#SECTION00437000000000000000">3.3.7 A further note on the default binding configuration</A>
<LI><A NAME="tex2html285"
  HREF="node4.html#SECTION00438000000000000000">3.3.8 Client window bindings</A>
</UL>
<BR>
<LI><A NAME="tex2html286"
  HREF="node4.html#SECTION00440000000000000000">3.4 Menus</A>
<UL>
<LI><A NAME="tex2html287"
  HREF="node4.html#SECTION00441000000000000000">3.4.1 Defining menus</A>
<LI><A NAME="tex2html288"
  HREF="node4.html#SECTION00442000000000000000">3.4.2 Special menus</A>
<LI><A NAME="tex2html289"
  HREF="node4.html#SECTION00443000000000000000">3.4.3 Defining context menus</A>
<LI><A NAME="tex2html290"
  HREF="node4.html#SECTION00444000000000000000">3.4.4 Displaying menus</A>
</UL>
<BR>
<LI><A NAME="tex2html291"
  HREF="node4.html#SECTION00450000000000000000">3.5 Winprops</A>
<UL>
<LI><A NAME="tex2html292"
  HREF="node4.html#SECTION00451000000000000000">3.5.1 Classes, roles and instances</A>
<LI><A NAME="tex2html293"
  HREF="node4.html#SECTION00452000000000000000">3.5.2 Finding window identification</A>
<LI><A NAME="tex2html294"
  HREF="node4.html#SECTION00453000000000000000">3.5.3 Some common examples</A>
<UL>
<LI><A NAME="tex2html295"
  HREF="node4.html#SECTION00453100000000000000">3.5.3.1 Acrobat Reader</A>
<LI><A NAME="tex2html296"
  HREF="node4.html#SECTION00453200000000000000">3.5.3.2 Fixing a Mozilla Firebird transient</A>
<LI><A NAME="tex2html297"
  HREF="node4.html#SECTION00453300000000000000">3.5.3.3 Forcing newly created windows in named frames</A>
</UL></UL></UL>
<!--End of Table of Child-Links-->
<HR>

<H1><A NAME="SECTION00400000000000000000"></A>
<A NAME="chap:config"></A>
<BR>
3. Basic configuration
</H1>

<P>
This chapter should help your configure Ion to your liking. As  the your
probably already know, Ion uses Lua as a configuration and extension 
language. If you're new to it, you might first want to read some Lua 
documentation as already suggested and pointed to in the Introduction
before continuing with this chapter.

<P>
Section <A HREF="#sec:conffiles">3.1</A>&nbsp;is an overview of the multiple configuration
files Ion uses and as a perhaps more understandable introduction to the
general layout of the configuration files, a walk-through of the main 
configuration file <I>ion.lua</I> is provided in section 
<A HREF="#sec:walkthrough">3.2</A>.
How keys and mouse action are bound to functions is described in detail
in <A HREF="#sec:bindings">3.3</A> and in section <A HREF="#sec:winprops">3.5</A> winprops are
explained. For a reference on exported functions, see section
<A HREF="node7.html#sec:exports">6</A>.

<P>

<H2><A NAME="SECTION00410000000000000000"></A>
<A NAME="sec:conffiles"></A>
<BR>
3.1 The configuration files
</H2>

<P>
Ion3, to which document applies, stores its stock configuration files in
<I>/usr/local/etc/ion3/</I> unless you, the OS package maintainer or 
whoever  installed the package on the system has modified the variables
<TT>PREFIX</TT><A NAME="595"></A> or
<TT>ETCDIR</TT><A NAME="596"></A> in
<I>system.mk</I><A NAME="597"></A> before compiling Ion.
In the first case you probably know where to find the files and in 
the other case the system administrator or the OS package maintainer
should  have provided documentation to point to the correct location. 
If these instructions are no help in locating the correct directory, 
the command <TT>locate cfg_ion.lua</TT> might help provided <TT>updatedb</TT> 
has been run recently. 

<P>
User configuration files go in <I>~/.ion3/</I>. 
Ion always searches the user configuration file directory before the stock
configuration file directory for files. Therefore, if you want to change
some setting, it is advised against that you modify the stock configuration
files in-place as subsequent installs of Ion will restore the stock
configuration files. Instead you should always make a copy of the stock
file in <I>~/.ion3/</I> and modify this file. When searching
for a file, if no extension or path component is given, compiled <I>.lc</I> 
files are attempted before <I>.lua</I> files.

<P>
All the configuration files are named <I>cfg_*.lua</I> with the ''<I>*</I>''
part varying. The configuration file for each module <I>mod_modname</I> is
<I>cfg_modname.lua</I>, with <I>modname</I> varying by the module in
question. The following table summarises these and other configuration
files:

<P>
<TABLE CELLPADDING=3 BORDER="1" WIDTH="100%">
<TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1>File</TD>
<TD ALIGN="LEFT">Description</TD>
</TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>cfg_ion.lua</I></TD>
<TD ALIGN="LEFT">The main configuration file</TD>
</TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>cfg_bindings.lua</I></TD>
<TD ALIGN="LEFT">Most of Ion's bindings are configured here. Bindings that are
    specific to some module are configured in the module's configuration
    file. For details, see section <A HREF="#sec:bindings">3.3</A>.</TD>
</TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>cfg_menus.lua</I></TD>
<TD ALIGN="LEFT">Menu definitions; see section <A HREF="#sec:menus">3.4</A>.</TD>
</TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>cfg_kludges.lua</I></TD>
<TD ALIGN="LEFT">Settings to get some applications behave more nicely have been 
    collected here. See section <A HREF="#sec:winprops">3.5</A>.</TD>
</TR>
<TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>cfg_ionws.lua</I> 
    <I>cfg_floatws.lua</I> 
    <I>cfg_panews.lua</I> 
    <I>cfg_query.lua</I> 
    <I>cfg_menu.lua</I> 
    <I>cfg_dock.lua</I> 
    <I>cfg_statusbar.lua</I> 
    ...</TD>
<TD ALIGN="LEFT">Configuration files for different modules.</TD>
</TR>
</TABLE>

<P>
Additionally, there's <I>look.lua</I> that configures the drawing engine,
but it is covered in chapter <A HREF="node5.html#chap:gr">4</A>.

<P>

<H2><A NAME="SECTION00420000000000000000"></A>
<A NAME="sec:walkthrough"></A>
<BR>
3.2 A walk through <I>cfg_ion.lua</I>
</H2>

<P>
As already mentioned <I>cfg_ion.lua</I> is Ion's main configuration
file. Some basic 'feel' settings are usually configured there and
the necessary modules and other configuration files configuring some 
more specific aspects of Ion are loaded there. In this section we
take a walk through the stock <I>cfg_ion.lua</I>.

<P>
The first thing that is done in that file is set

<P>
<PRE>
MOD1="Mod1+"
MOD2=""
</PRE>
This causes most of Ion's key bindings to use <B>Mod1</B> as the
modifier key. If <TT>MOD2</TT> is set, it is used as modifier for the keys
that don't normally use a modifier. for details on modifiers and key 
binding setup in general see section <A HREF="#sec:bindings">3.3</A>.

<P>
Next we do some basic feel configuration:

<P>
<PRE>
ioncore.set{
    dblclick_delay=250,
    kbresize_delay=1500,
}
</PRE>

<P>
These two will set the delay between button presses in a double click, and
the timeout to quit resize mode in milliseconds.

<P>
<PRE>
ioncore.set{
    opaque_resize=true,
    warp=true,
}
</PRE>

<P>
The first of these two settings enables opaque resize mode: in move/resize
move frames and other objects mirror you actions immediately. If opaque
resize is disabled, a XOR rubber band is shown during the mode instead.
This will, unfortunately, cause Ion to also grab the X server and has some
side effects.

<P>
<PRE>
ioncore.set{
    default_ws_type="WIonWS",
}
</PRE>

<P>
This will set the default workspace type to WIonWS - tiled workspaces.

<P>
To actually be able to do something besides display windows in full screen
mode, we must next load some modules:

<P>
<PRE>
dopath("mod_query")
dopath("mod_menu")
dopath("mod_ionws")
dopath("mod_floatws")
dopath("mod_panews")
dopath("mod_statusbar")
--dopath("mod_dock")
--dopath("mod_sp")
</PRE>

<P>
As already mentioned, each of these modules have their own configuration
files. Finally, additional configuration files are loaded:

<P>
<PRE>
dopath("cfg_kludges")
dopath("cfg_bindings")
dopath("cfg_menus")
</PRE>

<P>
Bindings and menus are defined in <I>cfg_bindings.lua</I> and
<I>cfg_menus.lua</I>. Details on making such definitions follow in
sections <A HREF="#sec:bindings">3.3</A> and <A HREF="#sec:menus">3.4</A>, respectively. 
some kludges or ''winprops'' to make some applications behave better
under Ion are colledted in <I>cfg_kludges.lua</I>; see section
<A HREF="#sec:winprops">3.5</A> for details. In addition to these, this file
lists quite a few statements of the form
<PRE>
ioncore.defshortening("[^:]+: (.*)(&lt;[0-9]+&gt;)", "$1$2$|$1$&lt;...$2")
</PRE>
These are used to configure how Ion attempts to shorten window titles
when they do not fit in a Tab. The first argument is a POSIX regular
expression that is used to match against the title and the next is
a rule to construct a new title of a match occurs. This particular
rule is used to shorten e.g. 'Foo: barbaz&lt;3&gt;' to 'barba...&lt;3&gt;'; for
details see the function reference entry for <A HREF="node7.html#fn:ioncore.defshortening"><TT>ioncore.defshortening</TT></A>.

<P>

<H2><A NAME="SECTION00430000000000000000"></A>
<A NAME="sec:bindings"></A>
<BR>
3.3 Keys and rodents
</H2>

<P>
In the stock configuration file setup, most key and mouse bindings are set
from the file <I>cfg_bindings.lua</I> while module-specific bindings
are set from the modules' main configuration files (<I>cfg_modname.lua</I>).
This, however, does not have to be so as long as the module has been
loaded prior to defining any module-specific bindings.

<P>
Bindings are defined by calling the function 
<A HREF="node7.html#fn:ioncore.defbindings"><TT>defbindings</TT></A> with the ''context'' of the
bindings and the a table of new bindings to make. The context is simply
string indicating one of the classes of regions (or modes such as
WMoveresMode) introduced in section <A HREF="node3.html#sec:objects">2.2</A>, and fully
listed in appendix <A HREF="node9.html#app:fullhierarchy">B</A>, although not all define
a binding map. For example, the following skeleton would be used to 
define new bindings for all frames:

<P>
<PRE>
defbindings("WFrame", {
    -- List of bindings to make goes here.
})
</PRE>

<P>
There has been some confusion among users about the need to define the
''context'' for each binding, so let me try to explain this design
decision here. The thing is that if there was a just a simple 'bind this 
key to this action' method without knowledge of the context, some 
limitations would have to be made on the available actions and writing 
custom handlers would be more complicated. In addition one may want to 
bind the same function to different key for different types of objects.
Indeed, the workspace and frame tab switching functions are the same both
classes being based on WMPlex, and in the stock configuration the 
switch to :th workspaces is bound to <B>Mod1+n</B> while the switch to 
:th tab is bound to the sequence <B>Mod1+k n</B>.

<P>
The following subsections describe how to construct elements of the
binding table. Note that <A HREF="node7.html#fn:ioncore.defbindings"><TT>defbindings</TT></A> adds
the the newly defined bindings to the previous bindings of the context,
overriding duplicates. To unbind an event, set the handler parameter
to <TT>nil</TT> for each of the functions to be described in the following
subsections.

<P>
Also note that when multiple objects want to handle a binding, the 
innermost (when the root window is considered the outermost) active object
in the parent-child hierarchy (see Figure <A HREF="node3.html#fig:parentship">2.2</A>) of objects 
gets to handle the action.

<P>

<H3><A NAME="SECTION00431000000000000000">
3.3.1 Binding handlers and special variables</A>
</H3>

<P>
Unlike in Ion2, in Ion3 binding handlers are not normally passed as
''anonymous functions'', although this is still possible. The preferred
method now is to pass the code of the handler as a string. Two special 
variables are available in this code. These are

<P>
<TABLE CELLPADDING=3 BORDER="1" WIDTH="100%">
<TR><TD ALIGN="LEFT">Variable</TD>
<TD ALIGN="LEFT">Description</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>_</TT> (underscore)</TD>
<TD ALIGN="LEFT">Reference to the object on which the 
      binding was triggered. The object is of the same class as the the
      context of the <A HREF="node7.html#fn:ioncore.defbindings"><TT>defbindings</TT></A> call
      defining the binding.</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>_sub</TT></TD>
<TD ALIGN="LEFT">Usually, the currently active child of the 
      object referred to by <TT>_</TT>, but sometimes (e.g. mouse actions
      on tabs of frames) something else relevant to the action triggering
      the binding.</TD>
</TR>
</TABLE>

<P>
For example, supposing '<TT>_</TT>' is a WFrame, the following
handler should move the active window to the right, if possible:

<P>
<PRE>
"_:inc_index(_sub)"
</PRE>

<P>

<H3><A NAME="SECTION00432000000000000000">
3.3.2 Guards</A>
</H3>

<P>
To suppress error messages, each binding handler may also be accompanied
by a ''guard'' expression that blocks the handler from being called when
the guard condition is not met. Currently the following guard expressions
are supported:

<P>
<TABLE CELLPADDING=3 BORDER="1" WIDTH="100%">
<TR><TD ALIGN="LEFT">Guard</TD>
<TD ALIGN="LEFT">Description</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>"_sub:non-nil"</TT></TD>
<TD ALIGN="LEFT">The <TT>_sub</TT> parameter must be set.</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>"_sub:SomeClass"</TT></TD>
<TD ALIGN="LEFT">The <TT>_sub</TT> parameter must be member
      of class SomeClass.</TD>
</TR>
</TABLE>

<P>

<H3><A NAME="SECTION00433000000000000000"></A>
<A NAME="sec:binddef"></A>
<BR>
3.3.3 Defining the bindings
</H3>

<P>
The descriptions of the individual bindings in the binding table argument
to <A HREF="node7.html#fn:ioncore.defbindings"><TT>defbindings</TT></A> should be constructed with the following
functions.

<P>
Key presses:

<UL>
<LI><A HREF="#fn:kpress"><TT>kpress</TT></A><TT>(keyspec, handler [, guard])</TT>,
</LI>
<LI><A HREF="#fn:kpress_wait"><TT>kpress_wait</TT></A><TT>(keyspec, handler [, guard])</TT> and
</LI>
<LI><A HREF="#fn:submap"><TT>submap</TT></A><TT>(keyspec, { ... more key bindings ... })</TT>.
</LI>
</UL>
Mouse actions:

<UL>
<LI><A HREF="#fn:mclick"><TT>mclick</TT></A><TT>(buttonspec, handler [, guard])</TT>,
</LI>
<LI><A HREF="#fn:mdblclick"><TT>mdblclick</TT></A><TT>(buttonspec, handler [, guard])</TT>, 
</LI>
<LI><A HREF="#fn:mpress"><TT>mpress</TT></A><TT>(buttonspec, handler [, guard])</TT> and
</LI>
<LI><A HREF="#fn:mdrag"><TT>mdrag</TT></A><TT>(buttonspec, handler [, guard])</TT>.
</LI>
</UL>

<P>
The actions that most of these functions correspond to should be clear
and as explained in the reference, <A HREF="#fn:kpress_wait"><TT>kpress_wait</TT></A> is simply
<A HREF="#fn:kpress"><TT>kpress</TT></A> with a flag set instructing Ioncore wait for all
modifiers to be released before processing any further actions.
This is to stop one from accidentally calling e.g.
<A HREF="node7.html#fn:WRegion.rqclose"><TT>WRegion.rqclose</TT></A> multiple times in a row. The <A HREF="#fn:submap"><TT>submap</TT></A>
function is used to define submaps or ''prefix maps''. The second
argument to this function is table listing the key press actions
(<A HREF="#fn:kpress"><TT>kpress</TT></A>) in the submap

<P>
The parameters <TT>keyspec</TT> and <TT>buttonspec</TT> are explained below
in detail. The parameter <TT>handler</TT> is the handler for the binding,
and the optional parameter <TT>guard</TT> its guard. These should normally
be strings as explained above. 

<P>

<H3><A NAME="SECTION00434000000000000000">
3.3.4 Examples</A>
</H3>

<P>
For example, to just bind the key <B>Mod1+1</B> to switch to the first
workspace and <B>Mod1+Right</B> to the next workspace, you would make the
following call
<PRE>
defbindings("WScreen", {
    kpress("Mod1+Right", "_:switch_next()"),
    kpress("Mod1+1", "_:switch_nth(1)"),
})
</PRE>

<P>
Note that <TT>_:switch_nth(1)</TT> is the same as calling
<A HREF="node7.html#fn:WMPlex.switch_next"><TT>WMPlex.switch_next</TT></A><TT>(_, 1)</TT> as WScreen inherits
WMPlex and this is where the function is actually defined.

<P>
Similarly to the above example, to bind the key sequence <B>Mod1+k n</B> 
switch to the next managed object within a frame, and <B>Mod1+k 1</B> to the
first, you would issue the following call:
<PRE>
defbindings("WFrame", {
    submap("Mod1+K", {
        kpress("Right", "_:switch_next()"),
        kpress("1", "_:switch_nth(1)"),
   }),
})
</PRE>

<P>

<H3><A NAME="SECTION00435000000000000000">
3.3.5 Key specifications</A>
</H3>

<P>
As seen above, the functions that create key binding specifications require
a <TT>keyspec</TT> argument. This argument should be a string containing the
name of a key as listed in the X header file <I>keysymdef.h</I><A NAME="tex2html7"
  HREF="#foot856"><SUP>3.1</SUP></A> without the <TT>XK_</TT> prefix.
<A NAME="857"></A>
Most of the key names are quite intuitive while some are not. For example,
the <B>Enter</B> key on the main part of the keyboard has the less common
name <B>Return</B> while the one the numpad is called <B>KP_Enter</B>.

<P>
The <TT>keyspec</TT> string may optionally have multiple ''modifier'' names
followed by a plus sign (<TT>+</TT>) as a prefix. X defines the following
modifiers:
<BLOCKQUOTE>
<B>Shift</B>, <B>Control</B>, <B>Mod1</B> to <B>Mod5</B>,
<B>AnyModifier</B> and <B>Lock</B>.
<A NAME="858"></A>
<A NAME="859"></A>
<A NAME="860"></A>
<A NAME="861"></A>
<A NAME="862"></A>

</BLOCKQUOTE>

<P>
X allows binding all of these modifiers to almost any key and while this
list of modifiers does not explicitly list keys such as 
<B>Alt</B><A NAME="863"></A> that are common on modern keyboards, such
keys are bound to one of the <B>ModN</B>. On systems running XFree86
<B>Alt</B> is usually <B>Mod1</B>. On Suns <B>Mod1</B> is the diamond key
and <B>Alt</B> something else. One of the ''flying window'' keys on so
called Windows-keyboards is probably mapped to <B>Mod3</B> if you have
such a key. Use the program <I>xmodmap</I><A NAME="864"></A>
to find out what exactly is bound where. 

<P>
Ion defaults to <B>AnyModifier</B> in submaps. This can sometimes lead to
unwanted effects when the same key is used with and without explicitly
specified modifiers in nested regions. For this reason, Ion recognises
<B>NoModifier</B> as a special modifier that can be used to reset this
default.

<P>
Ion ignores the <B>Lock</B> modifier and any <B>ModN</B> ()
bound to <B>NumLock</B><A NAME="865"></A> or
<B>ScrollLock</B><A NAME="866"></A>
by default because such<A NAME="tex2html8"
  HREF="#foot829"><SUP>3.2</SUP></A> locking keys may otherwise
cause confusion.

<P>

<H3><A NAME="SECTION00436000000000000000">
3.3.6 Button specifications</A>
</H3>

<P>
Button specifications are similar to key definitions but now
instead of specifying modifiers and a key, you specify modifiers
and one of the button names <B>Button1</B> to
<B>Button5</B><A NAME="867"></A>. Additionally the
specification may end with an optional area name following an @-sign.
Only frames currently support areas, and the supported values in this
case are
<TT>"border"</TT>, <TT>"tab"</TT>, <TT>"empty_tab"</TT>, <TT>"client"</TT> and
<TT>nil</TT> (for the whole frame).

<P>
For example, the following code binds dragging a tab with the first 
button pressed to initiate tab drag&amp;drop handling:

<P>
<PRE>
defbindings("WFrame", {
    mdrag("Button1@tab", "_:p_tabdrag()"),
})
</PRE>

<P>

<H3><A NAME="SECTION00437000000000000000">
3.3.7 A further note on the default binding configuration</A>
</H3>

<P>
The default binding configuration contains references to the variables
<TT>MOD1</TT> and <TT>MOD2</TT> instead of directly using the default
values of <TT>"Mod1+"</TT> and <TT>""</TT> (nothing). As explained in
section <A HREF="#sec:walkthrough">3.2</A>, the definitions of these variables
appear in <I>cfg_ion.lua</I>. This way you can easily change the the
modifiers used by all bindings in the default configuration without 
changing the whole binding configuration. Quite a few people prefer 
to use the Windows keys as modifiers because many applications already
use <B>Alt</B>. Nevertheless, <B>Mod1</B> is the default as a key bound 
to it is available virtually everywhere.

<P>

<H3><A NAME="SECTION00438000000000000000">
3.3.8 Client window bindings</A>
</H3>

<P>
As client windows do not have a binding map of their own due to technical
reasons, it is necessary to call client window functions by specifying the
bindings somewhere else. In the stock configuration file setup this is done
among WMPlex bindings, setting the guard to <TT>_sub:WClientWin</TT>
and using <TT>_sub</TT> to refer to the client window.

<P>
For example, the full screen toggle key is bound like this:

<P>
<PRE>
defbindings("WMPlex", {
    kpress_wait("Mod1+Return", 
                "_:toggle_fullscreen()", "_sub:WClientWin"),
})
</PRE>

<P>

<P>

<H2><A NAME="SECTION00440000000000000000"></A>
<A NAME="sec:menus"></A>
<BR>
3.4 Menus
</H2>

<P>

<H3><A NAME="SECTION00441000000000000000">
3.4.1 Defining menus</A>
</H3>

<P>
<A NAME="1100"></A>
<A NAME="1152"></A>
<A NAME="1153"></A>
<A NAME="1154"></A>
In the stock configuration file setup, menus are defined in the file
<I>cfg_menus.lua</I> as previously mentioned. The <I>mod_menu</I> module
must be loaded for one to be able to define menus, and this is done with
the function <A HREF="#fn:mod_menu.defmenu"><TT>defmenu</TT></A> provided by it.

<P>
Here's an example of the definition of a rather simple menu with a submenu:

<P>
<PRE>
defmenu("exitmenu", {
    menuentry("Restart", "ioncore.restart()"),
    menuentry("Exit", "ioncore.shutdown()"),
})

defmenu("mainmenu", {
    menuentry("Lock screen", "ioncore.exec('xlock')"),
    menuentry("Help", "mod_query.query_man(_)"),
    submenu("Exit", "exitmenu"),
})
</PRE>

<P>
The <A HREF="#fn:mod_menu.menuentry"><TT>menuentry</TT></A> function is used to create an entry in the 
menu with a title and an entry handler to be called when the menu entry
is activated. The parameters to the handler are similar to those of binding
handlers, and usually the same as those of the binding that opened the menu.

<P>
The <A HREF="#fn:mod_menu.submenu"><TT>submenu</TT></A> function is used to insert a submenu at that 
point in the menu. (One could as well just pass a table with the menu
entries, but it is not encouraged.)

<P>

<H3><A NAME="SECTION00442000000000000000">
3.4.2 Special menus</A>
</H3>

<P>
The menu module predefines the following special menus. These can be used
just like the menus defined as above.

<P>
<TABLE CELLPADDING=3 BORDER="1" WIDTH="100%">
<TR><TD ALIGN="LEFT">Menu name</TD>
<TD ALIGN="LEFT">Description</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>windowlist</TT></TD>
<TD ALIGN="LEFT">List of all client windows. Activating an entry jumps to that window.</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>workspacelist</TT></TD>
<TD ALIGN="LEFT">List of all workspaces. Activating an entry jumps to that workspaces.</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>stylemenu</TT></TD>
<TD ALIGN="LEFT">List of available <I>look_*.lua</I> style files. Activating an entry
    loads that style and ask to save the selection.</TD>
</TR>
<TR><TD ALIGN="LEFT"><TT>ctxmenu</TT></TD>
<TD ALIGN="LEFT">Context menu for given object.</TD>
</TR>
</TABLE>

<P>

<H3><A NAME="SECTION00443000000000000000">
3.4.3 Defining context menus</A>
</H3>

<P>
The ''ctxmenu'' is a special menu that is assembled from a defined context
menu for the object for which the menu was opened for, but also includes
the context menus for the manager objects as submenus.

<P>
Context menus for a given region class are defined with the
<A HREF="#fn:mod_menu.defctxmenu"><TT>defctxmenu</TT></A> function. This is other ways similar to
<A HREF="#fn:mod_menu.defmenu"><TT>defmenu</TT></A>, but the first argument instead being the name
of the menu, the name of the region class to define context menu for.
For example, here's part of the stock WFrame context menu 
definition:

<P>
<PRE>
defctxmenu("WFrame", {
    menuentry("Close", "WRegion.rqclose_propagate(_, _sub)"),
    menuentry("Kill",  "WClientWin.kill(_sub)", "_sub:WClientWin"),
})
</PRE>

<P>

<H3><A NAME="SECTION00444000000000000000"></A>
<A NAME="sec:menudisp"></A>
<BR>
3.4.4 Displaying menus
</H3>

<P>
The following functions may be used to display menus from binding
handlers (and elsewhere):

<P>
<TABLE CELLPADDING=3 BORDER="1" WIDTH="100%">
<TR><TD ALIGN="LEFT">Function</TD>
<TD ALIGN="LEFT">Description</TD>
</TR>
<TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:mod_menu.menu"><TT>mod_menu.menu</TT></A></TD>
<TD ALIGN="LEFT">Keyboard (or mouse) operated menus that open in the bottom-left corner
      of a screen or frame.</TD>
</TR>
<TR><TD ALIGN="LEFT"><A HREF="#fn:mod_menu.bigmenu"><TT>mod_menu.bigmenu</TT></A></TD>
<TD ALIGN="LEFT">Same as previous, but uses another graphical style.</TD>
</TR>
<TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:mod_menu.pmenu"><TT>mod_menu.pmenu</TT></A></TD>
<TD ALIGN="LEFT">Mouse-operated drop-down menus. This function can only be called from a
      mouse press or drag handler.</TD>
</TR>
<TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:mod_menu.grabmenu"><TT>mod_menu.grabmenu</TT></A></TD>
<TD ALIGN="LEFT">A special version of <A HREF="node7.html#fn:mod_menu.menu"><TT>mod_menu.menu</TT></A> that grabs the keyboard
      and is scrolled with a given key until all modifiers have been released,
      after which the selected entry is activated. This function is meant to 
      be used for implementing, for example, Win***s-style <B>Alt-Tab</B> 
      handling.<A NAME="tex2html9"
  HREF="#foot1155"><SUP>3.3</SUP></A></TD>
</TR>
</TABLE>

<P>
The <A HREF="node7.html#fn:mod_menu.grabmenu"><TT>grabmenu</TT></A> function takes the extra key parameter, but
aside from that each of these functions takes three arguments, which when
called from a binding handler, should be the parameters to the handler, and
the name of the menu. For example, the following snippet of of code binds
the both ways to open a context menu for a frame:

<P>
<PRE>
defbindings("WFrame", {
    kpress(MOD1.."M", "mod_menu.menu(_, _sub, 'ctxmenu')"),
    mpress("Button3", "mod_menu.pmenu(_, _sub, 'ctxmenu')"),
})
</PRE>

<P>

<H2><A NAME="SECTION00450000000000000000"></A>
<A NAME="sec:winprops"></A>
<BR>
3.5 Winprops
</H2>

<P>
The so-called ''winprops''<A NAME="1243"></A> can be used to change how
specific windows are handled and to set up some kludges to deal with
badly behaving applications. They are defined by calling the function
<TT>defwinprop</TT> with a table containing the properties to set and the
necessary information to identify a window. The currently supported
winprops are listed below, and the subsequent subsections explain the
usual method of identifying windows, and how to obtain this information.

<P>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>acrobatic</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1382"></A>
    Set this to <TT>true</TT> for Acrobat Reader. It has an annoying
    habit of trying to manage its dialogs instead of setting them as
    transients and letting the window manager do its job, causing
    Ion and acrobat go a window-switching loop when a dialog is
    opened.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>aspect</TT> (table)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1383"></A>
    The table should contain the entries <TT>w</TT> and <TT>h</TT> that
    override application-supplied aspect ratio hint.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>fullscreen</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1384"></A>
    Should the window be initially in full screen mode?

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>ignore_cfgrq</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1385"></A>
    Should configure requests on the window be ignored?
    Only has effect on windows on floatws:s.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>ignore_net_active_window</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1386"></A>
    Ignore extended WM hints <TT>_NET_ACTIVE_WINDOW</TT> request.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>ignore_resizeinc</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1387"></A>
    Should application supplied size increments be ignored?

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>jumpto</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1388"></A>
    Should a newly created client window always be made
    active, even if the allocated frame isn't.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>max_size</TT> (table)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1389"></A>
    The table should contain the entries <TT>w</TT> and <TT>h</TT> that
    override application-supplied maximum size hint.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>min_size</TT> (table)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1390"></A>
    Similar to <TT>max_size</TT> but for the minimum size hint.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>oneshot</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1391"></A>
    Discard this winprop after first use.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>switchto</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1392"></A>
    Should a newly mapped client window be switched to within
    its frame.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>target</TT> (string)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1393"></A>
    The name of an object (workspace, frame) that should manage 
    windows of this type.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>transient_mode</TT> (string)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1394"></A>
    "normal": No change in behaviour. "current": The window
    should be thought of as a transient for the current active
    client window (if any) even if it is not marked as a
    transient by the application. "off": The window should be
    handled as a normal window even if it is marked as a
    transient by the application.

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>transients_at_top</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1395"></A>
    When transients are managed by the client window itself (as it
    is the case on tiled workspaces), should the transients be
    placed at the top of the window instead of bottom?

</DD>
</DL>

<P>

  <DL>
<DT><STRONG>Winprop:</STRONG></DT>
<DD><TT>transparent</TT> (boolean)
      
</DD>
<DT><STRONG>Description:</STRONG></DT>
<DD><A NAME="1396"></A>
    Should frames be made transparent when this window is selected? 
<BR>  
  
</DD>
</DL>

<P>

<H3><A NAME="SECTION00451000000000000000"></A>
<A NAME="sec:classesrolesinstances"></A>
<BR>
3.5.1 Classes, roles and instances
</H3>

<P>
The identification information in the winprop specification is usually the
<TT>class</TT><A NAME="1397"></A>,
<TT>role</TT><A NAME="1398"></A>,
<TT>instance</TT><A NAME="1399"></A> and
<TT>name</TT>
of the window. The <TT>name</TT> field is a Lua-style regular expression
matched against the window's title and the rest are strings that must
exactly much the corresponding window information. It is not necessary
to specify all of these fields.

<P>
Ion looks for a matching winprop in the order listed by the following
table. An 'E' indicates that the field must be set in the winprop
and it must match the window's corresponding property exactly or, in
case of <TT>name</TT>, the regular expression must match the window
title. An asterisk '*' indicates that a winprop where the field is
not specified (or is itself an asterisk in case of the first three
fields) is tried.

<P>
<DIV ALIGN="CENTER">
<TABLE CELLPADDING=3 BORDER="1">
<TR><TD ALIGN="LEFT"><TT>class</TT></TD>
<TD ALIGN="LEFT"><TT>role</TT></TD>
<TD ALIGN="LEFT"><TT>instance</TT></TD>
<TD ALIGN="LEFT"><TT>name</TT></TD>
</TR>
<TR><TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
</TR>
<TR><TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">*</TD>
</TR>
<TR><TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">*</TD>
<TD ALIGN="LEFT">E</TD>
</TR>
<TR><TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">*</TD>
<TD ALIGN="LEFT">*</TD>
</TR>
<TR><TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">*</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">E</TD>
</TR>
<TR><TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">*</TD>
<TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">*</TD>
</TR>
<TR><TD ALIGN="LEFT">E</TD>
<TD ALIGN="LEFT">*</TD>
<TD ALIGN="LEFT">*</TD>
<TD ALIGN="LEFT">E</TD>
</TR>
<TR><TD ALIGN="LEFT">&nbsp;</TD>
<TD ALIGN="LEFT">&nbsp;</TD>
<TD ALIGN="LEFT">&nbsp;</TD>
<TD ALIGN="LEFT">etc.</TD>
</TR>
</TABLE>
</DIV>

<P>
If there are multiple winprops with other identification information 
the same but different <TT>name</TT>, the longest match is chosen.

<P>

<H3><A NAME="SECTION00452000000000000000">
3.5.2 Finding window identification</A>
</H3>

<P>
The 'Window info' context menu entry (<B>Mod1+M</B> or <B>Button3</B> on a tab)
can be used to list the identification information required to set winprops
for a window and all the transient windows managed within it. 

<P>
<A NAME="1355"></A> 
Another way to get the identification information is to use <TT>xprop</TT>.
Simply run To get class and instance, simply run <TT>xprop WM_CLASS</TT>
and click on the particular window of interest. The class is the latter of
the strings while the instance is the former.  To get the role - few
windows have this property - use the command <TT>xprop WM_ROLE</TT>. 
This method, however, will not work on transients. 

<P>
<A NAME="1359"></A>
So-called ''transient windows'' are usually short-lived dialogs (although
some programs abuse this property) that have a parent window that they are
''transient for''. On tiled workspaces Ion displays these windows 
simulatenously with the parent window at the bottom of the same frame.
Unfortunately <TT>xprop</TT> is stupid and can't cope with this situation,
returning the parent window's properties when the transient is clicked on.
For this reason you'll have to do a little extra work to get the properties
for that window.<A NAME="tex2html11"
  HREF="#foot1401"><SUP>3.4</SUP></A>
<P>
Finally, it should be mentioned that too many authors these days
''forget'' to set this vital identification to anything meaningful:
everything except name is the same for all of the programs's 
windows, for example.

<P>

<H3><A NAME="SECTION00453000000000000000">
3.5.3 Some common examples</A>
</H3>

<P>

<H4><A NAME="SECTION00453100000000000000">
3.5.3.1 Acrobat Reader</A>
</H4>

<P>
The following is absolutely necessary for Acrobat reader:

<P>
<PRE>
defwinprop{
    class = "AcroRead",
    instance = "documentShell",
    acrobatic = true,
}
</PRE>

<P>

<H4><A NAME="SECTION00453200000000000000">
3.5.3.2 Fixing a Mozilla Firebird transient</A>
</H4>

<P>
Mozilla Firebird (0.7) incorrectly does not set the <TT>WM_TRANSIENT_FOR</TT> 
property for the dialog that is used to ask the action to take for a file.
It, however, sets the the property point to the main window for the save
dialog. This can be annoying and confusing, as the first dialog is not 
closed before the second is displayed.

<P>
We'd like the first dialog to be transient to the main window. The closest
we can get to that is to consider it transient to the current window (if
there's one). Unfortunately Firebird does not set any meaningful classes, 
instances or roles for the windows, so we'll have to rely on an ugly title
match.

<P>
<PRE>
defwinprop{
    class = "MozillaFirebird-bin",
    name = "Opening .*",
    transient_mode = "current",
}
</PRE>

<P>

<H4><A NAME="SECTION00453300000000000000">
3.5.3.3 Forcing newly created windows in named frames</A>
</H4>

<P>
The following winprop should place xterm started with command-line parameter
<TT>-name sysmon</TT> and running a system monitoring program in a
particular frame:
<PRE>
defwinprop{
    class = "XTerm",
    instance = "sysmon",
    target = "sysmonframe",
}
</PRE>

<P>
For this example to work, we have to somehow create a frame named
<TT>sysmonframe</TT>. One way to do this is to make the following
call in the <B>Mod1+F3</B> Lua code query:

<P>
<PRE>
mod_query.query_renameframe(_)
</PRE>

<P>
Recall that <TT>_</TT> points to the multiplexer (frame or screen) in which 
the query was opened. Running this code should open a new query prefilled
with the current name of the frame. In our example we would change the 
name to <TT>sysmonframe</TT>, but we could just as well have used the 
default name formed from the frame's class name and an instance number.

<P>

<P>
<BR><HR><H4>Footnotes</H4>
<DL>
<DT><A NAME="foot856">...keysymdef.h</A><A
 HREF="node4.html#tex2html7"><SUP>3.1</SUP></A></DT>
<DD>This file can usually be found in the directory
<I>/usr/X11R6/include/X11/</I>.

</DD>
<DT><A NAME="foot829">... such</A><A
 HREF="node4.html#tex2html8"><SUP>3.2</SUP></A></DT>
<DD>Completely useless keys that should be
gotten rid of in the author's opinion.

</DD>
<DT><A NAME="foot1155">... handling.</A><A
 HREF="node4.html#tex2html9"><SUP>3.3</SUP></A></DT>
<DD>See the <I>wcirculate.lua</I> script in the Ion 
        scripts repository <TT><A NAME="tex2html10"
  HREF="http://iki.fi/tuomov/repos/ion-scripts-3/">http://iki.fi/tuomov/repos/ion-scripts-3/</A></TT>.

</DD>
<DT><A NAME="foot1401">... window.</A><A
 HREF="node4.html#tex2html11"><SUP>3.4</SUP></A></DT>
<DD>There's a patch to <TT>xprop</TT> to
fix this, but nothing seems to be happening with respect to including it in 
XFree86.

</DD>
</DL><HR>
<!--Navigation Panel-->
<A NAME="tex2html273"
  HREF="node5.html">
<IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> 
<A NAME="tex2html267"
  HREF="ionconf.html">
<IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> 
<A NAME="tex2html261"
  HREF="node3.html">
<IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> 
<A NAME="tex2html269"
  HREF="node1.html">
<IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> 
<A NAME="tex2html271"
  HREF="node11.html">
<IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> 
<BR>
<B> Next:</B> <A NAME="tex2html274"
  HREF="node5.html">4. Graphical styles</A>
<B> Up:</B> <A NAME="tex2html268"
  HREF="ionconf.html">Configuring and extending Ion3</A>
<B> Previous:</B> <A NAME="tex2html262"
  HREF="node3.html">2. Preliminaries: Key concepts</A>
 &nbsp; <B>  <A NAME="tex2html270"
  HREF="node1.html">Contents</A></B> 
 &nbsp; <B>  <A NAME="tex2html272"
  HREF="node11.html">Index</A></B> 
<!--End of Navigation Panel-->

</BODY>
</HTML>