3 Basic configuration
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.
In particular, if ''anonymous function'' sounds or the function construct in
kpress("Mod1+1", function(s) screen_switch_nth(s, 0) end)
looks confusing to you, please consider reading some Lua documentation.
Read the functions tutorial at
if nothing else. Ion's stock configuration files use anonymous functions
quite extensively.
Section 3.1 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 ion.lua is provided in section
3.2.
How keys and mouse action are bound to functions is described in detail
in 3.3 and in section 3.4 winprops are
explained. For a reference on exported functions, see section
6.
3.1 The configuration files
Ion3, to which document applies, stores its stock configuration files in
/usr/local/etc/ion/ unless you, OS package maintainer or whoever
installed the package has modified the variables
PREFIX or
ETCDIR in
system.mk 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
locate ion.lua might help provided updatedb has been
run recently. User configuration files go in ~/.ion3/.
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 ~/.ion3/ and modify this file. When searching
for a file, if no extension or path component is given, compiled .lc
files are attempted before .lua files.
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 ion.lua and draw.lua are loaded
from Ioncore and the rest are included from the former.
|
File |
Description |
|
ion.lua |
The main configuration file |
ion-bindings.lua |
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 3.3. |
ion-menus.lua |
Menu definitions; see section 3.6. |
kludges.lua |
Settings to get some applications behave more nicely have been collected here.
See section 3.4 for details on these ''winprops''. |
draw.lua |
This file is a link to or copy of one of the look-*.lua style
files. It should load a drawing engine and configure a style for
it; for details see chapter 4. |
Each (non-drawing engine) module has in addition its own configuration
file loaded when that module is loaded:
|
File |
Description |
|
ionws.lua |
Configuration file for the ionws module. Bindings specific to the
workspace and frame classes implemented by this module are
configured here. |
floatws.lua |
Configuration file for the floatws module. Bindings specific to
the workspace and frame classes implemented by this module are
configured here. |
query.lua |
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. |
menu.lua |
Configuration file for the menu module. Bindings to navigate
menus are defined here. Actual menus are (in the stock
configuration file setup) defined in ion-menus.lua
as mentioned above. |
Some of the files contain references to the files querylib.lua
and menulib.lua
These are installed in
SHAREDIR
(/usr/local/share/ion/ by default)
among some other other .lua 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 SHAREDIR as it is on the search
path after ~/.ion3 and ETCDIR.
There is one extra file in SHAREDIR that you may find useful and
that is not loaded by default. This is compat.lua 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 include("compat.lua") at the beginning of
ion.lua, 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.
3.2 A walk through ion.lua
As already mentioned ion.lua 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 ion.lua.
The first thing that is done in that file is set
DEFAULT_MOD = "Mod1+"
This causes most of Ion's key bindings to use Mod1 as the
modifier key; for details on modifiers and key binding setup in
general see section 3.3.
Next there are the commented-out delay settings
-- set_dblclick_delay(250)
-- set_resize_delay(1500)
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.
The setting
enable_opaque_resize(false)
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 true
.
The following settings controls whether Ion will ''warp'' the (mouse)
pointer to an object whenever it is focused from the keyboard.
enable_warp(true)
Some people may consider this annoying so setting the parameter
to false
can be used to disable this feature and have Ion
never move the pointer.
Next the stock ion.lua has the include-statements
include("kludges")
include("ion-bindings")
include("ion-menus")
The first of these loads the file kludges.lua that contains
some ''winprop'' settings used to make some applications behave a
little better under Ion. For details see section 3.4.
The second include statement loads file file
ion-bindings.lua 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.
Next we have quite a few statements of the form
add_shortenrule("[^:]+: (.*)(<[0-9]+>)", "$1$2$|$1$<...$2")
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 add_shortenrule.
The setting
query_man_path = {
"/usr/man",
"/usr/share/man",
"/usr/X11R6/man",
"/usr/local/man"
}
is used to configure where the querylib.query_man query
(F1) looks for man pages to tab-complete.
Finally we load the modules.
load_module("query")
load_module("menu")
load_module("ionws")
load_module("floatws")
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.
As already mentioned, each of these modules have their own configuration
files modulename.lua 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.
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.
3.3 Keys and rodents
In the stock configuration file setup, most key and mouse bindings are set
from the file ion-bindings.lua while module-specific bindings
are set from the modules' main configuration files (modulename.lua).
This, however, does not have to be so as long as the module has been
loaded prior to defining any module-specific bindings.
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
3.3.2 describes how the binding tables can be constructed.
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 2.2) of objects
gets to handle the action.
3.3.1 The binding setup functions
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 3.3.2 and
following sections.
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.
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 n:th
workspaces is bound to Mod1+n (using global_bindings
explained below) while the switch to n:th tab is bound to the
sequence Mod1+k n (using genframe_bindings and
submap).
So, in brief this little additional complexity in configuration is the
price of flexibility.
Ioncore binding setup functions
The following binding setup functions are defined by Ioncore and in the
stock configuration file setup, they are set from the file
ion-bindings.lua:
|
Function |
Handler parameters and description |
|
global_bindings |
Parameters to handler: WScreen |
|
Description: Bindings that are available all the
time. |
mplex_bindings |
Parameters to handler: WMPlex |
|
Description: Bindings that are common to all
WMPlexes (screens and frames). Usually
only bindings that affect current client window
(if any) are set here. |
genframe_bindings |
Parameters to handler:
WGenFrame, [WRegion] |
|
Description: Bindings that are common to all
types of frames (but not screens unlike
mplex_bindings above. When a tab has been
pressed the WRegion corresponding to the
tab is passed as the extra parameter. |
IonWS module binding setup functions
The following binding setup functions are defined by the IonWS module
and in the stock configuration file setup the bindings are set in
ionws.lua:
|
Function |
Handler parameters and description |
|
ionws_bindings |
Parameters to handler:
WIonWS, WRegion |
|
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. |
ionframe_bindings |
Parameters to handler:
WIonFrame, [WRegion] |
|
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. |
ionframe_moveres_bindings |
Parameters to handler:
WIonFrame |
|
Description: Resize mode bindings. Activated
by calling WIonFrame.begin_resize. Only
certain functions may be called here; see the
function reference for details. |
FloatWS module binding setup functions
These functions are similar to the ones described in the above section for
the FloatWS module. The bindings are defined in the configuration file
floatws.lua:
|
Function |
Handler parameters and description |
|
floatws_bindings |
Parameters to handler:
WFloatWS, [WRegion] |
|
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. |
floatframe_bindings |
Parameters to handler:
WFloatFrame, [WRegion] |
|
Description: Bindings that are specific to
the the conventional floating frames. |
floatframe_moveres_bindings |
Parameters to handler:
WIonFrame |
|
Description: Keyboard move/resize mode
bindings. Activated by calling the function
WFloatFrame.begin_resize. Only certain
functions may be called here; see the
function reference for details. |
Query module binding setup functions
These functions set the bindings for the query module. The bindings are set
from the file query.lua.
|
Function |
Handler parameters and description |
|
input_bindings |
Parameters to handler: WInput |
|
Description: bindings that are common to
message and query boxes; stuff to close
the box and to scroll message or completions. |
query_bindings |
Parameters to handler: WEdln |
|
Description: Bindings to edit text and
finish the query. |
Menu module binding setup functions
These functions set the bindings for the menu module. The bindings are set
from the file menu.lua.
|
Function |
Handler parameters and description |
|
menu_bindings |
Parameters to handler: WMenu |
|
Description: key bindings available in in-frame
menus. |
3.3.2 Defining the bindings
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:
Key presses:
Mouse actions:
-
mclick(buttonspec, func, [, area]),
- mdblclick(buttonspec, func, [, area]),
- mpress(buttonspec, func, [, area]) and
- mdrag(buttonspec, func, [, area]).
The actions that most of these functions correspond to should be clear
and as explained in the reference, kpress_waitrel is simply
kpress 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.
WRegion.close multiple times in a row. The submap
function is used to define submaps or ''prefix maps''. The second
argument to this function is table listing the key press actions
(kpress) in the submap
The parameters keyspec and buttonspec are explained below
in detail. The parameter func 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.
The optional string parameter area may be used to specify a more
precise location where the mouse action should occur for the binding to
take place.
Currently only ionframe_bindings and floatframe_bindings
support any meaningful values for this parameter. The allowed values
are in this case
"border", "tab", "empty_tab", "client" and
nil (for the whole frame).
3.3.3 An example
For example, to just bind the key Mod1+1 to switch to the first
workspace and Mod1+Right to the next workspace, you would make the
following call
global_bindings{
kpress("Mod1+Right", WScreen.switch_nth),
kpress("Mod1+1", function(scr) scr:switch_nth(1) end),
}
Recall that global_bindings{...} is syntactical sugar for
the more cumbersome
global_bindings({...}).
The first definition works, because WScreen.switch_next
(inherited WMPlex.switch_next) is a function that takes a
WScreen as its sole parameter. On the other hand,
WScreen.switch_nth (again inherited WMPlex.switch_nth)
expects two parameters: the screen and the n giving the number of
the workspace to switch to so it could not be directly passed to
kpress. Therefore we had to write around it our ''anonymous''
wrapper function around that takes a single parameter and calls
switch_nth properly. (Recall that scr:switch_nth(1)
is syntactic sugar for WScreen.switch_nth(scr, 1).
Alternatively we could have defined
function switch_1(scr) scr:switch_nth(1) end before the call
to global_bindings and passed switch_1 to kpress
instead of the anonymous function.)
3.3.4 Another example
Similarly to the above example, to bind the key sequence Mod1+k n
switch to the next managed object within a frame, and Mod1+k 1 to the
first, you would issue the following call:
genframe_bindings{
submap("Mod1+k", {
kpress("n", WGenFrame.switch_nth),
kpress("1", function(frame) frame:switch_nth(1) end),
}),
}
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.
3.3.5 Key and button specifications
As seen above, the functions that create key binding specifications require
a keyspec argument. This argument should be a string containing the
name of a key as listed in the X header file keysymdef.h1 without the XK_ prefix.
Most of the key names are quite intuitive while some are not. For example,
the Enter key on the main part of the keyboard has the less common
name Return while the one the numpad is called KP_Enter.
The keyspec string may optionally have multiple ''modifier'' names
followed by a plus sign (+) as a prefix. X defines the following
modifiers:
Shift, Control, Mod1 to Mod5,
AnyModifier and Lock.
X allows binding all of these modifiers to almost any key and while this
list of modifiers does not explicitly list keys such as
Alt that are common on modern keyboards, such
keys are bound to one of the ModN. On systems running XFree86
Alt is usually Mod1. On Suns Mod1 is the diamond key
and Alt something else. One of the ''flying window'' keys on so
called Windows-keyboards is probably mapped to Mod3 if you have
such a key. Use the program xmodmap
to find out what exactly is bound where. AnyModifier is usually
used in submaps to indicate that it doesn't matter which modifier keys
are pressed, if any.
Ion ignores the Lock modifier and any ModN modifiers bound
to
NumLock or
ScrollLock
by default because such2 locking keys may otherwise
cause confusion.
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 Button1 to
Button5.
3.3.6 A further note on the default binding configuration
The variable DEFAULT_MOD in the above listing defaults to
"Mod1+" and is set in ion.lua. 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 Alt. Nevertheless, Mod1 is the default as a
key bound to it is available virtually everywhere.
3.3.7 Client window bindings
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 mplex_bindings by functions that look up the object currently
displayed by the WMPlex (WMPlex.current). 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.
To make it easier to write such bindings, the function
make_mplex_clientwin_fn is used to construct this wrapper
function. The following two binding definitions are essentially
equivalent:
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)),
}
3.4 Winprops
3.4.1 Classes, roles and instances
The so-called ''winprops'' 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
winprop with a table containing the properties to set and the
necessary information to identify a window. This identification
information is more specifically the
class,
role,
instance and
name
of the window. The name 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.
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 name, 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.
|
class |
role |
instance |
name |
|
E |
E |
E |
E |
E |
E |
E |
* |
E |
E |
* |
E |
E |
E |
* |
* |
E |
* |
E |
E |
E |
* |
E |
* |
E |
* |
* |
E |
: |
: |
: |
etc. |
If there are multiple winprops with other identification information
the same but different name, the longest match is chosen.
3.4.2 Finding window identification with xprop
To get the identification information required for winprops, in case of
normally framed windows you may use the command xprop WM_CLASS
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 xprop WM_ROLE.
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 xprop 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.3
If you can guess the title of the transient, the simplest solution
is to use the Mod1+A query (querylib.query_attachclient)
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 Mod1+F3
(querylib.query_lua) Lua code execution query, assuming there's
only one transient (all on one line):
local id=_:current():managed_list()[1]:get_ident();
query_message(_, id.class..'.'..id.instance);
Role and name can be retrieved similarly (see the documentation for
WClientWin.get_ident or WRegion.name). Role may not
always be set.
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.
3.4.3 Supported winprops
Ion currently knows the following winprops:
|
Property |
Type |
Description |
|
switchto |
boolean |
Should a newly mapped client window be switched to within
its frame. |
jumpto |
boolean |
Should a newly created client window always be made
active, even if the allocated frame isn't. |
transient_mode |
string |
"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. |
target |
string |
The name of an object (workspace, frame) that should manage
windows of this type. |
transparent |
boolean |
Should frames be made transparent when this window is selected? |
acrobatic |
boolean |
Set this to true 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. |
max_size |
table |
The table should contain the entries w and h that
override application-supplied maximum size hint. |
aspect |
table |
The table should contain the entries w and h that
override application-supplied aspect ratio hint. |
ignore_resizeinc |
boolean |
Should application supplied size increments be ignored? |
fullscreen |
boolean |
Should the window be initially in full screen mode? |
ignore_cfgrq |
boolean |
Should configure requests on the window be ignored?
Only has effect on windows on floatws:s. |
transients_at_top |
boolean |
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? |
3.4.4 Some common examples
Acrobat Reader
The following is absolutely necessary for Acrobat reader:
winprop{
class = "AcroRead",
instance = "documentShell",
acrobatic = true,
}
Fixing a Mozilla Firebird transient
Mozilla Firebird (0.7) incorrectly does not set the WM_TRANSIENT_FOR
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.
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.
winprop{
class = "MozillaFirebird-bin",
name = "Opening .*",
transient_mode = "current",
}
Forcing newly created windows in named frames
The following winprop should place xterm started with command-line parameter
'-name sysmon' and running a system monitoring program in a
particular frame:
winprop{
class = "XTerm",
instance = "sysmon",
target = "sysmonframe",
}
For this example to work, we have to somehow create a frame with the
name sysmonframe. One way to do this is to make the following
call in the Mod1+F3 Lua code query:
querylib.query_renameframe(_)
Recall that _ 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 sysmonframe, but we could just as well have used the
default name formed from the frame's class name and an instance number.
3.5 The query library
The query module does not implement any queries in itself, but provides
the function query_query to execute arbitrary queries. Some
standard queries implemented with this interface are available in
'querylib' (SHAREDIR/querylib.lua). 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:
The default configuration puts most queries in genframe_bindings
while the exit and restart queries are in global_bindings.
For a listing of the functions, see section 6.10 in the
Function reference.
Querylib also provides functions to generate more queries; for details see
the script.
3.6.1 Defining menus
In the stock configuration file setup, menus are configured in the file
ion-menus.lua as previously mentioned. An example of a
definition of a rather simple menu with a submenu is:
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"),
})
The menulib library must be loaded for some of the functions
discussed here to be available.
The defmenu function is used to define a named menu that can later
be accessed with this name. The menuentry 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 3.6.3 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.
The submenu 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.)
3.6.2 Special menus
The menulib library predefines the following special menus.
These can be used as the menus defined as above.
|
Menu name |
Description |
|
windowlist |
List of all client windows. Activating an entry jumps to that window. |
workspacelist |
List of all workspaces. Activating an entry jumps to that workspaces. |
stylemenu |
List of available look-*.lua style files. Activating an entry
loads that style and ask to save the selection. |
3.6.3 Displaying menus
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: make_menu_fn,
make_bigmenu_fn or make_pmenu_fn. 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.
An example of a binding to display a menu is:
global_bindings{
kpress("F12", make_bigmenu_fn("mainmenu")),
}
The low-level functions menu_menu and menu_pmenu 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.
3.7 Some common configuration tasks
3.7.1 Binding a key to execute a program
Because the exec function immediately executes the argument string,
we must wrap this function in the bindings in the following way:
kpress("SomeKey", function() exec("program --param") end)
The make_exec_fn function can be used as a convenience; the
above is equivalent to
kpress("SomeKey", make_exec_fn("program --param"))
- 1
- This file can usually be found in the directory
/usr/X11R6/include/X11/.
- 2
- Completely useless keys that should be
gotten rid of in the author's opinion.
- 3
- There's a patch to xprop to
fix this, but nothing seems to be happening with respect to including it in
XFree86.