# Configuring and extending Notion with Lua

The Notion Team, `http://notion.sourceforge.net`

Tuomo Valkonen, tuomov at iki.fi

Configuring and extending Notion with Lua
Copyright © 2010-2011 The Notion Team.
Copyright © 2003-2009 Tuomo Valkonen.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''.

The latest version of this document can be found at `http://notion.sourceforge.net` in HTML and PDF formats. Updates are welcome, preferably in the form of patches against the LATEX sources which can be found in the git repository at `git://notion.git.sourceforge.net/gitroot/notion/notion-doc` (`http://notion.git.sourceforge.net/git/gitweb.cgi?p=notion/notion-doc;a=summary`)

## Contents

- 1. Introduction
- 2. Preliminaries: Key concepts and relations
  - 2.1 Modules
  - 2.2 Class and object hierarchies
    - 2.2.1 Class hierarchy
    - 2.2.2 Object hierarchies: WRegion parents and managers
    - 2.2.3 Summary
- 3. Basic configuration
  - 3.1 The configuration files
  - 3.2 A walk through cfg_notion.lua
  - 3.3 Keys and rodents
    - 3.3.1 Binding handlers and special variables
    - 3.3.2 Guards
    - 3.3.3 Defining the bindings
    - 3.3.4 Examples
    - 3.3.5 Key specifications
    - 3.3.6 Button specifications
    - 3.3.7 A further note on the default binding configuration
  - 3.4 Menus
    - 3.4.1 Defining menus
    - 3.4.2 Special menus
    - 3.4.3 Defining context menus
    - 3.4.4 Displaying menus
  - 3.5 Winprops
    - 3.5.1 Properties to set
    - 3.5.2 Identifying windows
    - 3.5.3 Finding window identification
    - 3.5.4 Some common examples
  - 3.6 Dockapps, panels and statusbars
    - 3.6.1 The dock
    - 3.6.2 The statusbar
- 4. Graphical styles
  - 4.1 Drawing engines, style specifications and sub-styles
    - 4.1.1 Known styles and substyles
  - 4.2 Defining styles for the default drawing engine
    - 4.2.1 The structure of the configuration files
    - 4.2.2 Defining the styles
    - 4.2.3 An example
  - 4.3 Miscellaneous settings
    - 4.3.1 Frame user attributes
    - 4.3.2 Extra fields for style `frame'
    - 4.3.3 Extra fields for style `dock'
- 5. Scripting
  - 5.1 Protected mode and (un-)safe functions
  - 5.2 Hooks
  - 5.3 Referring to regions
    - 5.3.1 Direct object references
    - 5.3.2 Name-based lookups
  - 5.4 Alternative winprop selection criteria
  - 5.5 Writing ion-statusd monitors
- 6. Function reference
  - 6.1 Functions defined in ioncore
    - 6.1.1 WClientWin functions
    - 6.1.2 WFrame functions
    - 6.1.3 WGroup functions
    - 6.1.4 WGroupCW functions
    - 6.1.5 WGroupWS functions
    - 6.1.6 WHook functions
    - 6.1.7 WInfoWin functions
    - 6.1.8 WMPlex functions
    - 6.1.9 WMoveresMode functions
    - 6.1.10 WRegion functions
    - 6.1.11 WRootWin functions
    - 6.1.12 WScreen functions
    - 6.1.13 WTimer functions
    - 6.1.14 WWindow functions
    - 6.1.15 global functions
    - 6.1.16 gr functions
    - 6.1.17 string functions
    - 6.1.18 table functions
  - 6.2 Functions defined in mod_tiling
    - 6.2.1 WSplit functions
    - 6.2.2 WSplitInner functions
    - 6.2.3 WSplitRegion functions
    - 6.2.4 WSplitSplit functions
    - 6.2.5 WTiling functions
  - 6.3 Functions defined in mod_query
    - 6.3.1 WComplProxy functions
    - 6.3.2 WEdln functions
    - 6.3.3 WInput functions
  - 6.4 Functions defined in mod_menu
    - 6.4.1 WMenu functions
  - 6.5 Functions defined in mod_dock
    - 6.5.1 WDock functions
  - 6.6 Functions defined in mod_sp
  - 6.7 Functions defined in mod_statusbar
    - 6.7.1 WStatusBar functions
  - 6.8 Functions defined in de
  - 6.9 Hooks
  - 6.10 Miscellaneous
    - 6.10.1 Size policies
- A. GNU Free Documentation License
- B. Full class hierarchy visible to Lua-side
- Index
- Bibliography

# 1. Introduction

This document is an ``advanced user'' manual for the X11 window manager Notion. It is an attempt at documenting things that go into Notion's configuration files, how to configure Notion by simple modifications to these files and how to write more complex extensions in Lua, the lightweight configuration and scripting language used by Notion.

Readers unfamiliar with Lua might first want to first glance at some Lua documentation at

`http://www.lua.org/docs.html`, or
`http://lua-users.org/wiki/LuaTutorial`,

although this should not be strictly necessary for basic modifications of configuration files for anyone with at least some familiarity with programming languages.

Back in this document, first in chapter 2 some key concepts and relations are explained. These include the module system, and Notion's object (or ``region'') and class hierarchies. While it may not be necessary to study the latter for basic copy-paste modifications of configuration files - for that you should not really need this manual either - it is, however, essential to for more extensive customisation, due to the semi-object-oriented nature of most of Notion's scripting interface. Knowing the different object types also helps dealing with the different binding ``contexts'' (see Section 3.3) that to some extent mirror these classes.

The new user, fed up with the default key bindings and eager to just quickly configure Notion to his liking, may therefore just want to skip to Chapter 3, and attempt to work from therefore. That chapter provides the very basic Notion configuration know-how is provided: all the different configuration files and their locations are explained, instructions are given to allow the reader to configure bindings and so-called ``winprops'', and the statusbar templates are also explained.

Next, Chapter 4 explains the notion of drawing engines and graphical styles and how to write new looks for Notion. More advanced aspects of Notion's scripting interface are documented in Chapter 5. Finally, most of the functions provided by Notion's scripting interface are listed and documented in the Function reference in Chapter 6. At the end of the document an alphabetical listing of all these functions may be found.

#
2. Preliminaries: Key concepts and relations

The purpose of this chapter to explain some of key concepts and relations you need to understand before reading the following chapters. These include modules explained in section 2.1 and the Notion class and object hierarchies, section 2.2.

##
2.1 Modules

Notion has been designed so that the 'notion' executable only implements some basic services on top of which very different kinds of window managers could be build by loading the appropriate 'modules'. On modern system these modules are simply dynamically loaded .so libraries. On more primitive systems, or if you want to squeeze total size of the executable and libraries, the modules can optionally be statically linked to the main binary, but must nevertheless be loaded with the `dopath` function. Modules may also include Lua code.

Currently Ion provides the following modules:

mod_tiling
  Tilings for workspaces of the original tiled Notion kind.
mod_query
  Queries (for starting programs and so on) and message boxes.
mod_menu
  Support for menus, both pull-down and keyboard-operated in-frame menus.
mod_statusbar
  Module that implements a statusbar that can be adaptively embedded in each workspace's layout.
mod_dock
  Module for docking Window Maker dock-apps. The dock can both float and be embedded as the statusbar.
mod_sp
  This module implements a scratchpad frame that can be toggled on/off everywhere. Think of the 'console' in some first-person shooters.
mod_sm
  Session management support module. Loaded automatically when needed!

So-called drawing engines are also implemented as a modules, but they are not discussed here; see chapter 4.

The stock configuration for the notion executable loads all of the modules mentioned above except mod_dock. The stock configuration for the pwm3 executable (which differs from the notion executable in a few configuration details) loads another set of modules.

##
2.2 Class and object hierarchies

While Notion does not have a truly object-oriented design2.1, things that appear on the computer screen are, however, quite naturally expressed as such ``objects''. Therefore Notion implements a rather primitive OO system for these screen objects and some other things.

It is essential for the module writer to learn this object system, but also people who write their own binding configuration files necessarily come into contact with the class and object hierarchies - you need to know which binding setup routines apply where, and what functions can be used as handlers in which bindings. It is the purpose of this section to attempt to explain these hierarchies. If you do not wish the read the full section, at least read the summary at the end of it, so that you understand the very basic relations.

For simplicity we consider only the essential-for-basic-configuration Notioncore, mod_tiling and mod_query classes. See Appendix B for the full class hierarchy visible to Lua side.

### 2.2.1 Class hierarchy

One of the most important principles of object-oriented design methodology is inheritance; roughly how classes (objects are instances of classes) extend on others' features. Inheritance gives rise to class hierarchy. In the case of single-inheritance this hierarchy can be expressed as a tree where the class at the root is inherited by all others below it and so on. The tree below lists out the Notion class hierarchy and below we explain what features of Notion the classes implement.

####
2.2.1.1 Partial Notioncore, mod_tiling and mod_query class hierarchy

        Obj
         |-->WRegion
         |    |-->WClientWin
         |    |-->WWindow
         |    |    |-->WRootWin
         |    |    |-->WMPlex
         |    |    |    |-->WFrame
         |    |    |    `-->WScreen
         |    |    `-->WInput (mod_query)
         |    |         |-->WEdln (mod_query)
         |    |         `-->WMessage (mod_query)
         |    |-->WGroup
         |    |    |-->WGroupWS
         |    |    `-->WGroupCW
         |    `-->WTiling (mod_tiling)
         `-->WSplit (mod_tiling)

#### 2.2.1.2 The core classes

Obj
  Is the base of Notion's object system.

WRegion
  is the base class for everything corresponding to something on the screen. Each object of type WRegion has a size and position relative to the parent WRegion. While a big part of Notion operates on these instead of more specialised classes, WRegion is a ``virtual'' base class in that there are no objects of ``pure'' type WRegion; all concrete regions are objects of some class that inherits WRegion.

WClientWin
  is a class for client window objects, the objects that window managers are supposed to manage.

WWindow
  is the base class for all internal objects having an X window associated to them (WClientWins also have X windows associated to them).

WMPlex
  is a base class for all regions that ``multiplex'' other regions. This means that of the regions managed by the multiplexer, only one can be displayed at a time.

WScreen
  is an instance of WMPlex for screens.

WRootWin
  is the class for root windows of X screens. Note that an ``X screen'' or root window is not necessarily a single physical screen as a root window may be split over multiple screens when techniques such as Xinerama are used. (Actually there can be only one root window when Xinerama is used.)

WFrame
  is the class for frames. While most Notion's objects have no graphical presentation, frames basically add to WMPlexes the decorations around client windows (borders, tabs).

WGroup
  is the base class for groups. Particular types of groups are workspaces (WGroupWS) and groups of client windows (WGroupCW).

Classes implemented by the mod_tiling module:

WTiling
  is the class for tilings of frames.
WSplit
  (or, more specifically, classes that inherit it) encode the WTiling tree structure.

Classes implemented by the mod_query module:

WInput
  is a virtual base class for the two classes below.
WEdln
  is the class for the ``queries'', the text inputs that usually appear at bottoms of frames and sometimes screens. Queries are the functional equivalent of ``mini buffers'' in many text editors.
WMessage
  implements the boxes for warning and other messages that Notion may wish to display to the user. These also usually appear at bottoms of frames.

There are also some other ``proxy'' classes that do not refer to objects on the screen. The only important one of these for basic configuration is WMoveresMode that is used for binding callbacks in the move and resize mode.

#### 2.2.1.3 Run-time access to types

Even though it often indicates a design mistake, sometimes it can be useful to have run-time access to the types of objects.

For example, to check wether a given object is of type WMPlex, the following C code can be used:

        if(obj_is((Obj*)cwin, &CLASSDESCR(WMPlex)))
            ....

Its lua counterpart is:

        if(obj_is(cwin, "WMPlex"))
            ....

