<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002-1 (1.69) 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-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="tex2html253" HREF="node5.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html247" HREF="ionconf.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html241" HREF="node3.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html249" HREF="node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html251" HREF="node10.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html254" HREF="node5.html">4. Graphical styles</A> <B> Up:</B> <A NAME="tex2html248" HREF="ionconf.html">Ion: Configuring and extending</A> <B> Previous:</B> <A NAME="tex2html242" HREF="node3.html">2. Preliminaries: Key concepts</A> <B> <A NAME="tex2html250" HREF="node1.html">Contents</A></B> <B> <A NAME="tex2html252" HREF="node10.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="tex2html255" HREF="node4.html#SECTION00410000000000000000">3.1 The configuration files</A> <LI><A NAME="tex2html256" HREF="node4.html#SECTION00420000000000000000">3.2 A walk through <I>ion.lua</I></A> <LI><A NAME="tex2html257" HREF="node4.html#SECTION00430000000000000000">3.3 Keys and rodents</A> <UL> <LI><A NAME="tex2html258" HREF="node4.html#SECTION00431000000000000000">3.3.1 The binding setup functions</A> <UL> <LI><A NAME="tex2html259" HREF="node4.html#SECTION00431100000000000000">3.3.1.1 Ioncore binding setup functions</A> <LI><A NAME="tex2html260" HREF="node4.html#SECTION00431200000000000000">3.3.1.2 IonWS module binding setup functions</A> <LI><A NAME="tex2html261" HREF="node4.html#SECTION00431300000000000000">3.3.1.3 FloatWS module binding setup functions</A> <LI><A NAME="tex2html262" HREF="node4.html#SECTION00431400000000000000">3.3.1.4 Query module binding setup functions</A> <LI><A NAME="tex2html263" HREF="node4.html#SECTION00431500000000000000">3.3.1.5 Menu module binding setup functions</A> </UL> <LI><A NAME="tex2html264" HREF="node4.html#SECTION00432000000000000000">3.3.2 Defining the bindings</A> <LI><A NAME="tex2html265" HREF="node4.html#SECTION00433000000000000000">3.3.3 An example</A> <LI><A NAME="tex2html266" HREF="node4.html#SECTION00434000000000000000">3.3.4 Another example</A> <LI><A NAME="tex2html267" HREF="node4.html#SECTION00435000000000000000">3.3.5 Key and button specifications</A> <LI><A NAME="tex2html268" HREF="node4.html#SECTION00436000000000000000">3.3.6 A further note on the default binding configuration</A> <LI><A NAME="tex2html269" HREF="node4.html#SECTION00437000000000000000">3.3.7 Client window bindings</A> </UL> <BR> <LI><A NAME="tex2html270" HREF="node4.html#SECTION00440000000000000000">3.4 Winprops</A> <UL> <LI><A NAME="tex2html271" HREF="node4.html#SECTION00441000000000000000">3.4.1 Classes, roles and instances</A> <LI><A NAME="tex2html272" HREF="node4.html#SECTION00442000000000000000">3.4.2 Finding window identification with <TT>xprop</TT></A> <LI><A NAME="tex2html273" HREF="node4.html#SECTION00443000000000000000">3.4.3 Supported winprops</A> <LI><A NAME="tex2html274" HREF="node4.html#SECTION00444000000000000000">3.4.4 Some common examples</A> <UL> <LI><A NAME="tex2html275" HREF="node4.html#SECTION00444100000000000000">3.4.4.1 Acrobat Reader</A> <LI><A NAME="tex2html276" HREF="node4.html#SECTION00444200000000000000">3.4.4.2 Fixing a Mozilla Firebird transient</A> <LI><A NAME="tex2html277" HREF="node4.html#SECTION00444300000000000000">3.4.4.3 Forcing newly created windows in named frames</A> </UL> </UL> <BR> <LI><A NAME="tex2html278" HREF="node4.html#SECTION00450000000000000000">3.5 The query library</A> <LI><A NAME="tex2html279" HREF="node4.html#SECTION00460000000000000000">3.6 Menus</A> <UL> <LI><A NAME="tex2html280" HREF="node4.html#SECTION00461000000000000000">3.6.1 Defining menus</A> <LI><A NAME="tex2html281" HREF="node4.html#SECTION00462000000000000000">3.6.2 Special menus</A> <LI><A NAME="tex2html282" HREF="node4.html#SECTION00463000000000000000">3.6.3 Displaying menus</A> </UL> <BR> <LI><A NAME="tex2html283" HREF="node4.html#SECTION00470000000000000000">3.7 Some common configuration tasks</A> <UL> <LI><A NAME="tex2html284" HREF="node4.html#SECTION00471000000000000000">3.7.1 Binding a key to execute a program</A> </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 the reader configure Ion to her/his liking. As the reader probably already knows, Ion uses Lua as a configuration and extension language. If the reader is new to Lua, he might first want to read some Lua documentation as already suggested and pointed to in the Introduction before continuing with this chapter. <P> In particular, if ''anonymous function'' sounds or the function construct in <PRE> kpress("Mod1+1", function(s) screen_switch_nth(s, 0) end) </PRE> looks confusing to you, please consider reading some Lua documentation. Read the functions tutorial at <P> <DIV ALIGN="CENTER"> <TT><A NAME="tex2html7" HREF="http://lua-users.org/wiki/FunctionsTutorial">http://lua-users.org/wiki/FunctionsTutorial</A></TT> </DIV> <P> if nothing else. Ion's stock configuration files use anonymous functions quite extensively. <P> Section <A HREF="#sec:conffiles">3.1</A> 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.4</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> Ion2, to which document applies, stores its stock configuration files in <I>/usr/local/etc/ion/</I> unless you, OS package maintainer or whoever installed the package has modified the variables <TT>PREFIX</TT><A NAME="908"></A> or <TT>ETCDIR</TT><A NAME="909"></A> in <I>system.mk</I><A NAME="910"></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 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 ion.lua</TT> might help provided <TT>updatedb</TT> has been run recently. User configuration files go in <I>~/.ion2/</I>. <P> Ion always searches 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>~/.ion2/</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> The ''Ioncore'' window manager core and each module have their own configuration files that should be used to configure that module. The configuration files related to the ioncore main binary are as follows. The files <I>ion.lua</I> and <I>draw.lua</I> are loaded from Ioncore and the rest are included from the former. <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>ion.lua</I></TD> <TD ALIGN="LEFT">The main configuration file</TD> </TR> <TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>ion-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>ion-menus.lua</I></TD> <TD ALIGN="LEFT">Menu definitions; see section <A HREF="#sec:menus">3.6</A>.</TD> </TR> <TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>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.4</A> for details on these ''winprops''.</TD> </TR> <TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>draw.lua</I></TD> <TD ALIGN="LEFT">This file is a link to or copy of one of the <I>look-*.lua</I> style files. It should load a drawing engine and configure a style for it; for details see chapter <A HREF="node5.html#chap:gr">4</A>.</TD> </TR> </TABLE> <P> Each (non-drawing engine) module has in addition its own configuration file loaded when that module is loaded: <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>ionws.lua</I></TD> <TD ALIGN="LEFT">Configuration file for the ionws module. Bindings specific to the workspace and frame classes implemented by this module are configured here.</TD> </TR> <TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>floatws.lua</I></TD> <TD ALIGN="LEFT">Configuration file for the floatws module. Bindings specific to the workspace and frame classes implemented by this module are configured here.</TD> </TR> <TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>query.lua</I></TD> <TD ALIGN="LEFT">Configuration file for the query module. Bindings to edit text in the queries and some other bindings related to queries and messages are defined here.</TD> </TR> <TR><TD ALIGN="LEFT" VALIGN="TOP" WIDTH=1><I>menu.lua</I></TD> <TD ALIGN="LEFT">Configuration file for the menu module. Bindings to navigate menus are defined here. Actual menus are (in the stock configuration file setup) defined in <I>ion-menus.lua</I> as mentioned above.</TD> </TR> </TABLE> <P> Some of the files contain references to the files <I>querylib.lua</I> and <I>menulib.lua</I> These are installed in <TT>SHAREDIR</TT><A NAME="915"></A> (<I>/usr/local/share/ion/</I> by default) among some other other <I>.lua</I> files that are an essential part of Ion's code. Users who only want to change a few settings should not need to modify the files in this directory. Nevertheless, it is possible to override the files in <TT>SHAREDIR</TT> as it is on the search path after <TT>/.ion2</TT> and <TT>ETCDIR</TT>. <P> There is one extra file in <TT>SHAREDIR</TT> that you may find useful and that is not loaded by default. This is <I>compat.lua</I> and it contains some wrapper functions for backwards compatibility to make the process of updating Ion a little less painful. If you have have modified configuration files that use some features no longer available in the latest Ion, you may just load this file (with <TT>include("compat.lua")</TT> at the beginning of <I>ion.lua</I>, for example) instead of immediately updating your configuration files. However, the wrappers will be removed eventually (maybe about two months after adding them depending on the rate of new releases) so you should nevertheless update your configuration files before this happens. <P> <H2><A NAME="SECTION00420000000000000000"></A> <A NAME="sec:walkthrough"></A> <BR> 3.2 A walk through <I>ion.lua</I> </H2> <P> As already mentioned <I>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>ion.lua</I>. <P> The first thing that is done in that file is set <PRE> DEFAULT_MOD = "Mod1+" </PRE> This causes most of Ion's key bindings to use <B>Mod1</B> as the modifier key; for details on modifiers and key binding setup in general see section <A HREF="#sec:bindings">3.3</A>. <P> Next there are the commented-out delay settings <PRE> -- set_dblclick_delay(250) -- set_resize_delay(1500) </PRE> The first of these settings is the maximum interval in milliseconds between two mouse button presses for the second press to be actually considered a double-click. The latter setting sets the delay, again in milliseconds, after which Ion will automatically terminate one of the keyboard resize modes if nothing has happened. <P> The setting <PRE> enable_opaque_resize(false) </PRE> says that a XOR rubber band should be shown when moving or resizing frames. This will, unfortunately, cause Ion to also grab the X server and has some side effects. If your computer is fast enough and you prefer so-called ''opaque resize'' mode where the frame is being resized already during the resize action you may set the parameter to <code>true</code>. <P> The following settings controls whether Ion will ''warp'' the (mouse) pointer to an object whenever it is focused from the keyboard. <PRE> enable_warp(true) </PRE> Some people may consider this annoying so setting the parameter to <code>false</code> can be used to disable this feature and have Ion never move the pointer. <P> Next the stock <I>ion.lua</I> has the include-statements <PRE> include("kludges") include("ion-bindings") include("ion-menus") </PRE> The first of these loads the file <I>kludges.lua</I> that contains some ''winprop'' settings used to make some applications behave a little better under Ion. For details see section <A HREF="#sec:winprops">3.4</A>. The second include statement loads file file <I>ion-bindings.lua</I> which contains the statements to configure most of Ion's bindings; modules' bindings are configured in their respective configuration files. The final include statement load menu definitions. <P> Next we have quite a few statements of the form <PRE> add_shortenrule("[^:]+: (.*)(<[0-9]+>)", "$1$2$|$1$<...$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<3>' to 'barba...<3>'; for details see the function reference entry for <A HREF="node7.html#fn:add_shortenrule"><TT>add_shortenrule</TT></A>. <P> The setting <PRE> query_man_path = { "/usr/man", "/usr/share/man", "/usr/X11R6/man", "/usr/local/man" } </PRE> is used to configure where the <A HREF="node7.html#fn:querylib.query_man"><TT>querylib.query_man</TT></A> query (<B>F1</B>) looks for man pages to tab-complete. <P> Finally we load the modules. <PRE> load_module("query") load_module("menu") load_module("ionws") load_module("floatws") </PRE> The first of the modules provides the queries, the mini buffer-like line-editor boxes that appear at bottoms of frames and screens and that can be and are used to to do quite a few things including starting programs and navigating to different windows by their name. The 'menu' module provides both pop-up and query-style in-frame menus. The third module loaded provides the normal Ion-style tiled workspaces and frames of that style while the 'floatws' module provides traditional ''free-floating'' WIMP workspaces and frames in the PWM style. <P> As already mentioned, each of these modules have their own configuration files <I>modulename.lua</I> that configure things that can only be configured if the module is loaded. These settings are mostly just the bindings that are specific to the classes provided by the module. <P> At the moment there are no other modules than the above three. Any of these modules may be removed; Ion is able to operate without any modules in full-screen only mode, but if you do so, you might first want to reconfigure some of the bindings. Ion will, however, complain of broken workspace save files if starting a module-less configuration over an old session. <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>ion-bindings.lua</I> while module-specific bindings are set from the modules' main configuration files (<I>modulename.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> The bindings are defined by calling various functions that add a new set of bindings to a binding group, usually related to some object class. These functions, descriptions of their contexts and parameters passed to ''bindings handlers'' are listed in the following subsection. Each of the functions listed there has a single argument: a table listing the keys and mouse actions to bind functions to. Section <A HREF="#sec:binddef">3.3.2</A> describes how the binding tables can be constructed. <P> 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 The binding setup functions</A> </H3> <P> This section simply lists out the different binding setup functions Ioncore and the modules provide and does not even attempt to describe how to use these functions; for that refer to <A HREF="#sec:binddef">3.3.2</A> and following sections. <P> There has been some confusion among users about the need for multiple, partially even overlapping functions to setup bindings so let me try to explain this design decision here. <P> The thing is that if there was a just a single 'bind this key to this function' method to bind keys, some limitations would have to be made on the available functions and writing custom functions 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 <IMG WIDTH="14" HEIGHT="14" ALIGN="BOTTOM" BORDER="0" SRC="img1.png" ALT="$n$">:th workspaces is bound to <B>Mod1+n</B> (using <A HREF="node7.html#fn:global_bindings"><TT>global_bindings</TT></A> explained below) while the switch to <IMG WIDTH="14" HEIGHT="14" ALIGN="BOTTOM" BORDER="0" SRC="img1.png" ALT="$n$">:th tab is bound to the sequence <B>Mod1+k n</B> (using <A HREF="node7.html#fn:genframe_bindings"><TT>genframe_bindings</TT></A> and <A HREF="node7.html#fn:submap"><TT>submap</TT></A>). <P> So, in brief this little additional complexity in configuration is the price of flexibility. <P> <H4><A NAME="SECTION00431100000000000000"> 3.3.1.1 Ioncore binding setup functions</A> </H4> <P> The following binding setup functions are defined by Ioncore and in the stock configuration file setup, they are set from the file <I>ion-bindings.lua</I>: <P> <TABLE CELLPADDING=3 BORDER="1" WIDTH="100%"> <TR><TD ALIGN="LEFT">Function</TD> <TD ALIGN="LEFT">Handler parameters and description</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:global_bindings"><TT>global_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WScreen</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings that are available all the time.</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:mplex_bindings"><TT>mplex_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WMPlex</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings that are common to all WMPlexes (screens and frames). Usually only bindings that affect current client window (if any) are set here.</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:genframe_bindings"><TT>genframe_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WGenFrame, [WRegion]</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings that are common to all types of frames (but not screens unlike <TT>mplex_bindings</TT> above. When a tab has been pressed the WRegion corresponding to the tab is passed as the extra parameter.</TD> </TR> </TABLE> <P> <H4><A NAME="SECTION00431200000000000000"> 3.3.1.2 IonWS module binding setup functions</A> </H4> <P> The following binding setup functions are defined by the IonWS module and in the stock configuration file setup the bindings are set in <I>ionws.lua</I>: <P> <TABLE CELLPADDING=3 BORDER="1" WIDTH="100%"> <TR><TD ALIGN="LEFT">Function</TD> <TD ALIGN="LEFT">Handler parameters and description</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:ionws_bindings"><TT>ionws_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WIonWS, WRegion</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings that are available on the tiled workspaces implemented by this module. The extra parameter to binding handler is the currently active object on the workspace.</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:ionframe_bindings"><TT>ionframe_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WIonFrame, [WRegion]</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings that are specific to the tiled frames. As above, when a tab has been pressed the WRegion corresponding to the tab is passed as the extra parameter.</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:ionframe_moveres_bindings"><TT>ionframe_moveres_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WIonFrame</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Resize mode bindings. Activated by calling <A HREF="node7.html#fn:WIonFrame.begin_resize"><TT>WIonFrame.begin_resize</TT></A>. Only certain functions may be called here; see the function reference for details.</TD> </TR> </TABLE> <P> <H4><A NAME="SECTION00431300000000000000"> 3.3.1.3 FloatWS module binding setup functions</A> </H4> <P> These functions are similar to the ones described in the above section for the FloatWS module. The bindings are defined in the configuration file <I>floatws.lua</I>: <P> <TABLE CELLPADDING=3 BORDER="1" WIDTH="100%"> <TR><TD ALIGN="LEFT">Function</TD> <TD ALIGN="LEFT">Handler parameters and description</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:floatws_bindings"><TT>floatws_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WFloatWS, [WRegion]</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings that are available on the conventional workspaces implemented by this module. The extra parameter to binding handler is the currently active object on the workspace, if any.</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:floatframe_bindings"><TT>floatframe_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WFloatFrame, [WRegion]</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings that are specific to the the conventional floating frames.</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:floatframe_moveres_bindings"><TT>floatframe_moveres_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WIonFrame</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Keyboard move/resize mode bindings. Activated by calling the function <A HREF="node7.html#fn:WFloatFrame.begin_resize"><TT>WFloatFrame.begin_resize</TT></A>. Only certain functions may be called here; see the function reference for details.</TD> </TR> </TABLE> <P> <H4><A NAME="SECTION00431400000000000000"> 3.3.1.4 Query module binding setup functions</A> </H4> <P> These functions set the bindings for the query module. The bindings are set from the file <I>query.lua</I>. <P> <TABLE CELLPADDING=3 BORDER="1" WIDTH="100%"> <TR><TD ALIGN="LEFT">Function</TD> <TD ALIGN="LEFT">Handler parameters and description</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="#fn:input_bindings"><TT>input_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WInput</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: bindings that are common to message and query boxes; stuff to close the box and to scroll message or completions.</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:query_bindings"><TT>query_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WEdln</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: Bindings to edit text and finish the query.</TD> </TR> </TABLE> <P> <H4><A NAME="SECTION00431500000000000000"> 3.3.1.5 Menu module binding setup functions</A> </H4> <P> These functions set the bindings for the menu module. The bindings are set from the file <I>menu.lua</I>. <P> <TABLE CELLPADDING=3 BORDER="1" WIDTH="100%"> <TR><TD ALIGN="LEFT">Function</TD> <TD ALIGN="LEFT">Handler parameters and description</TD> </TR> <TR><TD ALIGN="LEFT"><A HREF="node7.html#fn:menu_bindings"><TT>menu_bindings</TT></A></TD> <TD ALIGN="LEFT">Parameters to handler: WMenu</TD> </TR> <TR><TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT">Description: key bindings available in in-frame menus.</TD> </TR> </TABLE> <P> <H3><A NAME="SECTION00432000000000000000"></A> <A NAME="sec:binddef"></A> <BR> 3.3.2 Defining the bindings </H3> <P> Each of the functions listed above has a single argument: a table listing the key presses and other actions to be bound to functions. The descriptions of individual bindings in this table are also tables that can be more conveniently constructed with the following functions: <P> Key presses: <UL> <LI><A HREF="node7.html#fn:kpress"><TT>kpress</TT></A><TT>(keyspec, func)</TT>, </LI> <LI><A HREF="node7.html#fn:kpress_waitrel"><TT>kpress_waitrel</TT></A><TT>(keyspec, func)</TT> and </LI> <LI><A HREF="node7.html#fn:submap"><TT>submap</TT></A><TT>(keyspec, { ... more key bindings ... })</TT>. </LI> </UL> Mouse actions: <UL> <LI><A HREF="node7.html#fn:mclick"><TT>mclick</TT></A><TT>(buttonspec, func, [, area])</TT>, </LI> <LI><A HREF="node7.html#fn:mdblclick"><TT>mdblclick</TT></A><TT>(buttonspec, func, [, area])</TT>, </LI> <LI><A HREF="node7.html#fn:mpress"><TT>mpress</TT></A><TT>(buttonspec, func, [, area])</TT> and </LI> <LI><A HREF="node7.html#fn:mdrag"><TT>mdrag</TT></A><TT>(buttonspec, func, [, area])</TT>. </LI> </UL> <P> The actions that most of these functions correspond to should be clear and as explained in the reference, <A HREF="node7.html#fn:kpress_waitrel"><TT>kpress_waitrel</TT></A> is simply <A HREF="node7.html#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.close"><TT>WRegion.close</TT></A> multiple times in a row. The <A HREF="node7.html#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="node7.html#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>func</TT> is the handler for the binding. It is a reference to a function that should expect as parameter(s) objects of the type defined in the above tables depending on which binding setup function this binding definition is being passed to. <P> The optional string parameter <TT>area</TT> may be used to specify a more precise location where the mouse action should occur for the binding to take place. Currently only <A HREF="node7.html#fn:ionframe_bindings"><TT>ionframe_bindings</TT></A> and <A HREF="node7.html#fn:floatframe_bindings"><TT>floatframe_bindings</TT></A> support any meaningful values for this parameter. The allowed values are in this case <TT>"border"</TT>, <TT>"tab"</TT>, <TT>"empty_tab"</TT>, <TT>"client"</TT> and <TT>nil</TT> (for the whole frame). <P> <H3><A NAME="SECTION00433000000000000000"> 3.3.3 An example</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> global_bindings{ kpress("Mod1+Right", WScreen.switch_next), kpress("Mod1+1", function(scr) scr:switch_nth(1) end), } </PRE> <P> Recall that <TT>global_bindings{...}</TT> is syntactical sugar for the more cumbersome <TT>global_bindings({...})</TT>. <P> The first definition works, because <TT>WScreen.switch_next</TT> (inherited <A HREF="node7.html#fn:WMPlex.switch_next"><TT>WMPlex.switch_next</TT></A>) is a function that takes a WScreen as its sole parameter. On the other hand, <TT>WScreen.switch_nth</TT> (again inherited <A HREF="node7.html#fn:WMPlex.switch_nth"><TT>WMPlex.switch_nth</TT></A>) expects two parameters: the screen and the <IMG WIDTH="14" HEIGHT="14" ALIGN="BOTTOM" BORDER="0" SRC="img1.png" ALT="$n$"> giving the number of the workspace to switch to so it could not be directly passed to <TT>kpress</TT>. Therefore we had to write around it our ''anonymous'' wrapper function around that takes a single parameter and calls <TT>switch_nth</TT> properly. (Recall that <TT>scr:switch_nth(1)</TT> is syntactic sugar for <TT>WScreen.switch_nth(scr, 1)</TT>. Alternatively we could have defined <TT>function switch_1(scr) scr:switch_nth(1) end</TT> before the call to <TT>global_bindings</TT> and passed <TT>switch_1</TT> to <TT>kpress</TT> instead of the anonymous function.) <P> <H3><A NAME="SECTION00434000000000000000"> 3.3.4 Another example</A> </H3> <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> genframe_bindings{ submap("Mod1+k", { kpress("n", WGenFrame.switch_next), kpress("1", function(frame) frame:switch_nth(1) end), }), } </PRE> <P> Note that the switching functions being used in this example are exactly the same as in the previous example. Both WScreen and WGenFrame inherit them from WMPlex. <P> <H3><A NAME="SECTION00435000000000000000"> 3.3.5 Key and button 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="tex2html8" HREF="#foot917"><SUP>3.1</SUP></A> without the <TT>XK_</TT> prefix. <A NAME="918"></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="919"></A> <A NAME="920"></A> <A NAME="921"></A> <A NAME="922"></A> <A NAME="923"></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="924"></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="925"></A> to find out what exactly is bound where. <B>AnyModifier</B> is usually used in submaps to indicate that it doesn't matter which modifier keys are pressed, if any. <P> Ion ignores the <B>Lock</B> modifier and any <B>ModN</B> modifiers bound to <B>NumLock</B><A NAME="926"></A> or <B>ScrollLock</B><A NAME="927"></A> by default because such<A NAME="tex2html9" HREF="#foot740"><SUP>3.2</SUP></A> locking keys may otherwise cause confusion. <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="928"></A>. <P> <H3><A NAME="SECTION00436000000000000000"> 3.3.6 A further note on the default binding configuration</A> </H3> <P> The variable <TT>DEFAULT_MOD</TT> in the above listing defaults to <TT>"Mod1+"</TT> and is set in <I>ion.lua</I>. Changing this variable allows to easily change the the modifier used by all bindings in the default configuration that use modifiers. 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="SECTION00437000000000000000"> 3.3.7 Client window bindings</A> </H3> <P> As client windows do not have function to set their bindings, it is necessary to call client window functions by specifying the bindings somewhere else. In the stock configuration file setup this is done in <A HREF="node7.html#fn:mplex_bindings"><TT>mplex_bindings</TT></A> by functions that look up the object currently displayed by the WMPlex (<A HREF="node7.html#fn:WMPlex.current"><TT>WMPlex.current</TT></A>). We then check that it is of type WClientWin to suppress warning and then call the wanted function with the verified client window as argument. <P> To make it easier to write such bindings, the function <A HREF="node7.html#fn:make_mplex_clientwin_fn"><TT>make_mplex_clientwin_fn</TT></A> is used to construct this wrapper function. The following two binding definitions are essentially equivalent: <P> <PRE> mplex_bindings { kpress("Mod1+Return", function(mplex, r) if not r or r==mplex r=mplex:current() end if obj_is(r, "WClientWin") then r:toggle_fullscreen() end end), kpress("Mod1+Enter", make_mplex_clientwin_fn(WClientWin.toggle_fullscreen)), } </PRE> <P> <H2><A NAME="SECTION00440000000000000000"></A> <A NAME="sec:winprops"></A> <BR> 3.4 Winprops </H2> <P> <H3><A NAME="SECTION00441000000000000000"> 3.4.1 Classes, roles and instances</A> </H3> <P> The so-called ''winprops''<A NAME="761"></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>winprop</TT> with a table containing the properties to set and the necessary information to identify a window. This identification information is more specifically the <TT>class</TT><A NAME="929"></A>, <TT>role</TT><A NAME="930"></A>, <TT>instance</TT><A NAME="931"></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"> </TD> <TD ALIGN="LEFT"> </TD> <TD ALIGN="LEFT"> </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="SECTION00442000000000000000"> 3.4.2 Finding window identification with <TT>xprop</TT></A> </H3> <P> <A NAME="783"></A> To get the identification information required for winprops, in case of normally framed windows you may use the command <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>. <P> <A NAME="786"></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="tex2html10" HREF="#foot933"><SUP>3.3</SUP></A> <P> If you can guess the title of the transient, the simplest solution is to use the <B>Mod1+A</B> query (<A HREF="node7.html#fn:querylib.query_attachclient"><TT>querylib.query_attachclient</TT></A>) to attach it directly to a frame. Another easy solution is to create a WFloatWS and run the program for this once. A little more complicated solution is to run the following code in the <B>Mod1+F3</B> (<A HREF="#fn:querylib.query_lua_"><TT>querylib.query_lua)</TT></A> Lua code execution query, assuming there's only one transient (all on one line): <P> <PRE> local id=_:current():managed_list()[1]:get_ident(); query_message(_, id.class..'.'..id.instance); </PRE> <P> Role and name can be retrieved similarly (see the documentation for <A HREF="node7.html#fn:WClientWin.get_ident"><TT>WClientWin.get_ident</TT></A> or <A HREF="node7.html#fn:WRegion.name"><TT>WRegion.name</TT></A>). Role may not always be set. <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="SECTION00443000000000000000"> 3.4.3 Supported winprops</A> </H3> <P> Ion currently knows the following winprops: <P> <A NAME="934"></A> <A NAME="935"></A> <A NAME="936"></A> <A NAME="937"></A> <A NAME="938"></A> <A NAME="939"></A> <A NAME="940"></A> <A NAME="941"></A> <A NAME="942"></A> <P> <TABLE CELLPADDING=3 BORDER="1" WIDTH="100%"> <TR><TD ALIGN="LEFT">Property</TD> <TD ALIGN="LEFT">Type</TD> <TD ALIGN="LEFT">Description</TD> </TR> <TR><TD ALIGN="LEFT"><TT>switchto</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">Should a newly mapped client window be switched to within its frame.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>jumpto</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">Should a newly created client window always be made active, even if the allocated frame isn't.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>transient_mode</TT></TD> <TD ALIGN="LEFT">string</TD> <TD ALIGN="LEFT">"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.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>target</TT></TD> <TD ALIGN="LEFT">string</TD> <TD ALIGN="LEFT">The name of an object (workspace, frame) that should manage windows of this type.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>transparent</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">Should frames be made transparent when this window is selected?</TD> </TR> <TR><TD ALIGN="LEFT"><TT>acrobatic</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">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.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>max_size</TT></TD> <TD ALIGN="LEFT">table</TD> <TD ALIGN="LEFT">The table should contain the entries <TT>w</TT> and <TT>h</TT> that override application-supplied maximum size hint.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>aspect</TT></TD> <TD ALIGN="LEFT">table</TD> <TD ALIGN="LEFT">The table should contain the entries <TT>w</TT> and <TT>h</TT> that override application-supplied aspect ratio hint.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>ignore_resizeinc</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">Should application supplied size increments be ignored?</TD> </TR> <TR><TD ALIGN="LEFT"><TT>fullscreen</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">Should the window be initially in full screen mode?</TD> </TR> <TR><TD ALIGN="LEFT"><TT>ignore_cfgrq</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">Should configure requests on the window be ignored? Only has effect on windows on floatws:s.</TD> </TR> <TR><TD ALIGN="LEFT"><TT>transients_at_top</TT></TD> <TD ALIGN="LEFT">boolean</TD> <TD ALIGN="LEFT">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?</TD> </TR> </TABLE> <P> <H3><A NAME="SECTION00444000000000000000"> 3.4.4 Some common examples</A> </H3> <P> <H4><A NAME="SECTION00444100000000000000"> 3.4.4.1 Acrobat Reader</A> </H4> <P> The following is absolutely necessary for Acrobat reader: <P> <PRE> winprop{ class = "AcroRead", instance = "documentShell", acrobatic = true, } </PRE> <P> <H4><A NAME="SECTION00444200000000000000"> 3.4.4.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> winprop{ class = "MozillaFirebird-bin", name = "Opening .*", transient_mode = "current", } </PRE> <P> <H4><A NAME="SECTION00444300000000000000"> 3.4.4.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> winprop{ class = "XTerm", instance = "sysmon", target = "sysmonframe", } </PRE> <P> For this example to work, we have to somehow create a frame with the name <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> querylib.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> <H2><A NAME="SECTION00450000000000000000"> 3.5 The query library</A> </H2> <A NAME="943"></A> <P> The query module does not implement any queries in itself, but provides the function <A HREF="node7.html#fn:query_query"><TT>query_query</TT></A> to execute arbitrary queries. Some standard queries implemented with this interface are available in 'querylib' (<I>SHAREDIR/querylib.lua</I>). Most of these queries support tab-completion and can be directly passed to the binding setup functions for classes based on WMPlex. These setup functions are at the moment: <UL> <LI><A HREF="node7.html#fn:global_bindings"><TT>global_bindings</TT></A> </LI> <LI><A HREF="node7.html#fn:mplex_bindings"><TT>mplex_bindings</TT></A>, </LI> <LI><A HREF="node7.html#fn:genframe_bindings"><TT>genframe_bindings</TT></A>, </LI> <LI><A HREF="node7.html#fn:ionframe_bindings"><TT>ionframe_bindings</TT></A> and </LI> <LI><A HREF="node7.html#fn:floatframe_bindings"><TT>floatframe_bindings</TT></A>. </LI> </UL> <P> The default configuration puts most queries in <A HREF="node7.html#fn:genframe_bindings"><TT>genframe_bindings</TT></A> while the exit and restart queries are in <A HREF="node7.html#fn:global_bindings"><TT>global_bindings</TT></A>. For a listing of the functions, see section <A HREF="node7.html#sec:querylibref">6.9</A> in the Function reference. <P> Querylib also provides functions to generate more queries; for details see the script. <P> <H2><A NAME="SECTION00460000000000000000"></A> <A NAME="sec:menus"></A> <BR> 3.6 Menus </H2> <P> <H3><A NAME="SECTION00461000000000000000"> 3.6.1 Defining menus</A> </H3> <P> <A NAME="865"></A> <A NAME="944"></A> <A NAME="945"></A> <A NAME="946"></A> In the stock configuration file setup, menus are configured in the file <I>ion-menus.lua</I> as previously mentioned. An example of a definition of a rather simple menu with a submenu is: <PRE> include("menulib") defmenu("exitmenu", { menuentry("Restart", restart_wm), menuentry("Exit", exit_wm), }) defmenu("mainmenu", { menuentry("Lock screen", make_exec_fn("xlock")), menuentry("Help", querylib.query_man), submenu("Exit", "exitmenu"), }) </PRE> <P> The <I>menulib</I> library must be loaded for some of the functions discussed here to be available. <P> The <A HREF="node7.html#fn:defmenu"><TT>defmenu</TT></A> function is used to define a named menu that can later be accessed with this name. The <A HREF="node7.html#fn:menuentry"><TT>menuentry</TT></A> function is used to create an entry in the menu with a title and an entry handler function to be called when the menu entry is activated. If the functions discussed in subsection <A HREF="#sec:menudisp">3.6.3</A> are used to display the menu from a binding, the parameters that are passed to the function are those that the binding handler was passed. It is as if the function was called from that binding. <P> The <A HREF="node7.html#fn: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="SECTION00462000000000000000"> 3.6.2 Special menus</A> </H3> <P> The <I>menulib</I> library predefines the following special menus. These can be used as 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> </TABLE> <P> <H3><A NAME="SECTION00463000000000000000"></A> <A NAME="sec:menudisp"></A> <BR> 3.6.3 Displaying menus </H3> <P> <A NAME="947"></A> <A NAME="948"></A> <A NAME="949"></A> Menus defined with the routines described in the previous subsection should be bound to key and pointer actions by creating a bindable function with one of the following routines: <A HREF="node7.html#fn:make_menu_fn"><TT>make_menu_fn</TT></A>, <A HREF="node7.html#fn:make_bigmenu_fn"><TT>make_bigmenu_fn</TT></A> or <A HREF="node7.html#fn:make_pmenu_fn"><TT>make_pmenu_fn</TT></A>. The first two create functions to display in-frame (or in-mplex more generally) menus that appear on the bottom-left corner of the WMPlex where the bound action occurred. The difference between the two is the different drawing engine style used. The last function creates a pop-up menu display function and can only be bound to mouse press actions. <P> An example of a binding to display a menu is: <PRE> global_bindings{ kpress("F12", make_bigmenu_fn("mainmenu")), } </PRE> <P> The low-level functions <A HREF="node7.html#fn:menu_menu"><TT>menu_menu</TT></A> and <A HREF="node7.html#fn:menu_pmenu"><TT>menu_pmenu</TT></A> can also be used to display menus with different kinds of handlers and so on, but most users should not need to be concerned with these. If you use these functions note that they do not call the menu entry handlers but pass the entry to a specified handler the responsibility of which it is to decide what to do. <P> <H2><A NAME="SECTION00470000000000000000"> 3.7 Some common configuration tasks</A> </H2> <P> <H3><A NAME="SECTION00471000000000000000"> 3.7.1 Binding a key to execute a program</A> </H3> <P> Because the <A HREF="node7.html#fn:exec"><TT>exec</TT></A> function immediately executes the argument string, we must wrap this function in the bindings in the following way: <PRE> kpress("SomeKey", function() exec("program --param") end) </PRE> The <A HREF="node7.html#fn:make_exec_fn"><TT>make_exec_fn</TT></A> function can be used as a convenience; the above is equivalent to <PRE> kpress("SomeKey", make_exec_fn("program --param")) </PRE> <P> <P> <BR><HR><H4>Footnotes</H4> <DL> <DT><A NAME="foot917">...keysymdef.h</A><A HREF="node4.html#tex2html8"><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="foot740">... such</A><A HREF="node4.html#tex2html9"><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="foot933">... window.</A><A HREF="node4.html#tex2html10"><SUP>3.3</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="tex2html253" HREF="node5.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html247" HREF="ionconf.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html241" HREF="node3.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html249" HREF="node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html251" HREF="node10.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html254" HREF="node5.html">4. Graphical styles</A> <B> Up:</B> <A NAME="tex2html248" HREF="ionconf.html">Ion: Configuring and extending</A> <B> Previous:</B> <A NAME="tex2html242" HREF="node3.html">2. Preliminaries: Key concepts</A> <B> <A NAME="tex2html250" HREF="node1.html">Contents</A></B> <B> <A NAME="tex2html252" HREF="node10.html">Index</A></B> <!--End of Navigation Panel--> </BODY> </HTML>