]> git.decadent.org.uk Git - ion3-doc.git/blob - conf-bindings.tex
[svn-inject] Installing original source of ion3
[ion3-doc.git] / conf-bindings.tex
1 \section{Keys and rodents}
2 \label{sec:bindings}
3
4 In the stock configuration file setup, most key and mouse bindings are set
5 from the file \file{cfg\_ioncore.lua} while module-specific bindings
6 are set from the modules' main configuration files (\file{cfg\_modname.lua}).
7 This, however, does not have to be so as long as the module has been
8 loaded prior to defining any module-specific bindings.
9
10 Bindings are defined by calling the function 
11 \fnrefx{ioncore}{defbindings} with the ''context'' of the
12 bindings and the a table of new bindings to make. The context is simply
13 string indicating one of the classes of regions (or modes such as
14 \type{WMoveresMode}) introduced in section \ref{sec:objects}, and fully
15 listed in appendix \ref{app:fullhierarchy}, although not all define
16 a binding map. For example, the following skeleton would be used to 
17 define new bindings for all frames:
18
19 \begin{verbatim}
20 defbindings("WFrame", {
21     -- List of bindings to make goes here.
22 })
23 \end{verbatim}
24
25 There has been some confusion among users about the need to define the
26 ''context'' for each binding, so let me try to explain this design
27 decision here. The thing is that if there was a just a simple 'bind this 
28 key to this action' method without knowledge of the context, some 
29 limitations would have to be made on the available actions and writing 
30 custom handlers would be more complicated. In addition one may want to 
31 bind the same function to different key for different types of objects.
32 Indeed, the workspace and frame tab switching functions are the same both
33 classes being based on \type{WMPlex}, and in the stock configuration the 
34 switch to $n$:th workspaces is bound to \key{Mod1+n} while the switch to 
35 $n$:th tab is bound to the sequence \key{Mod1+k n}.
36
37 Currently known ''contexts'' include: 
38 \code{WScreen},
39 \code{WMPlex},
40 \code{WMPlex.toplevel},
41 \code{WFrame},
42 \code{WFrame.toplevel},
43 \code{WFrame.floating},
44 \code{WFrame.tiled},
45 \code{WFrame.transient},
46 \code{WMoveresMode},
47 \code{WGroup},
48 \code{WGroupCW},
49 \code{WGroupWS},
50 \code{WClientWin},
51 \code{WTiling}, and
52 \code{WStatusBar}.
53 Most of these should be self-explanatory, corresponding to objects
54 of class with the same name. The ones with \code{.toplevel} suffix
55 refer to screens and ''toplevel''  frames, i.e. frames that are
56 not used for transient windows. Likewise \code{.transient} refers
57 to frames in transient mode, and \code{.tiled} and \code{.floating}
58 to frames in, respectively, tiled and floating modes. 
59
60                                                         
61
62 The following subsections describe how to construct elements of the
63 binding table. Note that \fnrefx{ioncore}{defbindings} adds
64 the the newly defined bindings to the previous bindings of the context,
65 overriding duplicates. To unbind an event, set the handler parameter
66 to \code{nil} for each of the functions to be described in the following
67 subsections.
68
69 Also note that when multiple objects want to handle a binding, the 
70 innermost (when the root window is considered the outermost) active object
71 in the parent--child hierarchy (see Figure \ref{fig:parentship}) of objects 
72 gets to handle the action.
73
74
75 \subsection{Binding handlers and special variables}
76
77 Unlike in Ion2, in Ion3 binding handlers are not normally passed as
78 ''anonymous functions'', although this is still possible. The preferred
79 method now is to pass the code of the handler as a string. Two special 
80 variables are available in this code. These are
81
82 \begin{tabularx}{\linewidth}{lX}
83     \tabhead{Variable & Description}
84     \code{_} (underscore) &
85       Reference to the object on which the 
86       binding was triggered. The object is of the same class as the the
87       context of the \fnrefx{ioncore}{defbindings} call
88       defining the binding. \\
89     \code{_sub} &
90       Usually, the currently active \emph{managed object} of the 
91       object referred to by \code{_}, but sometimes (e.g. mouse actions
92       on tabs of frames) something else relevant to the action triggering
93       the binding. \\
94     \code{_chld} &
95       Object corresponding to the currently active child window of the
96        object referred to by \code{_}.
97 \end{tabularx}
98
99 For example, supposing '\code{_}' is a \type{WFrame}, the following
100 handler should move the active window to the right, if possible:
101
102 \begin{verbatim}
103 "_:inc_index(_sub)"
104 \end{verbatim}
105
106 \subsection{Guards}
107
108 To suppress error messages, each binding handler may also be accompanied
109 by a ''guard'' expression that blocks the handler from being called when
110 the guard condition is not met. Currently the following guard expressions
111 are supported (for both \code{_sub} and \code{_chld}):
112
113 \begin{tabularx}{\linewidth}{lX}
114     \tabhead{Guard & Description}
115     \code{"_sub:non-nil"} & The \code{_sub} parameter must be set. \\
116     \code{"_sub:SomeClass"} & The \code{_sub} parameter must be member
117       of class \type{SomeClass}. \\
118 \end{tabularx}
119
120
121 \subsection{Defining the bindings}
122 \label{sec:binddef}
123
124 The descriptions of the individual bindings in the binding table argument
125 to \fnrefx{ioncore}{defbindings} should be constructed with the following
126 functions.
127
128 Key presses:
129 \begin{itemize}
130     \item \fnref{kpress}\code{(keyspec, handler [, guard])},
131     \item \fnref{kpress_wait}\code{(keyspec, handler [, guard])} and
132     \item \fnref{submap}\code{(keyspec, \{ ... more key bindings ... \})}.
133 \end{itemize}
134 Mouse actions:
135 \begin{itemize}
136     \item \fnref{mclick}\code{(buttonspec, handler [, guard])},
137     \item \fnref{mdblclick}\code{(buttonspec, handler [, guard])}, 
138     \item \fnref{mpress}\code{(buttonspec, handler [, guard])} and
139     \item \fnref{mdrag}\code{(buttonspec, handler [, guard])}.
140 \end{itemize}
141
142 The actions that most of these functions correspond to should be clear
143 and as explained in the reference, \fnref{kpress_wait} is simply
144 \fnref{kpress} with a flag set instructing Ioncore wait for all
145 modifiers to be released before processing any further actions.
146 This is to stop one from accidentally calling e.g.
147 \fnref{WRegion.rqclose} multiple times in a row. The \fnref{submap}
148 function is used to define submaps or ''prefix maps''. The second
149 argument to this function is table listing the key press actions
150 (\fnref{kpress}) in the submap
151
152 The parameters \var{keyspec} and \var{buttonspec} are explained below
153 in detail. The parameter \var{handler} is the handler for the binding,
154 and the optional parameter \var{guard} its guard. These should normally
155 be strings as explained above. 
156
157 \subsection{Examples}
158
159 For example, to just bind the key \key{Mod1+1} to switch to the first
160 workspace and \key{Mod1+Right} to the next workspace, you would make the
161 following call
162 \begin{verbatim}
163 defbindings("WScreen", {
164     kpress("Mod1+Right", "_:switch_next()"),
165     kpress("Mod1+1", "_:switch_nth(1)"),
166 })
167 \end{verbatim}
168
169 Note that \code{_:switch_nth(1)} is the same as calling
170 \fnref{WMPlex.switch_next}\code{(_, 1)} as \type{WScreen} inherits
171 \type{WMPlex} and this is where the function is actually defined.
172
173 Similarly to the above example, to bind the key sequence \key{Mod1+k n} 
174 switch to the next managed object within a frame, and \key{Mod1+k 1} to the
175 first, you would issue the following call:
176 \begin{verbatim}
177 defbindings("WFrame", {
178     submap("Mod1+K", {
179         kpress("Right", "_:switch_next()"),
180         kpress("1", "_:switch_nth(1)"),
181    }),
182 })
183 \end{verbatim}
184
185
186 \subsection{Key specifications}
187
188 As seen above, the functions that create key binding specifications require
189 a \var{keyspec} argument. This argument should be a string containing the
190 name of a key as listed in the X header file \file{keysymdef.h}%
191 \footnote{This file can usually be found in the directory
192 \file{/usr/X11R6/include/X11/}.} without the \code{XK_} prefix.
193 \index{keysymdef.h@\file{keysymdef.h}}
194 Most of the key names are quite intuitive while some are not. For example,
195 the \key{Enter} key on the main part of the keyboard has the less common
196 name \key{Return} while the one the numpad is called \key{KP\_Enter}.
197
198 The \var{keyspec} string may optionally have multiple ''modifier'' names
199 followed by a plus sign (\code{+}) as a prefix. X defines the following
200 modifiers:
201 \begin{quotation}
202 \key{Shift}, \key{Control}, \key{Mod1} to \key{Mod5},
203 \key{AnyModifier} and \key{Lock}.
204 \index{Shift@\key{Shift}}
205 \index{Control@\key{Control}}
206 \index{ModN@\key{ModN}}
207 \index{AnyModifier@\key{AnyModifier}}
208 \index{Lock@\key{Lock}}
209 \end{quotation}
210
211 X allows binding all of these modifiers to almost any key and while this
212 list of modifiers does not explicitly list keys such as 
213 \key{Alt}\index{Alt@\key{Alt}} that are common on modern keyboards, such
214 keys are bound to one of the \key{ModN}. On systems running XFree86
215 \key{Alt} is usually \key{Mod1}. On Suns \key{Mod1} is the diamond key
216 and \key{Alt} something else. One of the ''flying window'' keys on so
217 called Windows-keyboards is probably mapped to \key{Mod3} if you have
218 such a key. Use the program \file{xmodmap}\index{xmodmap@\file{xmodmap}}
219 to find out what exactly is bound where. 
220
221 Ion defaults to \key{AnyModifier} in submaps. This can sometimes lead to
222 unwanted effects when the same key is used with and without explicitly
223 specified modifiers in nested regions. For this reason, Ion recognises
224 \key{NoModifier} as a special modifier that can be used to reset this
225 default.
226
227 Ion ignores the \key{Lock} modifier and any \key{ModN} ($N=1{\ldots} 5$)
228 bound to \key{NumLock}\index{NumLock@\key{NumLock}} or
229 \key{ScrollLock}\index{ScrollLock@\key{ScrollLock}}
230 by default because such\footnote{Completely useless keys that should be
231 gotten rid of in the author's opinion.} locking keys may otherwise
232 cause confusion.
233
234
235 \subsection{Button specifications}
236
237 Button specifications are similar to key definitions but now
238 instead of specifying modifiers and a key, you specify modifiers
239 and one of the button names \key{Button1} to
240 \key{Button5}\index{Button-n@\key{Button-n}}. Additionally the
241 specification may end with an optional area name following an @-sign.
242 Only frames currently support areas, and the supported values in this
243 case are
244 \code{"border"}, \code{"tab"}, \code{"empty_tab"}, \code{"client"} and
245 \code{nil} (for the whole frame).
246
247 For example, the following code binds dragging a tab with the first 
248 button pressed to initiate tab drag\&drop handling:
249
250 \begin{verbatim}
251 defbindings("WFrame", {
252     mdrag("Button1@tab", "_:p_tabdrag()"),
253 })
254 \end{verbatim}
255
256
257 \subsection{A further note on the default binding configuration}
258
259 The default binding configuration contains references to the variables
260 \code{META} and \code{ALTMETA} instead of directly using the default
261 values of \code{"Mod1+"} and \code{""} (nothing). As explained in
262 section \ref{sec:walkthrough}, the definitions of these variables
263 appear in \file{cfg\_ion.lua}. This way you can easily change the the
264 modifiers used by all bindings in the default configuration without 
265 changing the whole binding configuration. Quite a few people prefer 
266 to use the Windows keys as modifiers because many applications already
267 use \key{Alt}. Nevertheless, \key{Mod1} is the default as a key bound 
268 to it is available virtually everywhere.
269