While there's also an 'obj_cast' method available, C structs can be freely cast to their 'superclass' using a regular C cast, for example:

    bool input_fitrep(WInput *input, WWindow *par, const WFitParams *fp)
    {
        if(par!=NULL && !region_same_rootwin((WRegion*)input, (WRegion*)par))
            return FALSE;
        ...

### 2.2.2 Object hierarchies: WRegion parents and managers

#### 2.2.2.1 Parent-child relations

Each object of type WRegion has a parent and possibly a manager associated to it. The parent for an object is always a WWindow and for WRegion with an X window (WClientWin, WWindow) the parent WWindow is given by the same relation of the X windows. For other WRegions the relation is not as clear. There is generally very few restrictions other than the above on the parent--child relation but the most common is as described in paragraph 2.2.2.

####
2.2.2.1.1 Most common parent-child relations

        WRootWins
         |-->WGroupWSs
         |-->WTilings
         |-->WClientWins in full screen mode
         `-->WFrames
              |-->WGroupCWs
              |-->WClientWins
              |-->WFrames for transients
              `-->a possible WEdln or WMessage

#### 2.2.2.2 Manager-managed relations

WRegions have very little control over their children as a parent. The manager WRegion has much more control over its managed WRegions. Managers, for example, handle resize requests, focusing and displaying of the managed regions. Indeed the manager--managed relationship gives a better picture of the logical ordering of objects on the screen. Again, there are generally few limits, but the most common hierarchy is given in Figure . Note that sometimes the parent and manager are the same object and not all regions may have a manager, but all non-screen regions have a parent--a screen if not anything else.

####
2.2.2.2.1 Most common manager-managed relations

        WRootWins
         |-->WGroupCWs for full screen WClientWins
         |    |-->WClientWins
         |    `-->WFrames for transients (dialogs)
         |         `--> WClientWin
         |-->WGroupWSs for workspaces
         |    |-->WTiling
         |    |    |-->WFrames
         |    |    |    `-->WGroupCWs (with contents as above)
         |    |    `-->possibly a WStatusBar or WDock
         |    |-->WFrames for floating content
         |    |-->possibly a WEdln, WMessage or WMenu
         |    `-->possibly a WStatusBar or WDock (if no tiling)
         `-->WFrames for sticky stuff, such as the scratchpad

Note that a workspace can manage another workspace. This can be achieved with the `WGroup.attach_new` function, and allows you to nest workspaces as deep as you want.

In the presense of Xinerama there may be WScreen objects at the top of the manager-managed tree instead of WRootWin.

### 2.2.3 Summary

In the standard setup, keeping queries, messages and menus out of consideration:

- The top-level objects that matter are screens and they correspond to physical screens. The class for screens is WScreen.
- Screens contain (multiplex) groups (WGroup) and other objects, such as WFrames. Some of these are mutually exclusive to be viewed at a time.
- Groups of the specific kind WGroupWS often contain a WTiling tiling for tiling frames (WFrame), but groups may also directly contain floating frames.
- Frames are the objects with decorations such as tabs and borders. Frames contain (multiplex) among others (groups of) client windows, to each of which corresponds a tab in the frame's decoration. Only one client window (or other object) can be shown at a time in each frame. The class for client windows is WClientWin.

#
3. Basic configuration

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

Section 3.1 is an overview of the multiple configuration files Notion uses and as a perhaps more understandable introduction to the general layout of the configuration files, a walk-through of the main configuration file cfg_notion.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.5 winprops are explained. Finally, the statusbar is explained in 3.6.2. For a reference on exported functions, see section 6.

##
3.1 The configuration files

Notion stores its stock configuration files in /usr/local/etc/notion/ unless you, the OS package maintainer or whoever installed the package on the system has modified the variables `PREFIX` or `ETCDIR` in system.mk before compiling Notion. In the first case you probably know where to find the files and in the other case the system administrator or the OS package maintainer should have provided documentation to point to the correct location. If these instructions are no help in locating the correct directory, the command `locate cfg_notion.lua` might help provided `updatedb` has been run recently.

User configuration files go in ~/.notion/. Notion always searches the user configuration file directory before the stock configuration file directory for files. Therefore, if you want to change some setting, it is advised against that you modify the stock configuration files in-place as subsequent installs of Notion will restore the stock configuration files. Instead you should always make a copy of the stock file in ~/.notion/ and modify this file. For sake of maintainability of your customised configuration, it is recommended against copying all of the files there. Only copy those files you actually need to modify. Most simple customisations, such as changes in a few bindings, are best done entirely within cfg_notion.lua.

All the configuration files are named cfg_*.lua with the ``*'' part varying. The configuration file for each module mod_modname is cfg_modname.lua, with modname varying by the module in question. Configuration files can also be compiled into .lc files, and these are attempted by the configuration file search routines before .lua files.

The following table summarises these and other configuration files:

File
cfg_notion.lua
cfg_notioncore.lua
cfg_kludges.lua
cfg_layouts.lua
cfg_tiling.lua cfg_query.lua cfg_menu.lua cfg_dock.lua cfg_statusbar.lua ...

Additionally, there's the file look.lua that configures the drawing engine, but it is covered in chapter 4.

##
3.2 A walk through cfg_notion.lua

As already mentioned cfg_notion.lua is Notion'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 Notion are loaded there. In this section we take a walk through the stock cfg_notion.lua. Notice that most of the settings are commented-out (`--` is a line comment in Lua) in the actual file, as they're the defaults nevertheless.

The first thing done in the file, is to set

    META="Mod1+"
    ALTMETA=""

These settings cause most of Notion's key bindings to use Mod1 as the modifier key. If `ALTMETA` is set, it is used as modifier for the keys that don't normally use a modifier. Note that these two are Lua variables used in the configuration files only, and not Notion settings. For details on modifiers and key binding setup in general, see section 3.3.

Next we do some basic feel configuration:

    ioncore.set{
        dblclick_delay=250,
        kbresize_delay=1500,
    }

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

    ioncore.set{
        opaque_resize=true,
        warp=true
    }

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

There are some other options as well; see the documentation for `ioncore.set` for details.

As a next step, in the actual cfg_notion.lua file, we load cfg_defaults.lua. However, it is merely a convenience file for doing exactly what we will going through below, and what is commented out in the actual file. If you do not want to load what cfg_defaults.lua loads, just comment out the corresponding line, and uncomment the lines for the files that you want:

    --dopath("cfg_defaults")
    dopath("cfg_notioncore")
    dopath("cfg_kludges")
    dopath("cfg_layouts")

Most bindings and menus are defined in cfg_ioncore.lua. Details on making such definitions follow in sections 3.3 and 3.4, respectively. some kludges or ``winprops'' to make some applications behave better under Notion are collected in cfg_kludges.lua; see section 3.5 for details. In addition to these, this file lists quite a few statements of the form

    ioncore.defshortening("[^:]+: (.*)(<[0-9]+>)", "$1$2$|$1$<...$2")

These are used to configure how Notion 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 `ioncore.defshortening`. Finally, cfg_layouts.lua defines some workspace layouts, available through the F9 workspace creation query.

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

    dopath("mod_query")
    dopath("mod_menu")
    dopath("mod_tiling")
    dopath("mod_statusbar")
    --dopath("mod_dock")
    dopath("mod_sp")

##
3.3 Keys and rodents

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

Bindings are defined by calling the function `defbindings` with the ``context'' of the bindings and the a table of new bindings to make. The context is simply string indicating one of the classes of regions (or modes such as WMoveresMode) introduced in section 2.2, and fully listed in appendix B, although not all define a binding map. For example, the following skeleton would be used to define new bindings for all frames:

    defbindings("WFrame", {
        -- List of bindings to make goes here.
    })

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

Currently known contexts include: ``WScreen`', ``WMPlex`', ``WMPlex.toplevel`', ``WFrame`', ``WFrame.toplevel`', ``WFrame.floating`', ``WFrame.tiled`', ``WFrame.transient`', ``WMoveresMode`', ``WGroup`', ``WGroupCW`', ``WGroupWS`', ``WClientWin`', ``WTiling`', and ``WStatusBar`'. Most of these should be self-explanatory, corresponding to objects of class with the same name. The ones with ``.toplevel`' suffix refer to screens and ``toplevel'' frames, i.e. frames that are not used for transient windows. Likewise ``.transient`' refers to frames in transient mode, and ``.tiled`' and ``.floating`' to frames in, respectively, tiled and floating modes.

The following subsections describe how to construct elements of the binding table. Note that `defbindings` adds the the newly defined bindings to the previous bindings of the context, overriding duplicates. To unbind an event, set the handler parameter to `nil` for each of the functions to be described in the following subsections.

Also note that when multiple objects want to handle a binding, the innermost (when the root window is considered the outermost) active object in the parent-child hierarchy (see Figure ) of objects gets to handle the action.

### 3.3.1 Binding handlers and special variables

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

Variable
`_` (underscore)
`_sub`
`_chld`

For example, supposing `_` (underscore) is a WFrame, the following handler should move the active window to the right, if possible:

    "_:inc_index(_sub)"

### 3.3.2 Guards

To suppress error messages, each binding handler may also be accompanied by a ``guard'' expression that blocks the handler from being called when the guard condition is not met. Currently the following guard expressions are supported (for both `_sub` and `_chld`):

Guard
``_sub:non-nil`'
``_sub:SomeClass`'

###
3.3.3 Defining the bindings

The descriptions of the individual bindings in the binding table argument to `defbindings` should be constructed with the following functions.

Key presses:

- `kpress`, and `kpress_wait``(keyspec, handler [, guard])`.
- `submap``(keyspec, { ... more key bindings ... })`.
- `submap_enter`, and `submap_wait``(handler [, guard])`.

Mouse actions:

- `mclick`, `mdblclick`, `mpress`, and `mdrag``(buttonspec, handler [, guard])`.

The actions that most of these functions correspond to should be clear and as explained in the reference, `kpress_wait` is simply `kpress` with a flag set instructing Notioncore wait for all modifiers to be released before processing any further actions. This is to stop one from accidentally calling e.g. `WRegion.rqclose` 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 `submap_enter` handler is called when the submap is entered, in which this handler is defined. Likewise, the `submap_wait` handler is called when all modifiers have been released while waiting for further key presses in the submap.

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

### 3.3.4 Examples

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

    defbindings("WScreen", {
        kpress("Mod1+Right", "_:switch_next()"),
        kpress("Mod1+1", "_:switch_nth(1)"),
    })

Note that `_:switch_nth(1)` is the same as calling `WMPlex.switch_next``(_, 1)` as WScreen inherits WMPlex and this is where the function is actually defined.

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:

    defbindings("WFrame", {
        submap("Mod1+K", {
            kpress("Right", "_:switch_next()"),
            kpress("1", "_:switch_nth(1)"),
       }),
    })

### 3.3.5 Key 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.h 3.1 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.

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

Notion ignores the Lock modifier and any ModN ( N = 1...5 mathend000#) bound to NumLock or ScrollLock by default because such3.2 locking keys may otherwise cause confusion.

### 3.3.6 Button specifications

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. Additionally the specification may end with an optional area name following an @-sign. Only frames currently support areas, and the supported values in this case are ``border`', ``tab`', ``empty_tab`', ``client`' and `nil` (for the whole frame).

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

    defbindings("WFrame", {
        mdrag("Button1@tab", "_:p_tabdrag()"),
    })

### 3.3.7 A further note on the default binding configuration

The default binding configuration contains references to the variables `META` and `ALTMETA` instead of directly using the default values of ``Mod1+`' and `' (nothing). As explained in section 3.2, the definitions of these variables appear in cfg_notion.lua. This way you can easily change the the modifiers used by all bindings in the default configuration without changing the whole binding configuration. Quite a few people prefer to use the Windows keys as modifiers because many applications already use Alt. Nevertheless, Mod1 is the default as a key bound to it is available virtually everywhere.

##
3.4 Menus

### 3.4.1 Defining menus

In the stock configuration file setup, menus are defined in the file cfg_menus.lua as previously mentioned. The mod_menu module must be loaded for one to be able to define menus, and this is done with the function `defmenu` provided by it.

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

    defmenu("exitmenu", {
        menuentry("Restart", "ioncore.restart()"),
        menuentry("Exit", "ioncore.shutdown()"),
    })

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

The `menuentry` function is used to create an entry in the menu with a title and an entry handler to be called when the menu entry is activated. The parameters to the handler are similar to those of binding handlers, and usually the same as those of the binding that opened the menu.

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.4.2 Special menus

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

Menu name
``windowlist`'
``workspacelist`'
``focuslist`'
``focuslist_`'
``stylemenu`'
``ctxmenu`'

### 3.4.3 Defining context menus

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

Context menus for a given region class are defined with the `defctxmenu` function. This is other ways similar to `defmenu`, but the first argument instead being the name of the menu, the name of the region class to define context menu for. For example, here's part of the stock WFrame context menu definition:

    defctxmenu("WFrame", {
        menuentry("Close", "WRegion.rqclose_propagate(_, _sub)"),
        menuentry("Kill",  "WClientWin.kill(_sub)", "_sub:WClientWin"),
    })

Some of the same ``modes'' as were available for some bindings may also be used: ``WFrame.tiled`', ``WFrame.floating`', and ``WFrame.transient`'.

###
3.4.4 Displaying menus

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

Function
`mod_menu.menu`
`mod_menu.pmenu`
`mod_menu.grabmenu`

Each of these functions takes three arguments, which when called from a binding handler, should be the parameters to the handler, and the name of the menu. For example, the following snippet of of code binds the both ways to open a context menu for a frame:

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

##
3.5 Winprops

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 `defwinprop` with a table containing the properties to set and the necessary information to identify a window. The currently supported winprops are listed below, and the subsequent subsections explain the usual method of identifying windows, and how to obtain this information.

### 3.5.1 Properties to set

These properties can be used to tell Notion how to treat the matched windows:

Winprop:
  `acrobatic` (boolean)
Description:
  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 Notion and acrobat go a window-switching loop when a dialog is opened.

Winprop:
  `float` (boolean)
Description:
  Set this to open the window in a floating frame, when in a group.

Winprop:
  `fullscreen` (boolean)
Description:
  Should the window be initially in full screen mode?

Winprop:
  `ignore_cfgrq` (boolean)
Description:
  Should configure requests on the window be ignored? Only has effect on floating windows.

Winprop:
  `ignore_net_active_window` (boolean)
Description:
  Ignore extended WM hints `_NET_ACTIVE_WINDOW` request.

Winprop:
  `jumpto` (boolean)
Description:
  Should a newly created client window always be made active, even if the allocated frame isn't.

Winprop:
  `lazy_resize` (boolean)
Description:
  Do not resize a region when it is currently hidden, resize it when the user switches to it instead. Useful for applications that raise themselves on resize (like VirtualBox) or when many (hidden) frames with resource-intensive resize routines cause performance issues.

Winprop:
  `new_group` (string)
Description:
  If the region specified by `target` winprop does not exist (or that winprop is not set), create a new workspace using the previously stored layout (see `ioncore.deflayout`) named by this property. After creating the workspace, `target` is attempted to be found again. (If that still fails, the newly created workspace is still asked to manage the client window.)

Winprop:
  `oneshot` (boolean)
Description:
  Discard this winprop after first use.

Winprop:
  `orientation` (string)
Description:
  The orientation of the window: one of ``vertical`' or ``horizontal`'. This is only useful when using the window as a status display.

Winprop:
  `statusbar` (string)
Description:
  Put the window in the statusbar, in the named tray component, (The default tray component is called simply ``systray`', and others you give names to in your custom template, always prefixed by ``systray_`'.

Winprop:
  `switchto` (boolean)
Description:
  Should a newly mapped client window be switched to within its frame.

Winprop:
  `target` (string)
Description:
  The name of an object (workspace, frame) that should manage windows of this type. See also `new_group`.

Winprop:
  `transient_mode` (string)
Description:
  ``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.

Winprop:
  `transparent` (boolean)
Description:
  Should frames be made transparent when this window is selected?

#### 3.5.1.1 Sizehint winprops

Additionally, the winprops `max_size`, `min_size`, `aspect`, `resizeinc`, and `ignore_max_size`, `ignore_min_size`, `ignore_aspect`, `ignore_resizeinc`, may be used to override application-supplied size hints. The four first ones are tables with the fields `w` and `h`, indicating the width and height size hints in pixels, and the latter ignore winprop is a boolean.

Finally, the boolean `userpos` option may be used to override the `USPosition` flag of the size hints. Normally, when this flag is set, Notion tries to respect the supplied window position more than when it is not set. Obviously, this makes sense only for floating windows.

### 3.5.2 Identifying windows

The primary identification information supported is the `class`, `role` and `instance` of the window.

Secondary filters are the `name`, `is_transient` and `is_dockapp` fields, or a custom matching algorithm.

Notion first filters the winprops based on the primary identification fields. Of those winprops that match the primary identification fields, the most recently defined winprop that also matches the secondary filters is used.

####
3.5.2.1 Classes, roles and instances

The primary identification fields are strings, and must exactly match the corresponding information obtained from the window's properties.

Notion looks for a 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. 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`
E | E | E
E | E | *
E | * | E
E | * | *
&vellip#vdots; | &vellip#vdots; | etc.

#### 3.5.2.2 Secondary filters

The `name` field is a Lua-style regular expression matched against the window's title. The `is_transient` field is a boolean that can be used to include or exclude transients only, while the `is_dockapp` field is set by Notion for the dock windows of Window Maker dockapp protocol dockapps. Usually this is the only information available for these icon windows.

#### 3.5.2.3 Custom matching algorithms

If a custom matching algorithm is used, the secondary filters are ignored.

A custom matching algorithm can be specified by simple adding a lua function named `match` to the winprop table. This function will be passed 3 parameters: the winprop itself, the client window against which the winprop must be matched, and the identification information of this client window.

The identification information of the client window is a table containing the `class`, `role`, `instance`, `is_transient` and `is_dockapp` fields of the window.

### 3.5.3 Finding window identification

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

Another way to get the identification information is to use `xprop`. Simply run To get class and instance, simply run `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`. This method, however, will not work on transients.

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 Notion displays these windows simultaneously 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.3

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 program's windows, for example. Some other programs only set this information after the window has been mapped, i.e. the window manager has been told to start managing it, which is obviously too late. Gtk applications in particular are often guilty on both counts.

### 3.5.4 Some common examples

#### 3.5.4.1 Acrobat Reader

The following is absolutely necessary for Acrobat reader:

    defwinprop{
        class = "AcroRead",
        instance = "documentShell",
        acrobatic = true,
    }

#### 3.5.4.2 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:

    defwinprop{
        class = "XTerm",
        instance = "sysmon",
        target = "sysmonframe",
    }

For this example to work, we have to somehow create a frame named ``sysmonframe`'. One way to do this is to make the following call in the Mod1+F3 Lua code query:

    mod_query.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.6 Dockapps, panels and statusbars

Most window managers have some kind of 'dock' or statusbar/panel to give a quick overview of running processes and system status. Notion is no different - actually we have several options.

When a part of the screen is reserved for this purpose, in Notion this is called a ``status display'' or ``stdisp''. You can have one stdisp per Screen - it is independent of the current workspace or tiling.

Notion has 2 kinds of stdisp's: if you want to use one or more existing panel/dock applications, you can use mod_dock with the ``embedded'' mode. Alternatively, you can use the built-in mod_statusbar. Since a Screen can only hold one stdisp, you can have either - not both.

### 3.6.1 The dock

Generally, if you want to use some panel application like the xfce4-panel, fbpanel or the gnome-panel, use an embedded dock. When used in this way, it is common to add only one panel to the dock and have it span the entire width of the screen. However, the dock does support adding multiple applications to it, so if you prefer WindowMaker-style dockapps, mod_dock (either embedded or floating) is also the way to go.

###
3.6.2 The statusbar

Given the high quality of 3rd-party panels, mod_statusbar is mostly a legacy part of Notion.

The mod_statusbar module provides a statusbar that adapts to layouts of tilings, using only the minimal space needed.

The statusbar is configured in cfg_statusbar.lua. Typically, the configuration consists of two steps: creating a statusbar with `mod_statusbar.create`, and then launching the separate `ion-statusd` status daemon process with `mod_statusbar.launch_statusd`. This latter phase is done automatically, if it was not done by the configuration file, but the configuration file may pass extra parameters to `ion-statusd` monitors. (See Section 5.5 for more information on writing `ion-statusd` monitors.)

A typical cfg_statusbar.lua configuration might look as follows:

    -- Create a statusbar
    mod_statusbar.create{
        screen = 0,     -- First screen,
        pos = 'bl',     -- bottom left corner
        systray = true, -- Swallow systray windows

        -- The template
        template = "[ %date || load:% %>load || mail:% %>mail_new/%>mail_total ]"
                   .. " %filler%systray",
    }

    -- Launch ion-statusd.
    mod_statusbar.launch_statusd{
        -- Date meter
        date={
            -- ISO-8601 date format with additional abbreviated day name
            date_format='%a %Y-%m-%d %H:%M',
        },
    }

#### 3.6.2.1 The template

The template specifies what is shown on the statusbar; for information on the other options to `mod_statusbar.create`, see the reference. Strings of the form ``%spec`' tokens specially interpreter by the statusbar; the rest appears verbatim. The `spec` typically consists of the name of the value/meter to display (beginning with a latin alphabet), but may be preceded by an alignment specifier and a number specifying the minimum width. The alignment specifiers are: ``>`' for right, ``<`' for left, and ``|`' for centring. Additionally, space following ``%`' (that is, the string ``%` '), adds ``stretchable space'' at that point. The special string ``%filler`' may be used to flush the rest of the template to the right end of the statusbar.

The stretchable space works as follows: mod_statusbar remembers the widest string (in terms of graphical presentation) that it has seen for each meter, unless the width has been otherwise constrained. If there is stretchable space in the template, it tries to make the meter always take this much space, by stretching any space found in the direction indicated by the alignment specifier: the opposite direction for left or right alignment, and both for centring.

#### 3.6.2.2 The systray

The special ``%systray`' and ``%systray_*`' (``*`' varying) monitors indicate where to place system tray windows. There may be multiple of these. KDE-protocol system tray icons are placed in ``%systray`' automatically, unless disabled with the `systray` option. Otherwise the `statusbar` winprop may be used to place any window in any particular ``%systray_*`'.

#### 3.6.2.3 Monitors

The part before the first underscore of each monitor name, describes the script/plugin/module that provides the meter, and any configuration should be passed in the a corresponding sub-table `mod_statusbar.launch_statusd`. Notion comes with date, load and mail (for plain old mbox) `ion-statusd` monitor scripts. More may be obtained from the scripts repository [1]. These included scripts provide the following monitors and their options

#### 3.6.2.3.1 Date

Options: `date_format`: The date format in as seen above, in the usual `strftime` format. `formats`: table of formats for additional date monitors, the key being the name of the monitor (without the ``date_`' prefix).

Monitors: ``date`' and other user-specified ones with the ``date_`' prefix.

#### 3.6.2.3.2 Load

Options: `update_interval`: Update interval in milliseconds (default 10s). `important_threshold`: Threshold above which the load is marked as important (default 1.5), so that the drawing engine may be suitably hinted. `critical_threshold`: Threshold above which the load is marked as critical (default 4.0).

Monitors: ``load`' (for all three values), ``load_1min`', ``load_5min`' and ``load_15min`'.

#### 3.6.2.3.3 Mail

Options: `update_interval`: Update interval in milliseconds (default 1min). `mbox`: mbox-format mailbox location (default `$MAIL`). `files`: list of additional mailboxes, the key giving the name of the monitor.

Monitors: ``mail_new`', ``mail_unread`', ``mail_total`', and corresponding ``mail_*_new`', ``mail_*_unread`', and ``mail_*_total`' for the additional mailboxes (``*`' varying).

#
4. Graphical styles

This chapter first gives in section 4.1 a general outline of how drawing engines are used, of style specifications and then in section 4.2 describes how to specify styles for the default drawing engine. Some additional settings and user attributes are explained in Sections 4.3.

##
4.1 Drawing engines, style specifications and sub-styles

Notion's drawing routines are abstracted into so-called drawing engine modules that can, again depending on the system, be dynamically loaded as needed. The drawing engine modules provide ``brushes'' that objects can use to draw some high-level primitives such as borders and text boxes (in addition to simple text and rectangle drawing) on their windows and configure e.g. the shape and background of the window. While the drawing engines therefore do not directly implement looks for each possible object (that would hardly be maintainable), different brush styles can be used to give a distinctive look to different objects and engines could interpret some styles as special cases. Style specifications are strings of the form

    element1-element2-...-elementn

An example of such a style specification is ``tab-frame`'; see the table in subsection 4.1.1 for more styles.

When an object asks for a brush of certain style, the selected drawing engine will attempt to find the closest match to this specification. The styles/brushes defined by the drawing engines may have asterisks (``*`') as some of the elements indicating a match to anything. Exact matches are preferred to asterisk matches and longer matches to shorter. For example, let a brush for style ``foo-bar-baz`' be queried, then the following brushes are in order of preference:

    foo-bar-baz
    foo-*-baz
    foo-bar
    *

Some of the drawing primitives allow extra attributes to be specified, also in the form

    attr1-attr2-...-attrn

These extra attributes are called substyles and allow, for example, the state of the object to be indicated by different colour sets while keeping the interface at an abstract level and the drawing engine completely ignorant of the semantics - only the writer of the drawing engine configuration file has to know them. However the drawing engine can again interpret known substyles as special cases and the default engine indeed does so with frame tab tag and drag states.)

###
4.1.1 Known styles and substyles

#### 4.1.1.1 Frames

Style name
``frame`'
``frame-tiled`'
``frame-tiled-alt`'
``frame-floating`'
``frame-transient`'

#### 4.1.1.2 Tabs and menu entries

Style name
``tab`'
``tab-frame`'
``tab-frame-tiled`',
``tab-frame-tiled-alt`',
``tab-frame-floating`',
``tab-frame-transient`'
``tab-menuentry`'
``tab-menuentry-bigmenu`'
``tab-info`'

#### 4.1.1.3 The rest

Style name
``input`'
``input-edln`'
``input-message`'
``input-menu`'
``input-menu-bigmenu`'
``moveres_display`'
``actnotify`'
``stdisp`'
``stdisp-dock`'
``stdisp-statusbar`'

##
4.2 Defining styles for the default drawing engine

Drawing engine style files are usually named look_foo.lua where foo is the name of the style. The file that Notion loads on startup or when `gr.read_config` is called, however, is look.lua and should usually be symlinked to or a copy of of some look_foo.lua.

### 4.2.1 The structure of the configuration files

The first thing to do in a style file is to choose the drawing engine, possibly loading the module as well. This is done with the following chunk of code.

    if not gr.select_engine("de") then
        return
    end

The `gr.select_engine` function sees if the engine given as argument is registered (the default drawing engine is simply called ``de''). If the engine could not be found, it tries to load a module of the same name. If the engine still is not registered, `gr.select_engine` returns ``false`' and in this case we also exit the style setup script. If the engine was found, `gr.select_engine` sees that further requests for brushes are forwarded to that engine and returns ``true`'.

Before defining new styles it may be a good idea to clear old styles from memory so if the old configuration defines more specific styles than the new, the old styles don't override those specified by the new configuration. That can be done by calling

    de.reset()

After this the new styles can be defined with `de.defstyle` as explained in the next subsection. Finally, after the styles have been defined we must ask objects on the screen to look up new brushes to reflect the changes in configuration. This is done with

    gr.refresh()

### 4.2.2 Defining the styles

Styles for the default drawing engine are defined with the function `de.defstyle`. It has two arguments the first being a style specification as explained in previous sections and the second a table whose fields describe the style:

    de.defstyle("some-style", {
        attribute = value,
        ...
    })

The supported attributes are described in tables below. The different border elements and styles referred to there are explained in the following sketch of different border styles and elements:

    Elevated:        Inlaid:         Ridge:            Groove:
      hhhhhhhhhhhs     ............	   hhhhhhhhhhhs      sssssssssssh
      h..........s     .sssssssssh.	   h..........s      s..........h
      h.        .s     .s        h.	   h.sssssssh.s      s.hhhhhhhs.h
      h.        .s     .s        h.	   h.s      h.s      s.h      s.h
      h.        .s     .s        h.	   h.shhhhhhh.s      s.hsssssss.h
      h..........s     .shhhhhhhhh.	   h..........s      s..........h
      hsssssssssss     ............	   hsssssssssss      shhhhhhhhhhh

    h = highlight, s = shadow, . = padding

#### 4.2.2.1 Colours

Each of these fields a string of the form that can be passed to `XAllocNamedColor`. Valid strings are e.g. hexadecimal RGB specifications of the form `#RRGGBB` and colour names as specified in /usr/X11R6/lib/X11/rgb.txt (exact path varying).

Field
`highlight_colour`
`shadow_colour`
`foreground_colour`
`background_colour`
`padding_colour`

#### 4.2.2.2 Borders and widths

All other fields below except `border_style` are non-negative integers indicating a number of pixels.

Field
`border_style`
`border_sides`
`highlight_pixels`
`shadow_pixels`
`padding_pixels`
`spacing`

#### 4.2.2.3 Text

Field
`font`
`text_align`

#### 4.2.2.4 Miscellaneous

Field
`transparent_background`
`based_on`

#### 4.2.2.5 Substyles

As discussed in previous sections, styles may have substyles to e.g. indicate different states of the object being drawn. The ``de'' engine limits what can be configured in substyles to the set of colours in the first table above, but also specifically interprets for the main style ``tab-frame`' the substyles ``*-*-tagged`' and ``*-*-*-dragged`' by, respectively, drawing a right angle shape at the top right corner of a tab and by shading the tab with a stipple pattern. Also for menus the substyles ``*-*-submenu`' are handled as a special case.

Substyles are defined with the function `de.substyle` within the table defining the main style. The parameters to this function are similar to those of `de.defstyle`.

    de.defstyle("some-style", {
       ...
       de.substyle("some-substyle", {
          ...
       }),
       ...
    })

### 4.2.3 An example

The following shortened segment from look_cleanviolet.lua should help to clarify the matters discussed in the previous subsection.

    de.defstyle("*", {
        -- Gray background
        highlight_colour = "#eeeeee",
        shadow_colour = "#eeeeee",
        background_colour = "#aaaaaa",
        foreground_colour = "#000000",

        shadow_pixels = 1,
        highlight_pixels = 1,
        padding_pixels = 1,
        spacing = 0,
        border_style = "elevated",

        font = "-*-helvetica-medium-r-normal-*-12-*-*-*-*-*-*-*",
        text_align = "center",
    })

    de.defstyle("tab-frame", {
        based_on = "*",

        de.substyle("active-selected", {
            -- Violet tab
            highlight_colour = "#aaaacc",
            shadow_colour = "#aaaacc",
            background_colour = "#666699",
            foreground_colour = "#eeeeee",
        }),

        --  More substyles would follow ...
    })

##
4.3 Miscellaneous settings

### 4.3.1 Frame user attributes

The function `WFrame.set_grattr` may be used to give frames (and their tabs) arbitrary extra attributes to be passed to the drawing engine. Hence, by configuring such substyles in the style configuration files, and turning on the attribute when needed, scripts may display visual cues related to the frame. There is also one extra attribute specially interpreted by the default drawing engine: the ``numbered`' attribute, which causes numbers to be displayed on the tabs.

### 4.3.2 Extra fields for style ``frame`'

The following style fields are independent of the drawing engine used, but are related to objects' styles and therefore configured in the drawing engine configuration file.

Field
`bar`
`frame_tab_width_alg`
`frame_tab_min_w`
`floatframe_tab_min_w`
`frame_propor_tab_min_w`
`floatframe_bar_max_w_q`

### 4.3.3 Extra fields for style ``dock`'

Field
`outline_style`
`tile_size`

Hopefully that's enough to get you started in writing new style configuration files for Notion. When in doubt, study the existing style configuration files.

#
5. Scripting

This chapter documents some additional features of the Notion configuration and scripting interface that can be used for more advanced scripting than the basic configuration explained in chapter 3.

## 5.1 Protected mode and (un-)safe functions

Some of Notion's functions call other functions in so-called ``protected mode''. In particular this is true for all the iterator functions mentioned in 6. If a function `fn` is called in protected mode, the call will only succeed if `fn` is considered ``safe'', and will otherwise fail with the message ``Ignoring call to unsafe function `fn` in restricted mode.''.

Let us try to explain the rationale behind this behavior and the heuristic for deciding when a function can be considered safe through an example. The function `WMPlex.managed_i` iterates over all regions managed by an `mplex` and calls `iterfn` on each of these regions. If `iterfn` was able to alter the list of regions managed by `mplex`, say by adding additional regions, this iteration could easily turn into an infinite loop or lead to inconsistent behavior.

To avoid situations like this, in order to be considered safe, a function must not alter any of the internal data structures of Notion.

If you ever need to use an unsafe function in combination with an iterator, there is a simple workaround. In the example above, instead of writing `WMPlex.managed_i(mplex, iterfn)`, which fails if `iterfn` is unsafe, you can use the following code snippet to achieve the same result:

    managed_regions={}
    mplex:managed_i(function(reg)
        table.insert(managed_regions, reg) return true
    end)
    for _,reg in ipairs(managed_regions) do
        iterfn(reg)
    end

##
5.2 Hooks

Hooks are lists of functions to be called when a certain event occurs. There are two types of them; normal and ``alternative'' hooks. Normal hooks do not return anything, but alt-hooks should return a boolean indicating whether it handled its assigned task successfully. In the case that `true` is returned, remaining handlers are not called.

Hook handlers are registered by first finding the hook with `ioncore.get_hook` and then calling `WHook.add` on the (successful) result with the handler as parameter. Similarly handlers are unregistered with `WHook.remove`. For example:

    ioncore.get_hook("ioncore_snapshot_hook"):add(
        function() print("Snapshot hook called.") end
    )

In this example the hook handler has no parameters, but many hook handlers do. The types of parameters for each hook are listed in the hook reference, section 6.9.

Note that many of the hooks are called in ``protected mode'' and can not use any functions that modify Notion's internal state.

## 5.3 Referring to regions

### 5.3.1 Direct object references

All Notion objects are passed to Lua scripts as 'userdatas', and you may safely store such object references for future use. The C-side object may be destroyed while Lua still refers to the object. All exported functions gracefully fail in such a case, but if you need to explicitly test that the C-side object still exists, use `obj_exists`.

As an example, the following short piece of code implements bookmarking:

    local bookmarks={}

    -- Set bookmark bm point to the region reg
    function set_bookmark(bm, reg)
        bookmarks[bm]=reg
    end

    -- Go to bookmark bm
    function goto_bookmark(bm)
        if bookmarks[bm] then
            -- We could check that bookmarks[bm] still exists, if we
            -- wanted to avoid an error message.
            bookmarks[bm]:goto()
        end
    end

### 5.3.2 Name-based lookups

If you want to a single non-WClientWin region with an exact known name, use `ioncore.lookup_region`. If you want a list of all regions, use `ioncore.region_list`. Both functions accept an optional argument that can be used to specify that the returned region(s) must be of a more specific type. Client windows live in a different namespace and for them you should use the equivalent functions `ioncore.lookup_clientwin` and `ioncore.clientwin_list`.

To get the name of an object, use `WRegion.name`. Please be aware, that the names of client windows reflect their titles and are subject to changes. To change the name of a non-client window region, use `WRegion.set_name`.

## 5.4 Alternative winprop selection criteria

It is possible to write more complex winprop selection routines than those described in section 3.5. To match a particular winprop using whatever way you want to, just set the `match` field of the winprop to a function that receives the as its parameters the triple `(prop, cwin, id)`, where `prop` is the table for the winprop itself, `cwin` is the client window object, and `id` is the `WClientWin.get_ident` result. The function should return `true` if the winprop matches, and `false` otherwise. Note that the `match` function is only called after matching against class/role/instance.

The title of a client window can be obtained with `WRegion.name`. If you want to match against (almost) arbitrary window properties, have a look at the documentation for the following functions, and their standard Xlib counterparts: `ioncore.x_intern_atom` (XInternAtom), `ioncore.x_get_window_property` (XGetWindowProperty), and `ioncore.x_get_text_property` (XGetTextProperty).

##
5.5 Writing `ion-statusd` monitors

All statusbar meters that do not monitor the internal state of Notion should go in the separate `ion-statusd` program.

Whenever the user requests a meter ``%foo`' or ``%foo_bar`' to be inserted in a statusbar, mod_statusbar asks `ion-statusd` to load `statusd_foo.lua` on its search path (same as that for Notion-side scripts). This script should then supply all meters with the initial part ``foo`'.

To provide this value, the script should simply call `statusd.inform` with the name of the meter and the value as a string. Additionally the script should provide a 'template' for the meter to facilitate expected width calculation by mod_statusbar, and may provide a 'hint' for colour-coding the value. The interpretation of hints depends on the graphical style in use, and currently the stock styles support the ``normal`', ``important`' and ``critical`' hints.

In our example of the 'foo monitor', at script initialisation we might broadcast the template as follows:

    statusd.inform("foo_template", "000")

To inform mod_statusbar of the actual value of the meter and indicate that the value is critical if above 100, we might write the following function:

    local function inform_foo(foo)
        statusd.inform("foo", tostring(foo))
        if foo>100 then
            statusd.inform("foo_hint", "critical")
        else
            statusd.inform("foo_hint", "normal")
        end
    end

To periodically update the value of the meter, we must use timers. First we must create one:

    local foo_timer=statusd.create_timer()

Then we write a function to be called whenever the timer expires. This function must also restart the timer.

    local function update_foo()
        local foo= ... measure foo somehow ...
        inform_foo(foo)
        foo_timer:set(settings.update_interval, update_foo)
    end

Finally, at the end of our script we want to do the initial measurement, and set up timer for further measurements:

    update_foo()

If our scripts supports configurable parameters, the following code (at the beginning of the script) will allow them to be configured in cfg_statusbar.lua and passed to the status daemon and our script:

    local defaults={
        update_interval=10*1000, -- 10 seconds
    }

    local settings=table.join(statusd.get_config("foo"), defaults)

#
6. Function reference

##
6.1 Functions defined in ioncore

Synopsis:
  `ioncore.TR(s, ...)`
Description:
  gettext+string.format

Synopsis:
  `ioncore.bdoc(text)`
Description:
  Used to enter documentation among bindings so that other programs can read it. Does nothing.

Synopsis:
  `ioncore.chdir_for(reg, dir)`
Description:
  Change default working directory for new programs started in `reg`.

Synopsis:
  `ioncore.compile_cmd(cmd, guard)`
Description:
  Compile string `cmd` into a bindable function. Within `cmd`, the variable ''`_`'' (underscore) can be used to refer to the object that was selecting for the bound action and chosen to handle it. The variable ''`_sub`'' refers to a ''currently active'' sub-object of `_`, or a sub-object where the action loading to the binding being called actually occured.

  The string `guard` maybe set to pose limits on `_sub`. Currently supported guards are `_sub:non-nil` and `_sub:WFoobar`, where WFoobar is a class.

Synopsis:
  `WTimer ioncore.create_timer()`
Description:
  Create a new timer.

Synopsis:
  `ioncore.create_ws(scr, tmpl, layout)`
Description:
  Create new workspace on screen `scr`. The table `tmpl` may be used to override parts of the layout named with `layout`. If no `layout` is given, "default" is used.

Synopsis:
  `ioncore.defbindings(context, bindings)`
Description:
  Define bindings for context `context`. Here `binding` is a table composed of entries created with `ioncore.kpress`, etc.; see Section 3.3 for details.

Synopsis:
  `ioncore.defctxmenu(ctx, ...)`
Description:
  Define context menu for context `ctx`, `tab` being a table of menu entries.

Synopsis:
  `ioncore.deflayout(name, tab)`
Description:
  Define a new workspace layout with name `name`, and attach/creation parameters given in `tab`. The layout "empty" may not be defined.

Synopsis:
  `ioncore.defmenu(name, tab)`
Description:
  Define a new menu with `name` being the menu's name and `tab` being a table of menu entries. If `tab.append` is set, the entries are appended to previously-defined ones, if possible.

Synopsis:
  `ioncore.defwinprop(list)`
Description:
  Define a winprop. For more information, see section 3.5.

Synopsis:
  `ioncore.exec_on(reg, cmd, merr_internal)`
Description:
  Run `cmd` with the environment variable DISPLAY set to point to the root window of the X screen `reg` is on. If `cmd` is prefixed by a colon (`:`), the following command is executed in an xterm (or other terminal emulator) with the help of the `ion-runinxterm` script. If the command is prefixed by two colons, `ion-runinxterm` will ask you to press enter after the command is finished, even if it returns succesfully.

  For GUI commands, you might prefer to use mod_query.exec_on_merr(), which monitors the process's `stderr` and shows any output as warnings on the screen instead of in notions own output.

Synopsis:
  `table ioncore.read_savefile(string basename)`
Description:
  Read a savefile. This function is considered safe.

Synopsis:
  `string ioncore.get_savefile(string basename)`
Description:
  Get a file name to save (session) data in. The string `basename` should contain no path or extension components. This function is considered safe.

Synopsis:
  `string ioncore.lookup_script(string file, string sp)`
Description:
  Lookup script `file`. If `try_in_dir` is set, it is tried before the standard search path. This function is considered safe.

Synopsis:
  `bool ioncore.write_savefile(string basename, table tab)`
Description:
  Write `tab` in file with basename `basename` in the session directory. This function is considered safe.

Synopsis:
  `ioncore.find_manager(obj, t)`
Description:
  Find an object with type name `t` managing `obj` or one of its managers.

Synopsis:
  `ioncore.get_dir_for(reg)`
Description:
  Get default working directory for new programs started in `reg`.

Synopsis:
  `ioncore.getbindings(maybe_context)`
Description:
  Get a table of all bindings.

Synopsis:
  `ioncore.getctxmenu(name)`
Description:
  Returns a context menu defined with `ioncore.defctxmenu`.

Synopsis:
  `ioncore.getlayout(name, all)`
Description:
  Get named layout (or all of the latter parameter is set, but this is for internal use only).

Synopsis:
  `ioncore.getmenu(name)`
Description:
  Returns a menu defined with `ioncore.defmenu`.

Synopsis:
  `ioncore.getwinprop(cwin)`
Description:
  Find winprop table for `cwin`.

Synopsis:
  `string ioncore.aboutmsg()`
Description:
  Returns an about message (version, author, copyright notice). This function is considered safe.

Synopsis:
  `WRegion ioncore.activity_first()`
Description:
  Returns first region on activity list. This function is considered safe.

Synopsis:
  `bool ioncore.activity_i(function iterfn)`
Description:
  Iterate over activity list until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `bool ioncore.clientwin_i(function fn)`
Description:
  Iterate over client windows until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `WRegion ioncore.current()`
Description:
  Returns the currently focused region, if any.

Synopsis:
  `bool ioncore.defshortening(string rx, string rule, bool always)`
Description:
  Add a rule describing how too long titles should be shortened to fit in tabs. The regular expression `rx` (POSIX, not Lua!) is used to match titles and when `rx` matches, `rule` is attempted to use as a replacement for title. If `always` is set, the rule is used even if no shortening is necessary.

  Similarly to sed's 's' command, `rule` may contain characters that are inserted in the resulting string and specials as follows:

  Special
  $0
  $1 to $9
  $|
  $<
  $>

Synopsis:
  `bool ioncore.detach(WRegion reg, string how)`
Description:
  Detach or reattach `reg` or any group it is the leader of (see `WRegion.groupleader_of`), depending on whether `how` is ``set`', ``unset`' or ``toggle`'. If this region is not a window, it is put into a frame.

  Detaching a region means having it managed by its nearest ancestor WGroup. Reattaching means having it managed where it used to be managed, if a ``return placeholder'' exists.

  Additionally, setting `how` to ``forget`', can be used to clear this return placeholder of the group leader of `reg`.

Synopsis:
  `integer ioncore.exec(string cmd)`
Description:
  Run `cmd` with the environment variable DISPLAY set to point to the X display the WM is running on. No specific screen is set unlike with `WRootWin.exec_on`. The PID of the (shell executing the) new process is returned. This function is considered safe.

Synopsis:
  `WScreen ioncore.find_screen_id(integer id)`
Description:
  Find the screen with numerical id `id`. This function is considered safe.

Synopsis:
  `bool ioncore.focushistory_i(function iterfn)`
Description:
  Iterate over focus history until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening.

Synopsis:
  `table ioncore.get()`
Description:
  Get ioncore basic settings. For details see `ioncore.set`. This function is considered safe.

Synopsis:
  `table ioncore.get_paths(table tab)`
Description:
  Get important directories (the fields `userdir`, `sessiondir`, `searchpath` in the returned table). This function is considered safe.

Synopsis:
  `bool ioncore.goto_activity()`
Description:
  Go to first region on activity list.

Synopsis:
  `WRegion ioncore.goto_first(WRegion reg, string dirstr, table param)`
Description:
  Go to first region within `reg` in direction `dirstr`. For information on `param`, see `ioncore.navi_next`. Additionally this function supports the boolean `nofront` field, for not bringing the object to front.

Synopsis:
  `WRegion ioncore.goto_next(WRegion reg, string dirstr, table param)`
Description:
  Go to region next from `reg` in direction `dirstr`. For information on `param`, see `ioncore.navi_next`. Additionally this function supports the boolean `nofront` field, for not bringing the object to front.

Synopsis:
  `WScreen ioncore.goto_next_screen()`
Description:
  Switch focus to the next screen and return it.

  Note that this function is asynchronous; the screen will not actually have received the focus when this function returns.

Synopsis:
  `WScreen ioncore.goto_nth_screen(integer id)`
Description:
  Switch focus to the screen with id `id` and return it.

  Note that this function is asynchronous; the screen will not actually have received the focus when this function returns.

Synopsis:
  `WScreen ioncore.goto_prev_screen()`
Description:
  Switch focus to the previous screen and return it.

  Note that this function is asynchronous; the screen will not actually have received the focus when this function returns.

Synopsis:
  `WRegion ioncore.goto_previous()`
Description:
  Go to and return to a previously active region (if any).

  Note that this function is asynchronous; the region will not actually have received the focus when this function returns.

Synopsis:
  `bool ioncore.is_i18n()`
Description:
  Is Notion supporting locale-specifically multibyte-encoded strings? This function is considered safe.

Synopsis:
  `bool ioncore.load_module(string modname)`
Description:
  Attempt to load a C-side module.

Synopsis:
  `WClientWin ioncore.lookup_clientwin(string name)`
Description:
  Attempt to find a client window with name `name`. This function is considered safe.

Synopsis:
  `WRegion ioncore.lookup_region(string name, string typenam)`
Description:
  Attempt to find a non-client window region with name `name` and type inheriting `typenam`. This function is considered safe.

Synopsis:
  `WRegion ioncore.navi_first(WRegion reg, string dirstr, table param)`
Description:
  Find first region within `reg` in direction `dirstr`. For information on `param`, see `ioncore.navi_next`.

Synopsis:
  `WRegion ioncore.navi_next(WRegion reg, string dirstr, table param)`
Description:
  Find region next from `reg` in direction `dirstr` (``up`', ``down`', ``left`', ``right`', ``next`', ``prev`', or ``any`'). The table `param` may contain the boolean field `nowrap`, instructing not to wrap around, and the WRegions `no_ascend` and `no_descend`, and boolean functions `ascend_filter` and `descend_filter` on `WRegion` pairs (`to`, `from`), are used to decide when to descend or ascend into another region.

Synopsis:
  `integer ioncore.popen_bgread(string cmd, function h, function errh, string wd)`
Description:
  Run `cmd` in directory `wd` with a read pipe connected to its stdout and stderr. When data is received through one of these pipes, `h` or `errh` is called with that data. When the pipe is closed, the handler is called with `nil` argument. The PID of the new process is returned, or -1 on error. This function is considered safe.

Synopsis:
  `void ioncore.profiling_start(string filename)`
Description:
  Start profiling (if enabled at compile-time) This function is considered safe.

Synopsis:
  `void ioncore.profiling_stop()`
Description:
  Stop profiling (if enabled at compile-time) This function is considered safe.

Synopsis:
  `string ioncore.progname()`
Description:
  Returns the name of program using Ioncore. This function is considered safe.

Synopsis:
  `bool ioncore.region_i(function fn, string typenam)`
Description:
  Iterate over all non-client window regions with (inherited) class `typenam` until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `void ioncore.request_selection(function fn)`
Description:
  Request (string) selection. The function `fn` will be called with the selection when and if it is received.

Synopsis:
  `void ioncore.resign()`
Description:
  Causes the window manager to simply exit without saving state/session.

Synopsis:
  `void ioncore.restart()`
Description:
  Restart, saving session first.

Synopsis:
  `void ioncore.restart_other(string cmd)`
Description:
  Attempt to restart another window manager `cmd`.

Synopsis:
  `WRootWin ioncore.rootwin()`
Description:
  Returns the first WRootWin This function is considered safe.

Synopsis:
  `void ioncore.screens_updated(WRootWin rw)`
Description:
  refresh _NET_WM_VIRTUAL_ROOTS This function is considered safe.

Synopsis:
  `void ioncore.set(table tab)`
Description:
  Set ioncore basic settings. The table `tab` may contain the following fields.

  Field
  `opaque_resize`
  `warp`
  `switchto`
  `screen_notify`
  `frame_default_index`
  `dblclick_delay`
  `kbresize_delay`
  `kbresize_t_max`
  `kbresize_t_min`
  `kbresize_step`
  `kbresize_maxacc`
  `edge_resistance`
  `framed_transients`
  `float_placement_method`
  `float_placement_padding`
  `mousefocus`
  `unsqueeze`
  `autoraise`
  `usertime_diff_current`
  `usertime_diff_new`
  `autosave_layout`
  `window_stacking_request`
  `focuslist_insert_delay`
  `activity_notification_on_all_screens`
  `workspace_indicator_timeout`

  When a keyboard resize function is called, and at most `kbresize_t_max` milliseconds has passed from a previous call, acceleration factor is reset to 1.0. Otherwise, if at least `kbresize_t_min` milliseconds have passed from the from previous acceleration update or reset the squere root of the acceleration factor is incremented by `kbresize_step`. The maximum acceleration factor (pixels/call modulo size hints) is given by `kbresize_maxacc`. The default values are (200, 50, 30, 100).

Synopsis:
  `bool ioncore.set_paths(table tab)`
Description:
  Set important directories (the fields `sessiondir`, `searchpath` of `tab`).

Synopsis:
  `void ioncore.set_selection(string p)`
Description:
  Set primary selection and cutbuffer0 to `p`.

Synopsis:
  `void ioncore.shutdown()`
Description:
  End session saving it first.

Synopsis:
  `void ioncore.snapshot()`
Description:
  Save session.

Synopsis:
  `void ioncore.tagged_clear()`
Description:
  Untag all regions.

Synopsis:
  `WRegion ioncore.tagged_first(bool untag)`
Description:
  Returns first tagged object, untagging it as well if `untag` is set. This function is considered safe.

Synopsis:
  `bool ioncore.tagged_i(function iterfn)`
Description:
  Iterate over tagged regions until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `void ioncore.unsqueeze(WRegion reg, bool override)`
Description:
  Try to detach `reg` if it fits poorly in its current location. This function does not do anything, unless `override` is set or the `unsqueeze` option of `ioncore.set` is set.

Synopsis:
  `void ioncore.update_net_state(WClientWin cwin)`
Description:
  refresh _NET_WM_STATE markers for this window This function is considered safe.

Synopsis:
  `string ioncore.version()`
Description:
  Returns Ioncore version string. This function is considered safe.

Synopsis:
  `void ioncore.warn(string str)`
Description:
  Issue a warning. How the message is displayed depends on the current warning handler. This function is considered safe.

Synopsis:
  `void ioncore.warn_traced(string str)`
Description:
  Similar to `ioncore.warn`, but also print Lua stack trace. This function is considered safe.

Synopsis:
  `void ioncore.x_change_property(integer win, integer atom, integer atom_type, integer format, string mode, table tab)`
Description:
  Modify a window property. The `mode` is one of ``replace`', ``prepend`' or ``append`', and format is either 8, 16 or 32. Also see `ioncore.x_get_window_property` and the `XChangeProperty`(3) manual page.

Synopsis:
  `void ioncore.x_delete_property(integer win, integer atom)`
Description:
  Delete a window property.

Synopsis:
  `string ioncore.x_get_atom_name(integer atom)`
Description:
  Get the name of an atom. See `XGetAtomName`(3) manual page for details.

Synopsis:
  `table ioncore.x_get_text_property(integer win, integer atom)`
Description:
  Get a text property for a window. The fields in the returned table (starting from 1) are the null-separated parts of the property. See the `XGetTextProperty`(3) manual page for more information. This function is considered safe.

Synopsis:
  `table ioncore.x_get_window_property(integer win, integer atom, integer atom_type, integer n32expected, bool more)`
Description:
  Get a property `atom` of type `atom_type` for window `win`. The `n32expected` parameter indicates the expected number of 32bit words, and `more` indicates whether all or just this amount of data should be fetched. Each 8, 16 or 32bit element of the property, as deciphered from `atom_type` is a field in the returned table. See `XGetWindowProperty`(3) manual page for more information. This function is considered safe.

Synopsis:
  `integer ioncore.x_intern_atom(string name, bool only_if_exists)`
Description:
  Create a new atom. See `XInternAtom`(3) manual page for details.

Synopsis:
  `void ioncore.x_set_text_property(integer win, integer atom, table tab)`
Description:
  Set a text property for a window. The fields of `tab` starting from 1 should be the different null-separated parts of the property. See the `XSetTextProperty`(3) manual page for more information.

Synopsis:
  `void ioncore.x_set_utf8_property(integer win, integer atom, table tab)`
Description:
  Set a `UTF8_STRING` property for a window. The fields of `tab` starting from 1 should be the different null-separated parts of the property. See the `XSetTextProperty`(3) manual page for more information.

Synopsis:
  `ioncore.kpress(keyspec, cmd, guard)`
Description:
  Creates a binding description table for the action of pressing a key given by `keyspec` (with possible modifiers) to the function `cmd`. The `guard` controls when the binding can be called. For more informationp see Section 3.3.

Synopsis:
  `ioncore.kpress_wait(keyspec, cmd, guard)`
Description:
  This is similar to `ioncore.kpress` but after calling `cmd`, Ioncore waits for all modifiers to be released before processing any further actions. For more information on bindings, see Section 3.3.

Synopsis:
  `bool ioncore.defer(function fn)`
Description:
  Defer execution of `fn` until the main loop. This function is considered safe.

Synopsis:
  `WHook ioncore.get_hook(string name)`
Description:
  Find named hook `name`. This function is considered safe.

Synopsis:
  `ioncore.match_winprop_dflt(prop, cwin, id)`
Description:
  The basic name-based winprop matching criteria.

Synopsis:
  `ioncore.mclick(buttonspec, cmd, guard)`
Description:
  Creates a binding description table for the action of clicking a mouse button while possible modifier keys are pressed, both given by `buttonspec`, to the function `cmd`. For more information, see Section 3.3.

Synopsis:
  `ioncore.mdblclick(buttonspec, cmd, guard)`
Description:
  Similar to `ioncore.mclick` but for double-click. Also see Section 3.3.

Synopsis:
  `ioncore.mdrag(buttonspec, cmd, guard)`
Description:
  Creates a binding description table for the action of moving the mouse (or other pointing device) while the button given by `buttonspec` is held pressed and the modifiers given by `buttonspec` were pressed when the button was initially pressed. Also see section 3.3.

Synopsis:
  `ioncore.menuentry(name, cmd, guard_or_opts)`
Description:
  Use this function to define normal menu entries. The string `name` is the string shown in the visual representation of menu. The parameter `cmd` and `guard_or_opts` (when string) are similar to those of `ioncore.defbindings`. If `guard_or_opts` is a table, it may contains the `guard` field, and the `priority` field, for controlling positioning of entries in context menus. (The default priority is 1 for most entries, and -1 for auto-generated submenus.)

Synopsis:
  `ioncore.mpress(buttonspec, cmd, guard)`
Description:
  Similar to `ioncore.mclick` but for just pressing the mouse button. Also see Section 3.3.

Synopsis:
  `ioncore.refresh_stylelist()`
Description:
  Refresh list of known style files.

Synopsis:
  `ioncore.submap(keyspec, list)`
Description:
  Returns a function that creates a submap binding description table. When the key press action `keyspec` occurs, Ioncore will wait for a further key presse and act according to the submap. For details, see Section 3.3.

Synopsis:
  `ioncore.submap_enter(cmd, guard)`
Description:
  Submap enter event for bindings.

Synopsis:
  `ioncore.submap_wait(cmd, guard)`
Description:
  Submap modifier release event for bindings.

Synopsis:
  `ioncore.submenu(name, sub_or_name, options)`
Description:
  Use this function to define menu entries for submenus. The parameter `sub_or_name` is either a table of menu entries or the name of an already defined menu. The initial menu entry to highlight can be specified by `options.initial` as either an integer starting from 1, or a function that returns such a number. Another option supported is `options.noautoexpand` that will cause `mod_query.query_menu` to not automatically expand this submenu.

Synopsis:
  `ioncore.tabnum.clear()`
Description:
  Clear all tab numbers set by `ioncore.tabnum.show`.

Synopsis:
  `ioncore.tabnum.show(frame, delay)`
Description:
  Show tab numbers on `frame`, clearing them when submap grab is released the next time. If `delay` is given, in milliseconds, the numbers are not actually displayed until this time has passed.

Synopsis:
  `ioncore.tagged_attach(reg, param)`
Description:
  Attach tagged regions to `reg`. The method of attach depends on the types of attached regions and whether `reg` implements `attach_framed` and `attach`. If `param` is not set, the default of `{switchto=true}` is used. The function returns `true` if all tagged regions were succesfully attached, and `false` otherwisse.

### 6.1.1 WClientWin functions

Synopsis:
  `table WClientWin.get_ident(WClientWin cwin)`
Description:
  Returns a table containing the properties `WM_CLASS` (table entries `instance` and `class`) and `WM_WINDOW_ROLE` (`role`) properties for `cwin`. If a property is not set, the corresponding field(s) are unset in the table. This function is considered safe.

Synopsis:
  `void WClientWin.kill(WClientWin cwin)`
Description:
  Attempt to kill (with `XKillWindow`) the client that owns the X window correspoding to `cwin`.

Synopsis:
  `void WClientWin.nudge(WClientWin cwin)`
Description:
  Attempts to fix window size problems with non-ICCCM compliant programs.

Synopsis:
  `void WClientWin.quote_next(WClientWin cwin)`
Description:
  Send next key press directly to `cwin`.

Synopsis:
  `double WClientWin.xid(WClientWin cwin)`
Description:
  Return the X window id for the client window. This function is considered safe.

### 6.1.2 WFrame functions

Synopsis:
  `bool WFrame.is_grattr(WFrame frame, string attr)`
Description:
  Is the attribute `attr` set on `frame`? This function is considered safe.

Synopsis:
  `bool WFrame.is_shaded(WFrame frame)`
Description:
  Is `frame` shaded? This function is considered safe.

Synopsis:
  `void WFrame.maximize_horiz(WFrame frame)`
Description:
  Attempt to toggle horizontal maximisation of `frame`.

Synopsis:
  `void WFrame.maximize_vert(WFrame frame)`
Description:
  Attempt to toggle vertical maximisation of `frame`.

Synopsis:
  `string WFrame.mode(WFrame frame)`
Description:
  Get frame mode. This function is considered safe.

Synopsis:
  `void WFrame.p_switch_tab(WFrame frame)`
Description:
  Display the region corresponding to the tab that the user pressed on. This function should only be used by binding it to a mouse action.

Synopsis:
  `void WFrame.p_tabdrag(WFrame frame)`
Description:
  Start dragging the tab that the user pressed on with the pointing device. This function should only be used by binding it to mpress or mdrag action with area ``tab`'.

Synopsis:
  `bool WFrame.set_grattr(WFrame frame, string attr, string how)`
Description:
  Set extra drawing engine attributes for the frame. The parameter `attr` is the attribute, and `how` is one of ``set`', ``unset`', or ``toggle`'.

Synopsis:
  `bool WFrame.set_mode(WFrame frame, string modestr)`
Description:
  Set frame mode (one of ``unknown`', ``tiled`', ``floating`', ``transient`', or any of these suffixed with ``-alt`').

Synopsis:
  `bool WFrame.set_shaded(WFrame frame, string how)`
Description:
  Set shading state according to the parameter `how` (``set`', ``unset`', or ``toggle`'). Resulting state is returned, which may not be what was requested.

### 6.1.3 WGroup functions

Synopsis:
  `WRegion WGroup.attach(WGroup ws, WRegion reg, table param)`
Description:
  Attach and reparent existing region `reg` to `ws`. The table `param` may contain the fields `index` and `switchto` that are interpreted as for `WMPlex.attach_new`.

Synopsis:
  `WRegion WGroup.attach_new(WGroup ws, table param)`
Description:
  Create a new region to be managed by `ws`. At least the following fields in `param` are understood:

  Field
  `type`
  `name`
  `switchto`
  `level`
  `modal`
  `sizepolicy`
  `bottom`

  In addition parameters to the region to be created are passed in this same table.

Synopsis:
  `WRegion WGroup.bottom(WGroup ws)`
Description:
  Returns the `bottom' of `ws`. This function is considered safe.

Synopsis:
  `bool WGroup.managed_i(WGroup ws, function iterfn)`
Description:
  Iterate over managed regions of `ws` until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `bool WGroup.set_bottom(WGroup ws, WRegion reg)`
Description:
  Sets the `bottom' of `ws`. The region `reg` must already be managed by `ws`, unless `nil`.

Synopsis:
  `bool WGroup.set_fullscreen(WGroup grp, string how)`
Description:
  Set client window `reg` full screen state according to the parameter `how` (one of ``set`', ``unset`', or ``toggle`'). Resulting state is returned, which may not be what was requested.

### 6.1.4 WGroupCW functions

### 6.1.5 WGroupWS functions

Synopsis:
  `bool WGroupWS.attach_framed(WGroupWS ws, WRegion reg, table t)`
Description:
  Attach region `reg` on `ws`. At least the following fields in `t` are supported:

  Field
  `switchto`
  `geom`

### 6.1.6 WHook functions

Synopsis:
  `bool WHook.add(WHook hk, function efn)`
Description:
  Add `efn` to the list of functions to be called when the hook `hk` is triggered.

Synopsis:
  `bool WHook.listed(WHook hk, function efn)`
Description:
  Is `fn` hooked to hook `hk`? This function is considered safe.

Synopsis:
  `bool WHook.remove(WHook hk, function efn)`
Description:
  Remove `efn` from the list of functions to be called when the hook `hk` is triggered.

### 6.1.7 WInfoWin functions

Synopsis:
  `void WInfoWin.set_text(WInfoWin p, string str, integer maxw)`
Description:
  Set contents of the info window.

### 6.1.8 WMPlex functions

Synopsis:
  `WRegion WMPlex.attach(WMPlex mplex, WRegion reg, table param)`
Description:
  Attach and reparent existing region `reg` to `mplex`. The table `param` may contain the fields `index` and `switchto` that are interpreted as for `WMPlex.attach_new`.

Synopsis:
  `WRegion WMPlex.attach_new(WMPlex mplex, table param)`
Description:
  Create a new region to be managed by `mplex`. At least the following fields in `param` are understood (all but `type` are optional).

  Field
  `type`
  `name`
  `switchto`
  `unnumbered`
  `index`
  `level`
  `modal`
  `hidden`
  `passive`
  `pseudomodal`
  `sizepolicy`
  `geom`

  In addition parameters to the region to be created are passed in this same table.

Synopsis:
  `void WMPlex.dec_index(WMPlex mplex, WRegion r)`
Description:
  Move `r` ``left'' within objects managed by `mplex` on list 1.

Synopsis:
  `integer WMPlex.get_index(WMPlex mplex, WRegion reg)`
Description:
  Get index of `reg` on the mutually exclusive list of `mplex`. The indices begin from zero.. If `reg` is not on the list, -1 is returned. This function is considered safe.

Synopsis:
  `table WMPlex.get_stdisp(WMPlex mplex)`
Description:
  Get status display information. See `WMPlex.get_stdisp` for information on the fields. This function is considered safe.

Synopsis:
  `void WMPlex.inc_index(WMPlex mplex, WRegion r)`
Description:
  Move `r` ``right'' within objects managed by `mplex` on list 1.

Synopsis:
  `bool WMPlex.is_hidden(WMPlex mplex, WRegion reg)`
Description:
  Is `reg` on within `mplex` and hidden? This function is considered safe.

Synopsis:
  `bool WMPlex.managed_i(WMPlex mplex, function iterfn)`
Description:
  Iterate over managed regions of `mplex` until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `integer WMPlex.mx_count(WMPlex mplex)`
Description:
  Returns the number of objects on the mutually exclusive list of `mplex`. This function is considered safe.

Synopsis:
  `WRegion WMPlex.mx_current(WMPlex mplex)`
Description:
  Returns the managed object currently active within the mutually exclusive list of `mplex`. This function is considered safe.

Synopsis:
  `bool WMPlex.mx_i(WMPlex mplex, function iterfn)`
Description:
  Iterate over numbered/mutually exclusive region list of `mplex` until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `WRegion WMPlex.mx_nth(WMPlex mplex, integer n)`
Description:
  Returns the `n`:th object on the mutually exclusive list of `mplex`. This function is considered safe.

Synopsis:
  `bool WMPlex.set_hidden(WMPlex mplex, WRegion reg, string how)`
Description:
  Set the visibility of the region `reg` on `mplex` as specified with the parameter `how` (one of ``set`', ``unset`', or ``toggle`'). The resulting state is returned.

Synopsis:
  `void WMPlex.set_index(WMPlex mplex, WRegion reg, integer index)`
Description:
  Set index of `reg` to `index` within the mutually exclusive list of `mplex`. Special values for `index` are:

  -1 mathend000#
  -2 mathend000#

Synopsis:
  `WRegion WMPlex.set_stdisp(WMPlex mplex, table t)`
Description:
  Set/create status display for `mplex`. Table is a standard description of the object to be created (as passed to e.g. `WMPlex.attach_new`). In addition, the following fields are recognised:

  Field
  `pos`
  `fullsize`
  `action`

Synopsis:
  `void WMPlex.switch_next(WMPlex mplex)`
Description:
  Have `mplex` display next (wrt. currently selected) object managed by it.

Synopsis:
  `void WMPlex.switch_nth(WMPlex mplex, integer n)`
Description:
  Have `mplex` display the `n`:th object managed by it.

Synopsis:
  `void WMPlex.switch_prev(WMPlex mplex)`
Description:
  Have `mplex` display previous (wrt. currently selected) object managed by it.

Synopsis:
  `void WMPlex.switch_to(WMPlex mplex, WRegion reg)`
Description:
  Have `mplex` display the given child window already added to the mplex

### 6.1.9 WMoveresMode functions

Synopsis:
  `void WMoveresMode.cancel(WMoveresMode mode)`
Description:
  Return from move/resize cancelling changes if opaque move/resize has not been enabled.

Synopsis:
  `void WMoveresMode.finish(WMoveresMode mode)`
Description:
  Return from move/resize mode and apply changes unless opaque move/resize is enabled.

Synopsis:
  `table WMoveresMode.geom(WMoveresMode mode)`
Description:
  Returns current geometry.

Synopsis:
  `void WMoveresMode.move(WMoveresMode mode, integer horizmul, integer vertmul)`
Description:
  Move resize mode target one step:

  `horizmul`/`vertmul` | effect
  -1 | Move left/up
  0 | No effect
  1 | Move right/down

Synopsis:
  `void WMoveresMode.resize(WMoveresMode mode, integer left, integer right, integer top, integer bottom)`
Description:
  Shrink or grow resize mode target one step in each direction. Acceptable values for the parameters `left`, `right`, `top` and `bottom` are as follows: -1: shrink along, 0: do not change, 1: grow along corresponding border.

Synopsis:
  `table WMoveresMode.rqgeom(WMoveresMode mode, table g)`
Description:
  Request exact geometry in move/resize mode. For details on parameters, see `WRegion.rqgeom`.

### 6.1.10 WRegion functions

Synopsis:
  `WMoveresMode WRegion.begin_kbresize(WRegion reg)`
Description:
  Enter move/resize mode for `reg`. The bindings set with `ioncore.set_bindings` for WMoveresMode are used in this mode. Of the functions exported by the Ion C core, only `WMoveresMode.resize`, `WMoveresMode.move`, `WMoveresMode.cancel` and `WMoveresMode.end` are allowed to be called while in this mode.

Synopsis:
  `WRegion WRegion.current(WRegion mgr)`
Description:
  Return the object, if any, that is considered ``currently active'' within the objects managed by `mplex`. This function is considered safe.

Synopsis:
  `table WRegion.geom(WRegion reg)`
Description:
  Returns the geometry of `reg` within its parent; a table with fields `x`, `y`, `w` and `h`. This function is considered safe.

Synopsis:
  `table WRegion.get_configuration(WRegion reg, bool clientwins)`
Description:
  Get configuration tree. If `clientwins` is unset, client windows are filtered out.

Synopsis:
  `bool WRegion.goto(WRegion reg)`
Description:
  Deprecated in favour of `WRegion.goto_focus` because 'goto' is a keyword since Lua 5.2.

Synopsis:
  `bool WRegion.goto_focus(WRegion reg)`
Description:
  Attempt to display `reg`, save region activity status and then warp to (or simply set focus to if warping is disabled) `reg`.

  Note that this function is asynchronous; the region will not actually have received the focus when this function returns.

Synopsis:
  `WRegion WRegion.groupleader_of(WRegion reg)`
Description:
  Returns the group of `reg`, if `reg` is its bottom, and `reg` itself otherwise.

Synopsis:
  `bool WRegion.is_active(WRegion reg, bool pseudoact_ok)`
Description:
  Is `reg` active/does it or one of it's children of focus? This function is considered safe.

Synopsis:
  `bool WRegion.is_activity(WRegion reg)`
Description:
  Is activity notification set on `reg`. This function is considered safe.

Synopsis:
  `bool WRegion.is_mapped(WRegion reg)`
Description:
  Is `reg` visible/is it and all it's ancestors mapped? This function is considered safe.

Synopsis:
  `bool WRegion.is_tagged(WRegion reg)`
Description:
  Is `reg` tagged? This function is considered safe.

Synopsis:
  `WRegion WRegion.manager(WRegion reg)`
Description:
  Returns the region that manages `reg`. This function is considered safe.

Synopsis:
  `string WRegion.name(WRegion reg)`
Description:
  Returns the name for `reg`. This function is considered safe.

Synopsis:
  `WWindow WRegion.parent(WRegion reg)`
Description:
  Returns the parent region of `reg`. This function is considered safe.

Synopsis:
  `WRootWin WRegion.rootwin_of(WRegion reg)`
Description:
  Returns the root window `reg` is on. This function is considered safe.

Synopsis:
  `void WRegion.rqclose(WRegion reg, bool relocate)`
Description:
  Attempt to close/destroy `reg`. Whether this operation works depends on whether the particular type of region in question has implemented the feature and, in case of client windows, whether the client supports the `WM_DELETE` protocol (see also `WClientWin.kill`). The region will not be destroyed when this function returns. To find out if and when it is destroyed, use the ``deinit`' notification. If `relocate` is not set, and `reg` manages other regions, it will not be closed. Otherwise the managed regions will be attempted to be relocated.

Synopsis:
  `WRegion WRegion.rqclose_propagate(WRegion reg, WRegion maybe_sub)`
Description:
  Recursively attempt to close a region or one of the regions managed by it. If `sub` is set, it will be used as the managed region, otherwise `WRegion.current``(reg)`. The object to be closed is returned, or NULL if nothing can be closed. For further details, see notes for `WRegion.rqclose`.

Synopsis:
  `table WRegion.rqgeom(WRegion reg, table g)`
Description:
  Attempt to resize and/or move `reg`. The table `g` is a usual geometry specification (fields `x`, `y`, `w` and `h`), but may contain missing fields, in which case, `reg`'s manager may attempt to leave that attribute unchanged.

Synopsis:
  `bool WRegion.rqorder(WRegion reg, string ord)`
Description:
  Request ordering. Currently supported values for `ord` are ``front`' and ``back`'.

Synopsis:
  `WScreen WRegion.screen_of(WRegion reg)`
Description:
  Returns the screen `reg` is on. This function is considered safe.

Synopsis:
  `bool WRegion.set_activity(WRegion reg, string how)`
Description:
  Set activity flag of `reg`. The `how` parameter must be one of ``set`', ``unset`' or ``toggle`'.

Synopsis:
  `bool WRegion.set_name(WRegion reg, string p)`
Description:
  Set the name of `reg` to `p`. If the name is already in use, an instance number suffix ``<n>`' will be attempted. If `p` has such a suffix, it will be modified, otherwise such a suffix will be added. Setting `p` to nil will cause current name to be removed.

Synopsis:
  `bool WRegion.set_name_exact(WRegion reg, string p)`
Description:
  Similar to `WRegion.set_name` except if the name is already in use, other instance numbers will not be attempted. The string `p` should not contain a ``<n>`' suffix or this function will fail.

Synopsis:
  `bool WRegion.set_tagged(WRegion reg, string how)`
Description:
  Change tagging state of `reg` as defined by `how` (one of ``set`', ``unset`', or ``toggle`'). The resulting state is returned.

Synopsis:
  `table WRegion.size_hints(WRegion reg)`
Description:
  Returns size hints for `reg`. The returned table always contains the fields `min_?`, `base_?` and sometimes the fields `max_?`, `base_?` and `inc_?`, where `?`=`w`, `h`. This function is considered safe.

### 6.1.11 WRootWin functions

Synopsis:
  `WScreen WRootWin.current_scr(WRootWin rootwin)`
Description:
  Returns previously active screen on root window `rootwin`. This function is considered safe.

Synopsis:
  `void WRootWin.warp_pointer(WRootWin root, integer x, integer y)`
Description:
  Warp the cursor pointer to this location

  I'm not *entirely* sure what 'safe' means, but this doesn't change internal notion state, so I guess it's 'safe'... This function is considered safe.

### 6.1.12 WScreen functions

Synopsis:
  `integer WScreen.id(WScreen scr)`
Description:
  Return the numerical id for screen `scr`. This function is considered safe.

Synopsis:
  `bool WScreen.set_managed_offset(WScreen scr, table offset)`
Description:
  Set offset of objects managed by the screen from actual screen geometry. The table `offset` should contain the entries `x`, `y`, `w` and `h` indicating offsets of that component of screen geometry.

### 6.1.13 WTimer functions

Synopsis:
  `bool WTimer.is_set(WTimer timer)`
Description:
  Is timer set?

Synopsis:
  `void WTimer.reset(WTimer timer)`
Description:
  Reset timer.

Synopsis:
  `void WTimer.set(WTimer timer, integer msecs, function fn)`
Description:
  Set `timer` to call `fn` in `msecs` milliseconds.

### 6.1.14 WWindow functions

Synopsis:
  `void WWindow.p_move(WWindow wwin)`
Description:
  Start moving `wwin` with the mouse or other pointing device. This function should only be used by binding it to mpress or mdrag action.

Synopsis:
  `void WWindow.p_resize(WWindow wwin)`
Description:
  Start resizing `wwin` with the mouse or other pointing device. This function should only be used by binding it to mpress or mdrag action.

Synopsis:
  `double WWindow.xid(WWindow wwin)`
Description:
  Return the X window id for `wwin`. This function is considered safe.

### 6.1.15 global functions

Synopsis:
  `export(lib, ...)`
Description:
  Export a list of functions from `lib` into global namespace.

### 6.1.16 gr functions

Synopsis:
  `void gr.read_config()`
Description:
  Read drawing engine configuration file look.lua.

Synopsis:
  `void gr.refresh()`
Description:
  Refresh objects' brushes to update them to use newly loaded style.

Synopsis:
  `bool gr.select_engine(string engine)`
Description:
  Future requests for ``brushes'' are to be forwarded to the drawing engine `engine`. If no engine of such name is known, a module with that name is attempted to be loaded. This function is only intended to be called from colour scheme etc. configuration files and can not be used to change the look of existing objects; for that use `gr.read_config`.

### 6.1.17 string functions

Synopsis:
  `string.shell_safe(str)`
Description:
  Make `str` shell-safe.

### 6.1.18 table functions

Synopsis:
  `table.append(t1, t2)`
Description:
  Add entries that do not exist in `t1` from `t2` to `t1`.

Synopsis:
  `table.copy(t, deep)`
Description:
  Make copy of `table`. If `deep` is unset, shallow one-level copy is made, otherwise a deep copy is made.

Synopsis:
  `table.icat(t1, t2)`
Description:
  Insert all positive integer entries from t2 into t1.

Synopsis:
  `table.join(t1, t2)`
Description:
  Create a table containing all entries from `t1` and those from `t2` that are missing from `t1`.

Synopsis:
  `table.map(f, t)`
Description:
  Map all entries of `t` by `f`.

##
6.2 Functions defined in mod_tiling

Synopsis:
  `table mod_tiling.get()`
Description:
  Get parameters. For details see `mod_tiling.set`. This function is considered safe.

Synopsis:
  `bool mod_tiling.mkbottom(WRegion reg)`
Description:
  Create a new WTiling 'bottom' for the group of `reg`, consisting of `reg`.

Synopsis:
  `void mod_tiling.set(table tab)`
Description:
  Set parameters. Currently only `raise_delay` (in milliseconds) is supported.

Synopsis:
  `bool mod_tiling.untile(WTiling tiling)`
Description:
  If `tiling` is managed by some group, float the frames in the tiling in that group, and dispose of `tiling`.

### 6.2.1 WSplit functions

Synopsis:
  `table WSplit.geom(WSplit split)`
Description:
  Returns the area of workspace used by the regions under `split`. This function is considered safe.

Synopsis:
  `WSplitInner WSplit.parent(WSplit split)`
Description:
  Return parent split for `split`. This function is considered safe.

Synopsis:
  `table WSplit.rqgeom(WSplit node, table g)`
Description:
  Attempt to resize and/or move the split tree starting at `node`. Behaviour and the `g` parameter are as for `WRegion.rqgeom` operating on `node` (if it were a WRegion).

Synopsis:
  `void WSplit.transpose(WSplit node)`
Description:
  Transpose contents of `node`.

### 6.2.2 WSplitInner functions

Synopsis:
  `WSplit WSplitInner.current(WSplitInner node)`
Description:
  Returns the most previously active child node of `split`. This function is considered safe.

### 6.2.3 WSplitRegion functions

Synopsis:
  `WRegion WSplitRegion.reg(WSplitRegion node)`
Description:
  Returns the region contained in `node`. This function is considered safe.

### 6.2.4 WSplitSplit functions

Synopsis:
  `WSplit WSplitSplit.br(WSplitSplit split)`
Description:
  Returns the bottom or right child node of `split` depending on the direction of the split. This function is considered safe.

Synopsis:
  `string WSplitSplit.dir(WSplitSplit split)`
Description:
  Returns the direction of `split`; either ``vertical`' or ``horizontal`'. This function is considered safe.

Synopsis:
  `void WSplitSplit.flip(WSplitSplit split)`
Description:
  Flip contents of `split`.

Synopsis:
  `WSplit WSplitSplit.tl(WSplitSplit split)`
Description:
  Returns the top or left child node of `split` depending on the direction of the split. This function is considered safe.

### 6.2.5 WTiling functions

Synopsis:
  `bool WTiling.flip_at(WTiling ws, WRegion reg)`
Description:
  Flip `ws` at `reg` or root if nil.

Synopsis:
  `bool WTiling.transpose_at(WTiling ws, WRegion reg)`
Description:
  Transpose `ws` at `reg` or root if nil.

Synopsis:
  `WRegion WTiling.farthest(WTiling ws, string dirstr, bool any)`
Description:
  Return the most previously active region on `ws` with no other regions next to it in direction `dirstr` (``left`', ``right`', ``up`', or ``down`'). If `any` is not set, the status display is not considered. This function is considered safe.

Synopsis:
  `bool WTiling.managed_i(WTiling ws, function iterfn)`
Description:
  Iterate over managed regions of `ws` until `iterfn` returns `false`. The function is called in protected mode. This routine returns `true` if it reaches the end of list without this happening. This function is considered safe.

Synopsis:
  `WRegion WTiling.nextto(WTiling ws, WRegion reg, string dirstr, bool any)`
Description:
  Return the most previously active region next to `reg` in direction `dirstr` (``left`', ``right`', ``up`', or ``down`'). The region `reg` must be managed by `ws`. If `any` is not set, the status display is not considered. This function is considered safe.

Synopsis:
  `WSplitRegion WTiling.node_of(WTiling ws, WRegion reg)`
Description:
  For region `reg` managed by `ws` return the WSplit a leaf of which `reg` is. This function is considered safe.

Synopsis:
  `bool WTiling.set_floating_at(WTiling ws, WRegion reg, string how, string dirstr)`
Description:
  Toggle floating of the sides of a split containin `reg` as indicated by the parameters `how` (``set`', ``unset`', or ``toggle`') and `dirstr` (``left`', ``right`', ``up`', or ``down`'). The new status is returned (and `false` also on error).

Synopsis:
  `WSplitSplit WTiling.set_floating(WTiling ws, WSplitSplit split, string how)`
Description:
  Toggle floating of a split's sides at `split` as indicated by the parameter `how` (``set`', ``unset`', or ``toggle`'). A split of the appropriate is returned, if there was a change.

Synopsis:
  `WFrame WTiling.split(WTiling ws, WSplit node, string dirstr)`
Description:
  Create a new frame on `ws` ``above`', ``below`' ``left`' of, or ``right`' of `node` as indicated by `dirstr`. If `dirstr` is prefixed with ``floating:`' a floating split is created.

Synopsis:
  `WFrame WTiling.split_at(WTiling ws, WFrame frame, string dirstr, bool attach_current)`
Description:
  Split `frame` creating a new frame to direction `dirstr` (one of ``left`', ``right`', ``top`' or ``bottom`') of `frame`. If `attach_current` is set, the region currently displayed in `frame`, if any, is moved to thenew frame. If `dirstr` is prefixed with ``floating:`', a floating split is created.

Synopsis:
  `WFrame WTiling.split_top(WTiling ws, string dirstr)`
Description:
  Same as `WTiling.split` at the root of the split tree.

Synopsis:
  `WSplit WTiling.split_tree(WTiling ws)`
Description:
  Returns the root of the split tree. This function is considered safe.

Synopsis:
  `void WTiling.unsplit_at(WTiling ws, WRegion reg)`
Description:
  Try to relocate regions managed by `reg` to another frame and, if possible, destroy it.

##
6.3 Functions defined in mod_query

Synopsis:
  `mod_query.defcmd(cmd, fn)`
Description:
  Define a command override for the `query_exec` query.

Synopsis:
  `mod_query.message(mplex, str)`
Description:
  Display a message in `mplex`.

Synopsis:
  `table mod_query.get()`
Description:
  Get module configuration. For more information see `mod_query.set`. This function is considered safe.

Synopsis:
  `void mod_query.history_clear()`
Description:
  Clear line editor history.

Synopsis:
  `string mod_query.history_get(integer n)`
Description:
  Get entry at index `n` in line editor history, 0 being the latest. This function is considered safe.

Synopsis:
  `bool mod_query.history_push(string str)`
Description:
  Push an entry into line editor history.

Synopsis:
  `integer mod_query.history_search(string s, integer from, bool bwd, bool exact)`
Description:
  Try to find matching history entry. Returns -1 if none was found. The parameter `from` specifies where to start searching from, and `bwd` causes backward search from that point. If `exact` is not set, `s` only required to be a prefix of the match. This function is considered safe.

Synopsis:
  `table mod_query.history_table()`
Description:
  Return table of history entries. This function is considered safe.

Synopsis:
  `void mod_query.set(table tab)`
Description:
  Set module configuration. The following are supported:

  Field
  `autoshowcompl`
  `autoshowcompl_delay`
  `caseicompl`
  `substrcompl`

Synopsis:
  `mod_query.popen_completions(cp, cmd, fn, reshnd, wd)`
Description:
  This function can be used to read completions from an external source. The parameter `cp` is the completion proxy to be used, and the string `cmd` the shell command to be executed, in the directory `wd`. To its stdout, the command should on the first line write the `common_beg` parameter of `WComplProxy.set_completions` (which `fn` maybe used to override) and a single actual completion on each of the successive lines. The function `reshnd` may be used to override a result table building routine. Its first argument is the completion table to be passed to `WComplProxy.set_completions`, and the second a new line of output from the command.

Synopsis:
  `mod_query.query(mplex, prompt, initvalue, handler, completor, context)`
Description:
  Low-level query routine. `mplex` is the WMPlex to display the query in, `prompt` the prompt string, and `initvalue` the initial contents of the query box. `handler` is a function that receives (`mplex`, result string) as parameter when the query has been succesfully completed, `completor` the completor routine which receives a (`cp`, `str`, `point`) as parameters. The parameter `str` is the string to be completed and `point` cursor's location within it. Completions should be eventually, possibly asynchronously, set with `WComplProxy.set_completions` on `cp`.

Synopsis:
  `mod_query.query_attachclient(mplex)`
Description:
  This query asks for the name of a client window and attaches it to the frame the query was opened in. It uses the completion function `ioncore.complete_clientwin`.

Synopsis:
  `mod_query.query_editfile(mplex, script, prompt)`
Description:
  Asks for a file to be edited. This script uses `run-mailcap -mode=edit` by default, but you may provide an alternative script to use. The default prompt is "Edit file:" (translated).

Synopsis:
  `mod_query.query_exec(mplex)`
Description:
  This function asks for a command to execute with /bin/sh. If the command is prefixed with a colon (':'), the command will be run in an XTerm (or other terminal emulator) using the script ion-runinxterm. Two colons ('::') will ask you to press enter after the command has finished.

Synopsis:
  `mod_query.query_gotoclient(mplex)`
Description:
  This query asks for the name of a client window and switches focus to the one entered. It uses the completion function `ioncore.complete_clientwin`.

Synopsis:
  `mod_query.query_lua(mplex)`
Description:
  This query asks for Lua code to execute. It sets the variable '`_`' in the local environment of the string to point to the mplex where the query was created. It also sets the table `arg` in the local environment to `{_, _:current()}`.

Synopsis:
  `mod_query.query_man(mplex, prog)`
Description:
  This query asks for a manual page to display. By default it runs the `man` command in an `xterm` using `ion-runinxterm`, but it is possible to pass another program as the `prog` argument.

Synopsis:
  `mod_query.query_menu(mplex, sub, themenu, prompt)`
Description:
  This query can be used to create a query of a defined menu.

Synopsis:
  `mod_query.query_renameframe(frame)`
Description:
  This function asks for a name new for the frame where the query was created.

Synopsis:
  `mod_query.query_renameworkspace(mplex, ws)`
Description:
  This function asks for a name new for the workspace `ws`, or the one on which `mplex` resides, if it is not set. If `mplex` is not set, one is looked for.

Synopsis:
  `mod_query.query_restart(mplex)`
Description:
  This query asks whether the user wants restart Ioncore. If the answer is 'y', 'Y' or 'yes', so will happen.

Synopsis:
  `mod_query.query_runfile(mplex, script, prompt)`
Description:
  Asks for a file to be viewed. This script uses `run-mailcap -action=view` by default, but you may provide an alternative script to use. The default prompt is "View file:" (translated).

Synopsis:
  `mod_query.query_shutdown(mplex)`
Description:
  This query asks whether the user wants to exit Ion (no session manager) or close the session (running under a session manager that supports such requests). If the answer is 'y', 'Y' or 'yes', so will happen.

Synopsis:
  `mod_query.query_ssh(mplex, ssh)`
Description:
  This query asks for a host to connect to with SSH. Hosts to tab-complete are read from ~/.ssh/known_hosts.

Synopsis:
  `mod_query.query_workspace(mplex)`
Description:
  This query asks for the name of a workspace. If a workspace (an object inheriting WGroupWS) with such a name exists, it will be switched to. Otherwise a new workspace with the entered name will be created and the user will be queried for the type of the workspace.

Synopsis:
  `mod_query.query_yesno(mplex, prompt, handler)`
Description:
  This function query will display a query with prompt `prompt` in `mplex` and if the user answers affirmately, call `handler` with `mplex` as parameter.

Synopsis:
  `mod_query.show_about_ion(mplex)`
Description:
  Display an "About Ion" message in `mplex`.

Synopsis:
  `mod_query.show_tree(mplex, reg, max_depth)`
Description:
  Show information about a region tree

Synopsis:
  `mod_query.warn(mplex, str)`
Description:
  Display an error message box in the multiplexer `mplex`.

### 6.3.1 WComplProxy functions

Synopsis:
  `bool WComplProxy.set_completions(WComplProxy proxy, table compls)`
Description:
  Set completion list of the WEdln that `proxy` refers to to `compls`, if it is still waiting for this completion run. The numerical indexes of `compls` list the found completions. If the entry `common_beg` (`common_end`) exists, it gives an extra common prefix (suffix) of all found completions.

### 6.3.2 WEdln functions

Synopsis:
  `void WEdln.back(WEdln wedln)`
Description:
  Move backward one character.

Synopsis:
  `void WEdln.backspace(WEdln wedln)`
Description:
  Delete previous character.

Synopsis:
  `void WEdln.bkill_word(WEdln wedln)`
Description:
  Starting from the previous characters, delete possible whitespace and preceding alphanumeric characters until previous non-alphanumeric character.

Synopsis:
  `void WEdln.bol(WEdln wedln)`
Description:
  Go to the beginning of line.

Synopsis:
  `void WEdln.bskip_word(WEdln wedln)`
Description:
  Go to to beginning of current sequence of alphanumeric characters followed by whitespace.

Synopsis:
  `void WEdln.clear_mark(WEdln wedln)`
Description:
  Clear mark.

Synopsis:
  `void WEdln.complete(WEdln wedln, string cycle, string mode)`
Description:
  Call completion handler with the text between the beginning of line and current cursor position, or select next/previous completion from list if in auto-show-completions mode and `cycle` is set to ``next`' or ``prev`', respectively. The `mode` may be ``history`' or ``normal`'. If it is not set, the previous mode is used. Normally next entry is not cycled to despite the setting of `cycle` if mode switch occurs. To override this, use ``next-always`' and ``prev-always`' for `cycle`.

Synopsis:
  `string WEdln.contents(WEdln wedln)`
Description:
  Get line editor contents. This function is considered safe.

Synopsis:
  `string WEdln.context(WEdln wedln)`
Description:
  Get history context for `wedln`. This function is considered safe.

Synopsis:
  `void WEdln.copy(WEdln wedln)`
Description:
  Copy text between mark and current cursor position to clipboard.

Synopsis:
  `void WEdln.cut(WEdln wedln)`
Description:
  Copy text between mark and current cursor position to clipboard and then delete that sequence.

Synopsis:
  `void WEdln.delete(WEdln wedln)`
Description:
  Delete current character.

Synopsis:
  `void WEdln.eol(WEdln wedln)`
Description:
  Go to the end of line.

Synopsis:
  `void WEdln.finish(WEdln wedln)`
Description:
  Close `wedln` and call any handlers.

Synopsis:
  `void WEdln.forward(WEdln wedln)`
Description:
  Move forward one character.

Synopsis:
  `void WEdln.history_next(WEdln wedln, bool match)`
Description:
  Replace line editor contents with next entry in history if one exists. If `match` is `true`, the initial part of the history entry must match the current line from beginning to point.

Synopsis:
  `void WEdln.history_prev(WEdln wedln, bool match)`
Description:
  Replace line editor contents with previous in history if one exists. If `match` is `true`, the initial part of the history entry must match the current line from beginning to point.

Synopsis:
  `void WEdln.insstr(WEdln wedln, string str)`
Description:
  Input `str` in wedln at current editing point.

Synopsis:
  `bool WEdln.is_histcompl(WEdln wedln)`
Description:
  Get history completion mode.

Synopsis:
  `void WEdln.kill_line(WEdln wedln)`
Description:
  Delete the whole line.

Synopsis:
  `void WEdln.kill_to_bol(WEdln wedln)`
Description:
  Delete all characters from previous to beginning of line.

Synopsis:
  `void WEdln.kill_to_eol(WEdln wedln)`
Description:
  Delete all characters from current to end of line.

Synopsis:
  `void WEdln.kill_word(WEdln wedln)`
Description:
  Starting from the current point, delete possible whitespace and following alphanumeric characters until next non-alphanumeric character.

Synopsis:
  `integer WEdln.mark(WEdln wedln)`
Description:
  Get current mark (start of selection) for `wedln`. Return value of -1 indicates that there is no mark, and 0 is the beginning of the line. This function is considered safe.

Synopsis:
  `bool WEdln.next_completion(WEdln wedln)`
Description:
  Select next completion.

Synopsis:
  `void WEdln.paste(WEdln wedln)`
Description:
  Request selection from application holding such.

  Note that this function is asynchronous; the selection will not actually be inserted before Ion receives it. This will be no earlier than Ion return to its main loop.

Synopsis:
  `integer WEdln.point(WEdln wedln)`
Description:
  Get current editing point. Beginning of the edited line is point 0. This function is considered safe.

Synopsis:
  `bool WEdln.prev_completion(WEdln wedln)`
Description:
  Select previous completion.

Synopsis:
  `void WEdln.set_context(WEdln wedln, string context)`
Description:
  Set history context for `wedln`.

Synopsis:
  `void WEdln.set_mark(WEdln wedln)`
Description:
  Set mark to current cursor position.

Synopsis:
  `void WEdln.skip_word(WEdln wedln)`
Description:
  Go to to end of current sequence of whitespace followed by alphanumeric characters..

Synopsis:
  `void WEdln.transpose_chars(WEdln wedln)`
Description:
  Transpose characters.

Synopsis:
  `void WEdln.transpose_words(WEdln wedln)`
Description:
  Transpose words.

### 6.3.3 WInput functions

Synopsis:
  `void WInput.cancel(WInput input)`
Description:
  Close input not calling any possible finish handlers.

Synopsis:
  `void WInput.scrolldown(WInput input)`
Description:
  Scroll input `input` text contents down.

Synopsis:
  `void WInput.scrollup(WInput input)`
Description:
  Scroll input `input` text contents up.

##
6.4 Functions defined in mod_menu

Synopsis:
  `mod_menu.grabmenu(mplex, sub, menu_or_name, param)`
Description:
  This function is similar to `mod_menu.menu`, but input is grabbed and the key used to active the menu can be used to cycle through menu entries.

Synopsis:
  `mod_menu.menu(mplex, sub, menu_or_name, param)`
Description:
  Display a menu in the lower-left corner of `mplex`. The variable `menu_or_name` is either the name of a menu defined with `mod_menu.defmenu` or directly a table similar to ones passesd to this function. When this function is called from a binding handler, `sub` should be set to the second argument of to the binding handler (`_sub`) so that the menu handler will get the same parameters as the binding handler. Extra options can be passed in the table `param`. The initial entry can be specified as the field `initial` as an integer starting from 1. Menus can be made to use a bigger style by setting the field `big` to `true`.

Synopsis:
  `table mod_menu.get()`
Description:
  Get module basic settings. For details, see `mod_menu.set`. This function is considered safe.

Synopsis:
  `void mod_menu.set(table tab)`
Description:
  Set module basic settings. The parameter table may contain the following fields:

  Field
  `scroll_amount`
  `scroll_delay`

Synopsis:
  `mod_menu.pmenu(win, sub, menu_or_name)`
Description:
  This function displays a drop-down menu and should only be called from a mouse press handler. The parameters are similar to those of `mod_menu.menu`.

### 6.4.1 WMenu functions

Synopsis:
  `void WMenu.cancel(WMenu menu)`
Description:
  Close `menu` not calling any possible finish handlers.

Synopsis:
  `void WMenu.finish(WMenu menu)`
Description:
  If selected entry is a submenu, display that. Otherwise destroy the menu and call handler for selected entry.

Synopsis:
  `void WMenu.select_next(WMenu menu)`
Description:
  Select next entry in menu.

Synopsis:
  `void WMenu.select_nth(WMenu menu, integer n)`
Description:
  Select `n`:th entry in menu.

Synopsis:
  `void WMenu.select_prev(WMenu menu)`
Description:
  Select previous entry in menu.

Synopsis:
  `void WMenu.typeahead_clear(WMenu menu)`
Description:
  Clear typeahead buffer.

##
6.5 Functions defined in mod_dock

Synopsis:
  `void mod_dock.set_floating_shown_on(WMPlex mplex, string how)`
Description:
  Toggle floating docks on `mplex`.

### 6.5.1 WDock functions

Synopsis:
  `bool WDock.attach(WDock dock, WRegion reg)`
Description:
  Attach `reg` to `dock`.

Synopsis:
  `table WDock.get(WDock dock)`
Description:
  Get `dock`'s configuration table. See `WDock.set` for a description of the table. This function is considered safe.

Synopsis:
  `void WDock.resize(WDock dock)`
Description:
  Resizes and refreshes `dock`.

Synopsis:
  `void WDock.set(WDock dock, table conftab)`
Description:
  Configure `dock`. `conftab` is a table of key/value pairs:

  Key | Values
  `name` | string
  `pos` | string in {t, m, b}×{t, c, b} mathend000#
  `grow` | up/down/left/right
  `is_auto` | bool

  Any parameters not explicitly set in `conftab` will be left unchanged.

##
6.6 Functions defined in mod_sp

Synopsis:
  `bool mod_sp.create_scratchpad(WScreen scr)`
Description:
  Attempt to create a scratchpad on `scr`.

Synopsis:
  `bool mod_sp.is_scratchpad(WRegion reg)`
Description:
  Is `reg` a scratchpad? This function is considered safe.

Synopsis:
  `bool mod_sp.set_shown(WFrame sp, string how)`
Description:
  Toggle displayed status of `sp`. The parameter `how` is one of ``set`', ``unset`', or ``toggle`'. The resulting status is returned.

Synopsis:
  `bool mod_sp.set_shown_on(WMPlex mplex, string how)`
Description:
  Change displayed status of some scratchpad on `mplex` if one is found. The parameter `how` is one of ``set`', ``unset`', or ``toggle`'. The resulting status is returned.

##
6.7 Functions defined in mod_statusbar

Synopsis:
  `mod_statusbar.create(param)`
Description:
  Create a statusbar. The possible parameters in the table `param` are:

  Variable | Type
  `template` | string
  `pos` | string
  `screen` | integer
  `fullsize` | boolean
  `systray` | boolaen

Synopsis:
  `mod_statusbar.inform(name, value)`
Description:
  Inform of a value.

Synopsis:
  `mod_statusbar.launch_statusd(cfg)`
Description:
  Load modules and launch ion-statusd with configuration table `cfg`. The options for each ion-statusd monitor script should be contained in the corresponding sub-table of `cfg`.

Synopsis:
  `table mod_statusbar.statusbars()`
Description:
  Returns a list of all statusbars.

Synopsis:
  `mod_statusbar.terminate_statusd()`
Description:
  Function to terminate ion-statusd on exit or reload. Should be called from hook `deinit`.

Synopsis:
  `mod_statusbar.update(update_templates)`
Description:
  Update statusbar contents. To be called after series of `mod_statusbar.inform` calls.

### 6.7.1 WStatusBar functions

Synopsis:
  `table WStatusBar.get_template_table(WStatusBar sb)`
Description:
  Get statusbar template as table.

Synopsis:
  `bool WStatusBar.is_systray(WStatusBar sb)`
Description:
  Is `sb` used as a systray?

Synopsis:
  `bool WStatusBar.set_systray(WStatusBar sb, string how)`
Description:
  Enable or disable use of `sb` as systray. The parameter `how` can be one of ``set`', ``unset`', or ``toggle`'. Resulting state is returned.

Synopsis:
  `void WStatusBar.set_template(WStatusBar sb, string tmpl)`
Description:
  Set statusbar template.

Synopsis:
  `void WStatusBar.set_template_table(WStatusBar sb, table t)`
Description:
  Set statusbar template as table.

Synopsis:
  `void WStatusBar.update(WStatusBar sb, table t)`
Description:
  Set statusbar template.

##
6.8 Functions defined in de

Synopsis:
  `bool de.defstyle(string name, table tab)`
Description:
  Define a style.

Synopsis:
  `bool de.defstyle_rootwin(WRootWin rootwin, string name, table tab)`
Description:
  Define a style for the root window `rootwin`.

Synopsis:
  `void de.reset()`
Description:
  Clear all styles from drawing engine memory.

Synopsis:
  `table de.substyle(string pattern, table tab)`
Description:
  Define a substyle. This function is considered safe.

##
6.9 Hooks

Hook name:
  `clientwin_do_manage_alt`
Parameters:
  `(WClientWin, table)`
Description:
  Called when we want to manage a new client window. The table argument contains the following fields:

  Field | Type
  `switchto` | bool
  `jumpto` | bool
  `userpos` | bool
  `dockapp` | bool
  `maprq` | bool
  `gravity` | number
  `geom` | table
  `tfor` | WClientWin

  This hook is not called in protected mode and can be used for arbitrary placement policies (deciding in which workspace a new WClientWin should go). In this case, you can call

      reg:attach(cwin)

  where `reg` is the region where the window should go, and `cwin` is the first argument of the function added to the hook.

Hook name:
  `clientwin_mapped_hook`
Parameters:
  `WClientWin`
Description:
  Called when we have started to manage a client window.

Hook name:
  `clientwin_property_change_hook`
Parameters:
  `(WClientWin, integer)`
Description:
  Called when the property identified by the parameter atom id (integer) has changed on a client window.

Hook name:
  `clientwin_unmapped_hook`
Parameters:
  `number`
Description:
  Called when we no longer manage a client window. The parameter is the X ID of the window; see `WClientWin.xid`.

Hook name:
  `frame_managed_changed_hook`
Parameters:
  `table`
Description:
  Called when there are changes in the objects managed by a frame or their order. The table parameter has the following fields:

  Field | Type
  `reg` | WFrame
  `mode` | string
  `sw` | bool
  `sub` | WRegion

Hook name:
  `ioncore_sigchld_hook`
Parameters:
  `integer`
Description:
  Called when a child process has exited. The parameter is the PID of the process.

Hook name:
  `ioncore_deinit_hook`
Parameters:
  `()`
Description:
  Called when Notion is deinitialising and about to quit.

Hook name:
  `ioncore_post_layout_setup_hook`
Parameters:
  `()`
Description:
  Called when Notion has done all initialisation and is almost ready to enter the main-loop, except no windows are yet being managed.

Hook name:
  `ioncore_snapshot_hook`
Parameters:
  `()`
Description:
  Called to signal scripts and modules to save their state (if any).

Hook name:
  `ioncore_submap_ungrab_hook`
Parameters:
  `()`
Description:
  This hook is used to signal whenever Notion leaves the submap grab mode.

Hook name:
  `tiling_placement_alt`
Parameters:
  `table`
Description:
  Called when a client window is about to be managed by a WTiling to allow for alternative placement policies. The table has the following fields:

  Field | Type
  `tiling` | WTiling
  `reg` | WRegion
  `mp` | table
  `res_frame` | WFrame

  This hook is just for placing within a given workspace after the workspace has been decided by the default workspace selection policy. It is called in protected mode. For arbitrary placement policies, `clientwin_do_manage_alt` should be used; it isn't called in protected mode,

Hook name:
  `region_do_warp_alt`
Parameters:
  `WRegion`
Description:
  This alt-hook exist to allow for alternative pointer warping implementations.

Hook name:
  `screen_managed_changed_hook`
Parameters:
  `table`
Description:
  Called when there are changes in the objects managed by a screen or their order. The table parameter is similar to that of `frame_managed_changed_hook`.

Hook name:
  `region_notify_hook`
Parameters:
  `(WRegion, string)`
Description:
  Signalled when something (minor) has changed in relation to the first parameter region. The string argument gives the change:

  String
  `deinit`
  `activated`
  `inactivated`
  `activity`
  `sub_activity`
  `name`
  `unset_manager`
  `set_manager`
  `tag`
  `pseudoactivated`
  `pseudoinactivated`

  A region is pseudo-active, when a) it is itself not active (does not not have the focus, and may not even have a window that could have it), but b) some region managed by it is active.

##
6.10 Miscellaneous

###
6.10.1 Size policies

Some functions accept a `sizepolicy` parameter. The possible values are:

``default`', ``full`', ``full_bounds`', ``free`', ``free_glue`', ``northwest`', ``north`', ``northeast`', ``west`', ``center`', ``east`', ``southwest`', ``south`', ``southeast`', ``stretch_top`', ``stretch_bottom`', ``stretch_left`', ``stretch_right`', ``free_glue_northwest`', ``free_glue_north`', ``free_glue_northeast`', ``free_glue_west`', ``free_glue_center`', ``free_glue_east`', ``free_glue_southwest`', ``free_glue_south`', and ``free_glue_southeast`'.

The ``free'' policies allow the managed object to be moved around, whereas the other versions do not. The ``glue'' policies glue the object to some border, while allowing it to be moved away from it by user action, but not automatically. The ``stretch'' policies stretch the object along the given border, while the coordinate-based policies simply place the object along that border.

# A. GNU Free Documentation License

Version 1.2, November 2002

Copyright © 2000,2001,2002 Free Software Foundation, Inc.

51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble

The purpose of this License is to make a manual, textbook, or other functional and useful document ``free'' in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of ``copyleft'', which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The ``Document'', below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as ``you''. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

A ``Modified Version'' of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A ``Secondary Section'' is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The ``Invariant Sections'' are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

The ``Cover Texts'' are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

A ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not ``Transparent'' is called ``Opaque''.

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

The ``Title Page'' means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

A section ``Entitled XYZ'' means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as ``Acknowledgements'', ``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' of such a section when you modify the Document means that it remains a section ``Entitled XYZ'' according to this definition.

The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

2. VERBATIM COPYING

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

3. COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

A.
  Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.

B.
  List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.

C.
  State on the Title page the name of the publisher of the Modified Version, as the publisher.

D.
  Preserve all the copyright notices of the Document.

E.
  Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.

F.
  Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.

G.
  Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.

H.
  Include an unaltered copy of this License.

I.
  Preserve the section Entitled ``History'', Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled ``History'' in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.

J.
  Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the ``History'' section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.

K.
  For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.

L.
  Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.

M.
  Delete any section Entitled ``Endorsements''. Such a section may not be included in the Modified Version.

N.
  Do not retitle any existing section to be Entitled ``Endorsements'' or to conflict in title with any Invariant Section.

O.
  Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

You may add a section Entitled ``Endorsements'', provided it contains nothing but endorsements of your Modified Version by various parties-for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

5. COMBINING DOCUMENTS

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections Entitled ``History'' in the various original documents, forming one section Entitled ``History''; likewise combine any sections Entitled ``Acknowledgements'', and any sections Entitled ``Dedications''. You must delete all sections Entitled ``Endorsements''.

6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an ``aggregate'' if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

8. TRANSLATION

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

If a section in the Document is Entitled ``Acknowledgements'', ``Dedications'', or ``History'', the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See `http://www.gnu.org/copyleft/`.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License ``or any later version'' applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

> Copyright © YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the ``with ... Texts.'' line with this:

> with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

#
B. Full class hierarchy visible to Lua-side

        Obj
         |-->WHook
         |-->WTimer
         |-->WMoveresMode
         |-->WRegion
         |    |-->WClientWin
         |    |-->WWindow
         |    |    |-->WRootWin
         |    |    |-->WMPlex
         |    |    |    |-->WFrame
         |    |    |    `-->WScreen
         |    |    |-->WInfoWin
         |    |    |    `-->WStatusBar (mod_statusbar)
         |    |    |-->WMenu (mod_menu)
         |    |    `-->WInput (mod_query)
         |    |         |-->WEdln (mod_query)
         |    |         `-->WMessage (mod_query)
         |    |-->WGroup
         |    |    |-->WGroupWS
         |    |    `-->WGroupCW
         |    `-->WTiling (mod_tiling)
         `-->WSplit (mod_tiling)
              |-->WSplitInner (mod_tiling)
              |    `-->WSplitSplit (mod_tiling)
              |         `-->WSplitFloat (mod_tiling)
              `-->WSplitRegion (mod_tiling)
                   `-->WSplitST (mod_tiling)

# List of functions

`de.defstyle`
`de.defstyle_rootwin`
`de.reset`
`de.substyle`
`export`
`gr.read_config`
`gr.refresh`
`gr.select_engine`
`ioncore.aboutmsg`
`ioncore.activity_first`
`ioncore.activity_i`
`ioncore.bdoc`
`ioncore.chdir_for`
`ioncore.clientwin_i`
`ioncore.compile_cmd`
`ioncore.create_timer`
`ioncore.create_ws`
`ioncore.current`
`ioncore.defbindings`
`ioncore.defctxmenu`
`ioncore.defer`
`ioncore.deflayout`
`ioncore.defmenu`
`ioncore.defshortening`
`ioncore.defwinprop`
`ioncore.detach`
`ioncore.exec`
`ioncore.exec_on`
`ioncore.find_manager`
`ioncore.find_screen_id`
`ioncore.focushistory_i`
`ioncore.get`
`ioncore.getbindings`
`ioncore.getctxmenu`
`ioncore.get_dir_for`
`ioncore.get_hook`
`ioncore.getlayout`
`ioncore.getmenu`
`ioncore.get_paths`
`ioncore.get_savefile`
`ioncore.getwinprop`
`ioncore.goto_activity`
`ioncore.goto_first`
`ioncore.goto_next`
`ioncore.goto_next_screen`
`ioncore.goto_nth_screen`
`ioncore.goto_previous`
`ioncore.goto_prev_screen`
`ioncore.is_i18n`
`ioncore.kpress`
`ioncore.kpress_wait`
`ioncore.load_module`
`ioncore.lookup_clientwin`
`ioncore.lookup_region`
`ioncore.lookup_script`
`ioncore.match_winprop_dflt`
`ioncore.mclick`
`ioncore.mdblclick`
`ioncore.mdrag`
`ioncore.menuentry`
`ioncore.mpress`
`ioncore.navi_first`
`ioncore.navi_next`
`ioncore.popen_bgread`
`ioncore.profiling_start`
`ioncore.profiling_stop`
`ioncore.progname`
`ioncore.read_savefile`
`ioncore.refresh_stylelist`
`ioncore.region_i`
`ioncore.request_selection`
`ioncore.resign`
`ioncore.restart`
`ioncore.restart_other`
`ioncore.rootwin`
`ioncore.screens_updated`
`ioncore.set`
`ioncore.set_paths`
`ioncore.set_selection`
`ioncore.shutdown`
`ioncore.snapshot`
`ioncore.submap`
`ioncore.submap_enter`
`ioncore.submap_wait`
`ioncore.submenu`
`ioncore.tabnum.clear`
`ioncore.tabnum.show`
`ioncore.tagged_attach`
`ioncore.tagged_clear`
`ioncore.tagged_first`
`ioncore.tagged_i`
`ioncore.TR`
`ioncore.unsqueeze`
`ioncore.update_net_state`
`ioncore.version`
`ioncore.warn`
`ioncore.warn_traced`
`ioncore.write_savefile`
`ioncore.x_change_property`
`ioncore.x_delete_property`
`ioncore.x_get_atom_name`
`ioncore.x_get_text_property`
`ioncore.x_get_window_property`
`ioncore.x_intern_atom`
`ioncore.x_set_text_property`
`ioncore.x_set_utf8_property`
`mod_dock.set_floating_shown_on`
`mod_menu.get`
`mod_menu.grabmenu`
`mod_menu.menu`
`mod_menu.pmenu`
`mod_menu.set`
`mod_query.defcmd`
`mod_query.get`
`mod_query.history_clear`
`mod_query.history_get`
`mod_query.history_push`
`mod_query.history_search`
`mod_query.history_table`
`mod_query.message`
`mod_query.popen_completions`
`mod_query.query`
`mod_query.query_attachclient`
`mod_query.query_editfile`
`mod_query.query_exec`
`mod_query.query_gotoclient`
`mod_query.query_lua`
`mod_query.query_man`
`mod_query.query_menu`
`mod_query.query_renameframe`
`mod_query.query_renameworkspace`
`mod_query.query_restart`
`mod_query.query_runfile`
`mod_query.query_shutdown`
`mod_query.query_ssh`
`mod_query.query_workspace`
`mod_query.query_yesno`
`mod_query.set`
`mod_query.show_about_ion`
`mod_query.show_tree`
`mod_query.warn`
`mod_sp.create_scratchpad`
`mod_sp.is_scratchpad`
`mod_sp.set_shown`
`mod_sp.set_shown_on`
`mod_statusbar.create`
`mod_statusbar.inform`
`mod_statusbar.launch_statusd`
`mod_statusbar.statusbars`
`mod_statusbar.terminate_statusd`
`mod_statusbar.update`
`mod_tiling.get`
`mod_tiling.mkbottom`
`mod_tiling.set`
`mod_tiling.untile`
`string.shell_safe`
`table.append`
`table.copy`
`table.icat`
`table.join`
`table.map`
`WClientWin.get_ident`
`WClientWin.kill`
`WClientWin.nudge`
`WClientWin.quote_next`
`WClientWin.xid`
`WComplProxy.set_completions`
`WDock.attach`
`WDock.get`
`WDock.resize`
`WDock.set`
`WEdln.back`
`WEdln.backspace`
`WEdln.bkill_word`
`WEdln.bol`
`WEdln.bskip_word`
`WEdln.clear_mark`
`WEdln.complete`
`WEdln.contents`
`WEdln.context`
`WEdln.copy`
`WEdln.cut`
`WEdln.delete`
`WEdln.eol`
`WEdln.finish`
`WEdln.forward`
`WEdln.history_next`
`WEdln.history_prev`
`WEdln.insstr`
`WEdln.is_histcompl`
`WEdln.kill_line`
`WEdln.kill_to_bol`
`WEdln.kill_to_eol`
`WEdln.kill_word`
`WEdln.mark`
`WEdln.next_completion`
`WEdln.paste`
`WEdln.point`
`WEdln.prev_completion`
`WEdln.set_context`
`WEdln.set_mark`
`WEdln.skip_word`
`WEdln.transpose_chars`
`WEdln.transpose_words`
`WFrame.is_grattr`
`WFrame.is_shaded`
`WFrame.maximize_horiz`
`WFrame.maximize_vert`
`WFrame.mode`
`WFrame.p_switch_tab`
`WFrame.p_tabdrag`
`WFrame.set_grattr`
`WFrame.set_mode`
`WFrame.set_shaded`
`WGroup.attach`
`WGroup.attach_new`
`WGroup.bottom`
`WGroup.managed_i`
`WGroup.set_bottom`
`WGroup.set_fullscreen`
`WGroupWS.attach_framed`
`WHook.add`
`WHook.listed`
`WHook.remove`
`WInfoWin.set_text`
`WInput.cancel`
`WInput.scrolldown`
`WInput.scrollup`
`WMenu.cancel`
`WMenu.finish`
`WMenu.select_next`
`WMenu.select_nth`
`WMenu.select_prev`
`WMenu.typeahead_clear`
`WMoveresMode.cancel`
`WMoveresMode.finish`
`WMoveresMode.geom`
`WMoveresMode.move`
`WMoveresMode.resize`
`WMoveresMode.rqgeom`
`WMPlex.attach`
`WMPlex.attach_new`
`WMPlex.dec_index`
`WMPlex.get_index`
`WMPlex.get_stdisp`
`WMPlex.inc_index`
`WMPlex.is_hidden`
`WMPlex.managed_i`
`WMPlex.mx_count`
`WMPlex.mx_current`
`WMPlex.mx_i`
`WMPlex.mx_nth`
`WMPlex.set_hidden`
`WMPlex.set_index`
`WMPlex.set_stdisp`
`WMPlex.switch_next`
`WMPlex.switch_nth`
`WMPlex.switch_prev`
`WMPlex.switch_to`
`WRegion.begin_kbresize`
`WRegion.current`
`WRegion.geom`
`WRegion.get_configuration`
`WRegion.goto`
`WRegion.goto_focus`
`WRegion.groupleader_of`
`WRegion.is_active`
`WRegion.is_activity`
`WRegion.is_mapped`
`WRegion.is_tagged`
`WRegion.manager`
`WRegion.name`
`WRegion.parent`
`WRegion.rootwin_of`
`WRegion.rqclose`
`WRegion.rqclose_propagate`
`WRegion.rqgeom`
`WRegion.rqorder`
`WRegion.screen_of`
`WRegion.set_activity`
`WRegion.set_name`
`WRegion.set_name_exact`
`WRegion.set_tagged`
`WRegion.size_hints`
`WRootWin.current_scr`
`WRootWin.warp_pointer`
`WScreen.id`
`WScreen.set_managed_offset`
`WSplit.geom`
`WSplitInner.current`
`WSplit.parent`
`WSplitRegion.reg`
`WSplit.rqgeom`
`WSplitSplit.br`
`WSplitSplit.dir`
`WSplitSplit.flip`
`WSplitSplit.tl`
`WSplit.transpose`
`WStatusBar.get_template_table`
`WStatusBar.is_systray`
`WStatusBar.set_systray`
`WStatusBar.set_template`
`WStatusBar.set_template_table`
`WStatusBar.update`
`WTiling.farthest`
`WTiling.flip_at`
`WTiling.managed_i`
`WTiling.nextto`
`WTiling.node_of`
`WTiling.set_floating`
`WTiling.set_floating_at`
`WTiling.split`
`WTiling.split_at`
`WTiling.split_top`
`WTiling.split_tree`
`WTiling.transpose_at`
`WTiling.unsplit_at`
`WTimer.is_set`
`WTimer.reset`
`WTimer.set`
`WWindow.p_move`
`WWindow.p_resize`
`WWindow.xid`

## Index

  `acrobatic` : 3.5.1
  Alt : 3.3.5
  AnyModifier : 3.3.5
  `resizeinc` : 3.5.1.1 | 3.5.1.1
  Button-n : 3.3.6
  `class`
    winprop : 3.5.2 | 3.5.2.3
  `clientwin_do_manage_alt` : 6.9
  `clientwin_mapped_hook` : 6.9
  `clientwin_property_change_hook` : 6.9
  `clientwin_unmapped_hook` : 6.9
  Control : 3.3.5
  `defmenu` : 3.4.1
  drawing engine : 4.1
  `ETCDIR` : 3.1
  `float` : 3.5.1
  `frame_managed_changed_hook` : 6.9
  `fullscreen` : 3.5.1
  `ignore_resizeinc` : 3.5.1.1 | 3.5.1.1
  `ignore_cfgrq` : 3.5.1
  `ignore_max_size` : 3.5.1.1
  `ignore_min_size` : 3.5.1.1
  `ignore_net_active_window` : 3.5.1
  `instance`
    winprop : 3.5.2 | 3.5.2.3
  `ioncore_deinit_hook` : 6.9
  `ioncore_post_layout_setup_hook` : 6.9
  `ioncore_sigchld_hook` : 6.9
  `ioncore_snapshot_hook` : 6.9
  `ioncore_submap_ungrab_hook` : 6.9
  `is_dockapp`
    winprop : 3.5.2 | 3.5.2.3
  `is_transient`
    winprop : 3.5.2 | 3.5.2.3
  `jumpto` : 3.5.1
  keysymdef.h : 3.3.5
  `lazy_resize` : 3.5.1
  Lock : 3.3.5
  manager : 2.2.2.2
  `max_size` : 3.5.1.1
  `menuentry` : 3.4.1
  menus : 3.4.1
  `min_size` : 3.5.1.1
  ModN : 3.3.5
  `name`
    winprop : 3.5.2
  `new_group` : 3.5.1
  NumLock : 3.3.5
  Obj : 2.2.1.2
  `oneshot` : 3.5.1
  `orientation` : 3.5.1
  parent : 2.2.2.1
  `PREFIX` : 3.1
  `region_do_warp_alt` : 6.9
  `region_notify_hook` : 6.9
  `role`
    winprop : 3.5.2 | 3.5.2.3
  root window : 2.2.1.2
  screen
    physical : 2.2.1.2
    X : 2.2.1.2
  `screen_managed_changed_hook` : 6.9
  ScrollLock : 3.3.5
  Shift : 3.3.5
  `statusbar` : 3.5.1
  style : 4.1
  `submenu` : 3.4.1
  substyle : 4.1
  `switchto` : 3.5.1
  system.mk : 3.1
  `target` : 3.5.1
  `tiling_placement_alt` : 6.9
  transient : 3.5.3
  `transient_mode` : 3.5.1
  `transparent` : 3.5.1
  `userpos` : 3.5.1.1
  WClientWin : 2.2.1.2
  WEdln : 2.2.1.2
  WFrame : 2.2.1.2
  WGroup : 2.2.1.2
  WGroupCW : 2.2.1.2
  WGroupWS : 2.2.1.2
  Winprops : 3.5
  WInput : 2.2.1.2
  WMessage : 2.2.1.2
  WRegion : 2.2.1.2
  WRootWin : 2.2.1.2
  WScreen : 2.2.1.2
  WSplit : 2.2.1.2
  WTiling : 2.2.1.2
  WWindow : 2.2.1.2
  Xinerama : 2.2.1.2 | 2.2.2.2.1
  xmodmap : 3.3.5
  xprop : 3.5.3

## Bibliography

1
  The Ion 3 scripts repository, `http://iki.fi/tuomov/repos/ion-scripts-3/`.

# About this document ...

Configuring and extending Notion with Lua

This document was generated using the LaTeX2`HTML` translator Version 2012 (1.2)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html `-show_section_numbers -short_index -local_icons -noaddress -up_url http://notion.sourceforge.net -up_title 'Notion homepage' -nofootnode -style notion.css -html_version 4.0,math,table -split 0 -dir notionconf-onepage notionconf`

The translation was initiated by builduser on 2016-03-09

#### Footnotes

... design 2.1
  the author doesn't like such artificial designs
...keysymdef.h 3.1
  This file can usually be found in the directory /usr/X11R6/include/X11/.
... such 3.2
  Completely useless keys that should be gotten rid of in the author's opinion.
... window.3.3
  There's a patch to `xprop` to fix this, but nothing seems to be happening with respect to including it in XFree86.